最高机密

华盛顿特区美国司法部联邦调查局

发件人:小埃德加·胡佛(局长)

主题:政府专家系统中的可疑泄漏

麻省剑桥市分局报告“可疑人物识别专家系统”(Suspicious Persons Identification Expert System,SPIES)中存在可疑泄漏。据可靠消息和几位精通软件的线人透露,该泄漏是由“临时工”编码造成的,涉案人员未知。

一名曾提供过可靠消息并声称与当事人有着密切关系的线人表示,该漏洞是由存储器中某块区域数据的管理不善所引起的,黑客兄弟会的人把该区域称为“堆”。

现在,我赋予你查看专家系统源代码以及动用FBI软件工程实验室所有资源的权力,请考虑种种迹象,仔细地分析案件的每一个细节,找到并修复这个漏洞。

只许成功不许失败。

此致

敬礼!

最高机密 - 图1

物证一:源代码

以下是“可疑人物识别专家系统”(SPIES)的源代码。这款软件可以用来记录嫌疑犯,并辨认他们。你不需要现在就细读代码,但请留一份副本,调查的过程中可能会用到它。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct node {
  5. char *question;
  6. struct node *no;
  7. struct node *yes;
  8. } node;
  9. int yes_no(char *question)
  10. {
  11. char answer[3];
  12. printf("%s? (y/n): ", question);
  13. fgets(answer, 3, stdin);
  14. return answer[0] == 'y';
  15. }
  16. node* create(char *question)
  17. {
  18. node *n = malloc(sizeof(node));
  19. n->question = strdup(question);
  20. n->no = NULL;
  21. n->yes = NULL;
  22. return n;
  23. }
  24. void release(node *n)
  25. {
  26. if (n) {
  27. if (n->no)
  28. release(n->no);
  29. if (n->yes)
  30. release(n->yes);
  31. if (n->question)
  32. free(n->question);
  33. free(n);
  34. }
  35. }
  36. int main()
  37. {
  38. char question[80];
  39. char suspect[20];
  40. node *start_node = create("Does suspect have a mustache");
  41. start_node->no = create("Loretta Barnsworth");
  42. start_node->yes = create("Vinny the Spoon");
  43. node *current;
  44. do {
  45. current = start_node;
  46. while (1) {
  47. if (yes_no(current->question))
  48. {
  49. if (current->yes) {
  50. current = current->yes;
  51. } else {
  52. printf("SUSPECT IDENTIFIED\n");
  53. break;
  54. }
  55. } else if (current->no) {
  56. current = current->no;
  57. } else {
  58. /* Make the yes-node the new suspect name */
  59. printf("Who's the suspect? ");
  60. fgets(suspect, 20, stdin);
  61. node *yes_node = create(suspect);
  62. current->yes = yes_node;
  63. /* Make the no-node a copy of this question */
  64. node *no_node = create(current->question);
  65. current->no = no_node;
  66. /* Then replace this question with the new question */
  67. printf("Give me a question that is TRUE for %s but not for %s? ", suspect, current->question);
  68. fgets(question, 80, stdin);
  69. current->question = strdup(question);
  70. break;
  71. }
  72. }
  73. } while(yes_no("Run again"));
  74. release(start_node);
  75. return 0;
  76. }