From d8bc76e48bc56735485e542a4bb5d1d04817d741 Mon Sep 17 00:00:00 2001
From: Will_Zhu MacBook Pro <will_zyq@qq.com>
Date: Mon, 30 Sep 2019 22:44:13 +1000
Subject: [PATCH] wait for testing

---
 src/vuln-1/passbook.c | 543 ++++++++++++++++++------------------------
 1 file changed, 226 insertions(+), 317 deletions(-)

diff --git a/src/vuln-1/passbook.c b/src/vuln-1/passbook.c
index 98007a9..8d72064 100644
--- a/src/vuln-1/passbook.c
+++ b/src/vuln-1/passbook.c
@@ -38,212 +38,149 @@ typedef struct {
 typedef struct node {
   char * url;
   cred_t cred;
-  // struct node *left;
-  // struct node *right;
+  struct node *left;
+  struct node *right;
 } node_t;
 
-#define MAP_NODE_NUM 50
-
-static const node_t * lookup(const node_t *map, const char *url){
-  // while (p != NULL){
-  //   int ret = strcmp(url,p->url);
-  //   if (ret == 0){
-  //     return p;
-  //   }else if (ret < 0){
-  //     p = p->left;
-  //   }else{
-  //     p = p->right;
-  //   }
-  // }
-  // return p; // not found
-  if (map == NULL) {
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
-  }
-  for (int i = 0; i < MAP_NODE_NUM; i++) {
-    if ((map + i)->url == NULL) {
-      continue;
-    }
-    if (strcmp((map + i)->url,url) == 0) {
-      return (map + i);
+static const node_t * lookup(const node_t *p, const char *url){
+  while (p != NULL){
+    int ret = strcmp(url,p->url);
+    if (ret == 0){
+      return p;
+    }else if (ret < 0){
+      p = p->left;
+    }else{
+      p = p->right;
     }
   }
-  return NULL;
+  return p; // not found
 }
 
-
-
 static void node_print(const node_t *p){
   printf("URL: %s, Username: %s, Password: %s\n",p->url,p->cred.username,p->cred.password);
 }
 
-// /* construct a new node */
-// static node_t *node_new(const char *url, const cred_t cred){
-//   node_t *new = malloc(sizeof(node_t));
-//   assert(new != NULL && "new: malloc failed");
-//   new->url = strdup(url);
-//   assert(new->url != NULL && "new: strdup url failed");
-//   new->cred.username = strdup(cred.username);
-//   assert(new->cred.username != NULL && "new: strdup username failed");  
-//   new->cred.password = strdup(cred.password);
-//   assert(new->cred.password != NULL && "new: strdup password failed");
-//   // new->left = NULL;
-//   // new->right = NULL;
-//   return new;
-// }
-
-// /* updates a node's credential in place: 
-//    replaces p's credential with that from q and frees q */
-// static void node_edit_cred(node_t * p, node_t *q){
-//   free(p->cred.username);
-//   free(p->cred.password);
-
-//   p->cred.username = q->cred.username;
-//   p->cred.password = q->cred.password;
-//   free(q->url);
-//   free(q);
-// }
-
-// static void node_free(node_t *p){
-//   free(p->url);
-//   free(p->cred.username);
-//   free(p->cred.password);
-//   free(p);
-// }
+/* construct a new node */
+static node_t *node_new(const char *url, const cred_t cred){
+  node_t *new = malloc(sizeof(node_t));
+  assert(new != NULL && "new: malloc failed");
+  new->url = strdup(url);
+  assert(new->url != NULL && "new: strdup url failed");
+  new->cred.username = strdup(cred.username);
+  assert(new->cred.username != NULL && "new: strdup username failed");  
+  new->cred.password = strdup(cred.password);
+  assert(new->cred.password != NULL && "new: strdup password failed");
+  new->left = NULL;
+  new->right = NULL;
+  return new;
+}
+
+/* updates a node's credential in place: 
+   replaces p's credential with that from q and frees q */
+static void node_edit_cred(node_t * p, node_t *q){
+  free(p->cred.username);
+  free(p->cred.password);
+
+  p->cred.username = q->cred.username;
+  p->cred.password = q->cred.password;
+  free(q->url);
+  free(q);
+}
+
+static void node_free(node_t *p){
+  free(p->url);
+  free(p->cred.username);
+  free(p->cred.password);
+  free(p);
+}
 
 /* insert q into p
    we assume that if q has children then it cannot already
    be present in p. Otherwise, if q has no children and we find its url in p,
    then we edit the found entry in place while preserving its children */
-// static node_t * node_insert(node_t *map, node_t *q){
-  // if (p == NULL){
-  //   return q;
-  // }
-  // if (q == NULL){
-  //   return p;
-  // }
-  // /* we store a pointer to a node pointer that remembers where in the 
-  //    tree the new node needs to be added */
-  // node_t ** new = NULL;
-  // node_t * const start = p;
-  // while (new == NULL) {
-  //   int ret = strcmp(q->url,p->url);
-  //   if (ret == 0){
-  //     assert (q->left == NULL && q->right == NULL && "illegal insertion");
-  //     /* edit the node in place */
-  //     node_edit_cred(p,q);
-  //     /* q is now freed so cannot be used anymore */
-  //     return start;
-  //   }else if (ret < 0){
-  //     if (p->left == NULL){
-  //       new = &(p->left);
-  //     }else{
-  //       p = p->left;
-  //     }
-  //   }else{
-  //     if (p->right == NULL){
-  //       new = &(p->right);
-  //     }else{
-  //       p = p->right;
-  //     }
-  //   }
-  // }
-  // *new = q;
-  // return start;
-// }
-
-/* returns a pointer to the tree with the node added or with the existing
-   node updated if it was  already present */
-static node_t * put(node_t *map, const char *url, const cred_t cred){
-  if (map == NULL) {
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
+static node_t * node_insert(node_t *p, node_t *q){
+  if (p == NULL){
+    return q;
   }
-  for (int i = 0; i < MAP_NODE_NUM; i++) {
-    if ((map + i)->url != NULL && strcmp((map + i)->url, url) == 0) {
-      free((map + i)->cred.password);
-      free((map + i)->cred.username);
-      (map + i)->cred.password = strdup(cred.password);
-      (map + i)->cred.username = strdup(cred.username);
-      return map;
-    }
+  if (q == NULL){
+    return p;
   }
-  int i = 0;
-  while (1) {
-    if ((map + i)->url == NULL)
-    {
-      (map + i)->cred.password = strdup(cred.password);
-      (map + i)->cred.username = strdup(cred.username);
-      (map + i)->url = strdup(url);
-      return map;
+  /* we store a pointer to a node pointer that remembers where in the 
+     tree the new node needs to be added */
+  node_t ** new = NULL;
+  node_t * const start = p;
+  while (new == NULL) {
+    int ret = strcmp(q->url,p->url);
+    if (ret == 0){
+      assert (q->left == NULL && q->right == NULL && "illegal insertion");
+      /* edit the node in place */
+      node_edit_cred(p,q);
+      /* q is now freed so cannot be used anymore */
+      return start;
+    }else if (ret < 0){
+      if (p->left == NULL){
+        new = &(p->left);
+      }else{
+        p = p->left;
+      }
+    }else{
+      if (p->right == NULL){
+        new = &(p->right);
+      }else{
+        p = p->right;
+      }
     }
-    i++;
   }
-  return map;
+  *new = q;
+  return start;
+}
+
+/* returns a pointer to the tree with the node added or with the existing
+   node updated if it was  already present */
+static node_t * put(node_t *p, const char *url, const cred_t cred){
+  return node_insert(p,node_new(url,cred));
 }
 
 /* destroy tree rooted at p */
-static void destroy(node_t *map){
-  if(map == NULL) {
-    return;
+static void destroy(node_t *p){
+  while (p != NULL){
+    node_t * left = p->left;
+    node_t * const right = p->right;
+    left = node_insert(left,right);
+    node_free(p);
+    p = left;
   }
-  for(int i = 0; i < MAP_NODE_NUM; i++) {
-    if ((map + i)->url != NULL) {
-      free((map + i)->url);
-      free((map + i)->cred.password);
-      free((map + i)->cred.username);
-    } 
-  }
-  free(map);
-  map = NULL;
 }
 
 /* returns a pointer to the tree with the node removed (if it was present) */
-static node_t * rem(node_t *map, const char *url){
-  // node_t * const start = p;
-  // /* remember where the pointer to p was stored */
-  // node_t ** pptr = NULL;
-  // while (p != NULL){
-  //   int ret = strcmp(url,p->url);
-  //   if (ret == 0){
-  //     node_t * left = p->left;
-  //     node_t * const right = p->right;
-  //     left = node_insert(left,right);
-  //     node_free(p);
-  //     if (pptr != NULL){
-  //       *pptr = left;
-  //       return start;
-  //     }else{
-  //       /* p was the only node in the tree */
-  //       assert(p == start);
-  //       return left;
-  //     }
-  //   }else if (ret < 0){
-  //     pptr = &(p->left);
-  //     p = p->left;
-  //   }else{
-  //     pptr = &(p->right);
-  //     p = p->right;
-  //   }
-  // }
-  // return start; // not found
-  if (map == NULL) {
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
-  }
-  for (int i = 0; i < MAP_NODE_NUM; i++) {
-    if ((map + i)->url == NULL) {
-      continue;
-    }
-    if (strcmp((map + i)->url, url) == 0) {
-      free((map + i)->url);
-      (map + i)->url = NULL;
-      free((map + i)->cred.password);
-      free((map + i)->cred.username);
-      break;
+static node_t * rem(node_t *p, const char *url){
+  node_t * const start = p;
+  /* remember where the pointer to p was stored */
+  node_t ** pptr = NULL;
+  while (p != NULL){
+    int ret = strcmp(url,p->url);
+    if (ret == 0){
+      node_t * left = p->left;
+      node_t * const right = p->right;
+      left = node_insert(left,right);
+      node_free(p);
+      if (pptr != NULL){
+        *pptr = left;
+        return start;
+      }else{
+        /* p was the only node in the tree */
+        assert(p == start);
+        return left;
+      }
+    }else if (ret < 0){
+      pptr = &(p->left);
+      p = p->left;
+    }else{
+      pptr = &(p->right);
+      p = p->right;
     }
   }
-  return map;
+  return start; // not found
 }
 
 const char WHITESPACE[] = " \t\r\n";
@@ -294,112 +231,103 @@ node_t * map = NULL;
    tree traversal algorithms without using recursion (to avoid stack overflow
    for very large trees). Stack overflow is a trivial form of memory-safety
    vulnerability. */
-// typedef struct nodeptr_list_elem {
-//   const node_t *p;
-//   struct nodeptr_list_elem *next;
-//   struct nodeptr_list_elem *prev;
-// } nodeptr_list_elem_t;
-
-// typedef struct nodeptr_list {
-//   nodeptr_list_elem_t *head;
-//   nodeptr_list_elem_t *last;
-// } nodeptr_list_t;
-
-
-// /* push an element p onto the front of a nodeptr list lst */
-// nodeptr_list_t list_push(nodeptr_list_t lst, const node_t *p){
-//   nodeptr_list_elem_t *n = malloc(sizeof(nodeptr_list_elem_t));
-//   assert(n != NULL && "push: malloc failed");
-//   n->p = p;
-//   n->next = lst.head;
-//   n->prev = NULL;  
-//   if (lst.head != NULL){
-//     assert(lst.last != NULL);
-//     lst.head->prev = n;
-//   }else{
-//     assert(lst.last == NULL);
-//     lst.last = n;
-//   }
-//   lst.head = n;
+typedef struct nodeptr_list_elem {
+  const node_t *p;
+  struct nodeptr_list_elem *next;
+  struct nodeptr_list_elem *prev;
+} nodeptr_list_elem_t;
+
+typedef struct nodeptr_list {
+  nodeptr_list_elem_t *head;
+  nodeptr_list_elem_t *last;
+} nodeptr_list_t;
+
+
+/* push an element p onto the front of a nodeptr list lst */
+nodeptr_list_t list_push(nodeptr_list_t lst, const node_t *p){
+  nodeptr_list_elem_t *n = malloc(sizeof(nodeptr_list_elem_t));
+  assert(n != NULL && "push: malloc failed");
+  n->p = p;
+  n->next = lst.head;
+  n->prev = NULL;  
+  if (lst.head != NULL){
+    assert(lst.last != NULL);
+    lst.head->prev = n;
+  }else{
+    assert(lst.last == NULL);
+    lst.last = n;
+  }
+  lst.head = n;
   
-//   return lst;
-// }
-
-// /* when out is non-NULL we place a pointer to the first node into it.
-//    assumption: lst.head and lst.last are non-NULL */
-// nodeptr_list_t list_pop(nodeptr_list_t lst, const node_t **out){
-//   assert(lst.head != NULL && lst.last != NULL);
-//   if (out != NULL){
-//     *out = lst.head->p;
-//   }
-//   if (lst.last == lst.head){
-//     free(lst.head);
-//     lst.head = NULL;
-//     lst.last = NULL;
-//   }else{
-//     nodeptr_list_elem_t *ret = lst.head->next;
-//     free(lst.head);
-//     lst.head = ret;
-//   }
-//   return lst;
-// }
-
-// /* when out is non-NULL we place a pointer to the last node into it.
-//    assumption: lst.head and lst.last are non-NULL */
-// nodeptr_list_t list_dequeue(nodeptr_list_t lst, const node_t **out){
-//   assert(lst.head != NULL && lst.last != NULL);
-//   if (out != NULL){
-//     *out = lst.last->p;
-//   }
-
-//   if (lst.last == lst.head){
-//     free(lst.head);
-//     lst.head = NULL;
-//     lst.last = NULL;
-//   }else{
-//     nodeptr_list_elem_t *ret = lst.last->prev;
-//     free(lst.last);
-//     lst.last = ret;
-//   }
-//   return lst;
-// }
+  return lst;
+}
+
+/* when out is non-NULL we place a pointer to the first node into it.
+   assumption: lst.head and lst.last are non-NULL */
+nodeptr_list_t list_pop(nodeptr_list_t lst, const node_t **out){
+  assert(lst.head != NULL && lst.last != NULL);
+  if (out != NULL){
+    *out = lst.head->p;
+  }
+  if (lst.last == lst.head){
+    free(lst.head);
+    lst.head = NULL;
+    lst.last = NULL;
+  }else{
+    nodeptr_list_elem_t *ret = lst.head->next;
+    free(lst.head);
+    lst.head = ret;
+  }
+  return lst;
+}
+
+/* when out is non-NULL we place a pointer to the last node into it.
+   assumption: lst.head and lst.last are non-NULL */
+nodeptr_list_t list_dequeue(nodeptr_list_t lst, const node_t **out){
+  assert(lst.head != NULL && lst.last != NULL);
+  if (out != NULL){
+    *out = lst.last->p;
+  }
+
+  if (lst.last == lst.head){
+    free(lst.head);
+    lst.head = NULL;
+    lst.last = NULL;
+  }else{
+    nodeptr_list_elem_t *ret = lst.last->prev;
+    free(lst.last);
+    lst.last = ret;
+  }
+  return lst;
+}
 
 /* in order traversal to print out nodes in sorted order. Is used to
    implement listing of all entries in the passbook */
-void print_inorder( ){
-  // nodeptr_list_t lst = {.head = NULL, .last = NULL};
-  // if (p != NULL){
-  //   lst = list_push(lst,p);
-
-  //   while(lst.head != NULL){
-  //     // keep recursing left until we can go no further
-  //     while (p->left != NULL){
-  //       lst = list_push(lst,p->left);
-  //       p = p->left;
-  //     }
+void print_inorder(const node_t *p){
+  nodeptr_list_t lst = {.head = NULL, .last = NULL};
+  if (p != NULL){
+    lst = list_push(lst,p);
+
+    while(lst.head != NULL){
+      // keep recursing left until we can go no further
+      while (p->left != NULL){
+        lst = list_push(lst,p->left);
+        p = p->left;
+      }
       
-  //     // pop from the stack to simulate the return
-  //     const node_t *q;
-  //     lst = list_pop(lst,&q);
-
-  //     // print the node following the return
-  //     node_print(q);
-
-  //     // simulate right recursive call
-  //     if (q->right != NULL){
-  //       lst = list_push(lst,q->right);
-  //       p = q->right;
-  //     }
-  //   }
-  // }
-  if (map == NULL) {
-    return;
-  }
-  for (int i = 0; i < MAP_NODE_NUM; i++) {
-    if((map + i)->url == NULL) {
-      continue;
+      // pop from the stack to simulate the return
+      const node_t *q;
+      lst = list_pop(lst,&q);
+
+      // print the node following the return
+      node_print(q);
+
+      // simulate right recursive call
+      if (q->right != NULL){
+        lst = list_push(lst,q->right);
+        p = q->right;
+      }
     }
-    node_print((map + i));
   }
 }
 
@@ -432,7 +360,7 @@ void masterpw_save(const char *pw, FILE *f){
    that the resulting tree has the same structure as the original one.
    This is how we save the passbook to a file.
    Returns 0 on success; nonzero on failure */
-int save_levelorder(const node_t *map, const char *masterpw,
+int save_levelorder(const node_t *p, const char *masterpw,
                     const char * filename){
 #ifdef PASSBOOK_FUZZ
   // ignore the file name when fuzzing etc. to avoid DoS on the server
@@ -445,30 +373,20 @@ int save_levelorder(const node_t *map, const char *masterpw,
     return -1;
   }
   masterpw_save(masterpw,f);
-  // nodeptr_list_t lst = {.head = NULL, .last = NULL};
-  // if (p != NULL){
-  //   lst = list_push(lst,p);
-
-  //   while(lst.last != NULL){
-  //     lst = list_dequeue(lst,&p);
-  //     node_save(p,f);
-  //     if (p->left != NULL){
-  //       lst = list_push(lst,p->left);
-  //     }
-  //     if (p->right != NULL){
-  //       lst = list_push(lst,p->right);
-  //     }
-  //   }
-  // }
-  if (map == NULL) {
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
-  }
-  for(int i = 0; i < MAP_NODE_NUM; i++) {
-    if ((map + i)->url == NULL) {
-      continue;
+  nodeptr_list_t lst = {.head = NULL, .last = NULL};
+  if (p != NULL){
+    lst = list_push(lst,p);
+
+    while(lst.last != NULL){
+      lst = list_dequeue(lst,&p);
+      node_save(p,f);
+      if (p->left != NULL){
+        lst = list_push(lst,p->left);
+      }
+      if (p->right != NULL){
+        lst = list_push(lst,p->right);
+      }
     }
-    node_save((map + i), f);
   }
   fclose(f);
   return 0;
@@ -497,9 +415,7 @@ static int execute(void){
       printf("Not found.\n");
     }
     destroy(map);
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
-
+    map = NULL;
   } else if (strcmp(toks[0],INSTRUCTION_REM) == 0){
     if (numToks != 2){
       debug_printf("Expected 1 argument to %s instruction but instead found %u\n",INSTRUCTION_REM,numToks-1);
@@ -507,9 +423,7 @@ static int execute(void){
     }
     debug_printf("Removing: %s\n",toks[1]);
     map = rem(map,toks[1]);
-    destroy(map);
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
+    
   } else if (strcmp(toks[0],INSTRUCTION_PUT) == 0){
     if (numToks != 4){
       debug_printf("Expected 3 arguments to %s instruction but instead found %u\n",INSTRUCTION_PUT,numToks-1);
@@ -530,9 +444,7 @@ static int execute(void){
       debug_printf("Error saving to file %s\n",toks[2]);
       return -1;
     }
-    destroy(map);
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
+
   } else if (strcmp(toks[0],INSTRUCTION_MASTERPW) == 0){
     if (numToks != 2){
       debug_printf("Expected 1 argument to %s instruction but instead found %u\n",INSTRUCTION_MASTERPW,numToks-1);      return -1;
@@ -547,15 +459,14 @@ static int execute(void){
 #else
     return -1; 
 #endif    
+
   } else if (strcmp(toks[0],INSTRUCTION_LIST) == 0){
     if (numToks != 1){
       debug_printf("Expected 0 arguments to %s instruction but instead found %u\n",INSTRUCTION_LIST,numToks-1);
       return -1;
     }
-    print_inorder();
-    destroy(map);
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
+    print_inorder(map);
+
   }else{
     debug_printf("Unrecognised instruction %s\n",toks[0]);
     return -1;
@@ -665,8 +576,6 @@ int main(const int argc, const char * argv[]){
         exit(1);
       }
     }
-    map = (node_t *)calloc(MAP_NODE_NUM, sizeof(node_t));
-    assert(map != NULL);
     int ans = run(f);
     if (ans < 0){
       fprintf(stderr,"Error\n");
-- 
GitLab