最高机密
华盛顿特区美国司法部联邦调查局
发件人:小埃德加·胡佛(局长)
主题:政府专家系统中的可疑泄漏
麻省剑桥市分局报告“可疑人物识别专家系统”(Suspicious Persons Identification Expert System,SPIES)中存在可疑泄漏。据可靠消息和几位精通软件的线人透露,该泄漏是由“临时工”编码造成的,涉案人员未知。
一名曾提供过可靠消息并声称与当事人有着密切关系的线人表示,该漏洞是由存储器中某块区域数据的管理不善所引起的,黑客兄弟会的人把该区域称为“堆”。
现在,我赋予你查看专家系统源代码以及动用FBI软件工程实验室所有资源的权力,请考虑种种迹象,仔细地分析案件的每一个细节,找到并修复这个漏洞。
只许成功不许失败。
此致
敬礼!
物证一:源代码
以下是“可疑人物识别专家系统”(SPIES)的源代码。这款软件可以用来记录嫌疑犯,并辨认他们。你不需要现在就细读代码,但请留一份副本,调查的过程中可能会用到它。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
char *question;
struct node *no;
struct node *yes;
} node;
int yes_no(char *question)
{
char answer[3];
printf("%s? (y/n): ", question);
fgets(answer, 3, stdin);
return answer[0] == 'y';
}
node* create(char *question)
{
node *n = malloc(sizeof(node));
n->question = strdup(question);
n->no = NULL;
n->yes = NULL;
return n;
}
void release(node *n)
{
if (n) {
if (n->no)
release(n->no);
if (n->yes)
release(n->yes);
if (n->question)
free(n->question);
free(n);
}
}
int main()
{
char question[80];
char suspect[20];
node *start_node = create("Does suspect have a mustache");
start_node->no = create("Loretta Barnsworth");
start_node->yes = create("Vinny the Spoon");
node *current;
do {
current = start_node;
while (1) {
if (yes_no(current->question))
{
if (current->yes) {
current = current->yes;
} else {
printf("SUSPECT IDENTIFIED\n");
break;
}
} else if (current->no) {
current = current->no;
} else {
/* Make the yes-node the new suspect name */
printf("Who's the suspect? ");
fgets(suspect, 20, stdin);
node *yes_node = create(suspect);
current->yes = yes_node;
/* Make the no-node a copy of this question */
node *no_node = create(current->question);
current->no = no_node;
/* Then replace this question with the new question */
printf("Give me a question that is TRUE for %s but not for %s? ", suspect, current->question);
fgets(question, 80, stdin);
current->question = strdup(question);
break;
}
}
} while(yes_no("Run again"));
release(start_node);
return 0;
}