1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <stdio.h>
16 #include <string.h>
17 
18 #include <openssl/crypto.h>
19 #include <openssl/pqueue.h>
20 #include <openssl/ssl.h>
21 
22 
clear_and_free_queue(pqueue q)23 static void clear_and_free_queue(pqueue q) {
24   for (;;) {
25     pitem *item = pqueue_pop(q);
26     if (item == NULL) {
27       break;
28     }
29     pitem_free(item);
30   }
31   pqueue_free(q);
32 }
33 
trivial(void)34 static int trivial(void) {
35   pqueue q = pqueue_new();
36   if (q == NULL) {
37     return 0;
38   }
39   int32_t data = 0xdeadbeef;
40   uint8_t priority[8] = {0};
41   pitem *item = pitem_new(priority, &data);
42   if (item == NULL ||
43       pqueue_insert(q, item) != item ||
44       pqueue_size(q) != 1 ||
45       pqueue_peek(q) != item ||
46       pqueue_pop(q) != item ||
47       pqueue_size(q) != 0 ||
48       pqueue_pop(q) != NULL) {
49     return 0;
50   }
51   pitem_free(item);
52   clear_and_free_queue(q);
53   return 1;
54 }
55 
56 #define NUM_ITEMS 10
57 
fixed_random(void)58 static int fixed_random(void) {
59   /* Random order of 10 elements, chosen by
60    * random.choice(list(itertools.permutations(range(10)))) */
61   int ordering[NUM_ITEMS] = {9, 6, 3, 4, 0, 2, 7, 1, 8, 5};
62   int i;
63   pqueue q = pqueue_new();
64   uint8_t priority[8] = {0};
65   piterator iter;
66   pitem *curr, *item;
67 
68   if (q == NULL) {
69     return 0;
70   }
71 
72   /* Insert the elements */
73   for (i = 0; i < NUM_ITEMS; i++) {
74     priority[7] = ordering[i];
75     item = pitem_new(priority, &ordering[i]);
76     if (item == NULL || pqueue_insert(q, item) != item) {
77       return 0;
78     }
79   }
80 
81   /* Insert the elements again. This inserts duplicates and should
82    * fail. */
83   for (i = 0; i < NUM_ITEMS; i++) {
84     priority[7] = ordering[i];
85     item = pitem_new(priority, &ordering[i]);
86     if (item == NULL || pqueue_insert(q, item) != NULL) {
87       return 0;
88     }
89     pitem_free(item);
90   }
91 
92   if (pqueue_size(q) != NUM_ITEMS) {
93     return 0;
94   }
95 
96   /* Iterate over the elements. */
97   iter = pqueue_iterator(q);
98   curr = pqueue_next(&iter);
99   if (curr == NULL) {
100     return 0;
101   }
102   while (1) {
103     pitem *next = pqueue_next(&iter);
104     int *curr_data, *next_data;
105 
106     if (next == NULL) {
107       break;
108     }
109     curr_data = (int*)curr->data;
110     next_data = (int*)next->data;
111     if (*curr_data >= *next_data) {
112       return 0;
113     }
114     curr = next;
115   }
116   clear_and_free_queue(q);
117   return 1;
118 }
119 
main(void)120 int main(void) {
121   CRYPTO_library_init();
122 
123   if (!trivial() || !fixed_random()) {
124     return 1;
125   }
126 
127   printf("PASS\n");
128   return 0;
129 }
130