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
17#include <openssl/crypto.h>
18#include <openssl/err.h>
19#include <openssl/mem.h>
20
21
22static int test_overflow(void) {
23  unsigned i;
24
25  for (i = 0; i < ERR_NUM_ERRORS*2; i++) {
26    ERR_put_error(1, 2, 3, "test", 1);
27  }
28
29  for (i = 0; i < ERR_NUM_ERRORS - 1; i++) {
30    if (ERR_get_error() == 0) {
31      fprintf(stderr, "ERR_get_error failed at %u\n", i);
32      return 0;
33    }
34  }
35
36  if (ERR_get_error() != 0) {
37    fprintf(stderr, "ERR_get_error more than the expected number of values.\n");
38    return 0;
39  }
40
41  return 1;
42}
43
44static int test_put_error(void) {
45  uint32_t packed_error;
46  int line, flags;
47  const char *file;
48  char *data;
49
50  if (ERR_get_error() != 0) {
51    fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
52    return 0;
53  }
54
55  ERR_put_error(1, 2, 3, "test", 4);
56  ERR_add_error_data(1, "testing");
57
58  packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
59  if (strcmp(file, "test") != 0 ||
60      line != 4 ||
61      (flags & ERR_FLAG_STRING) == 0 ||
62      (flags & ERR_FLAG_MALLOCED) == 0 ||
63      ERR_GET_LIB(packed_error) != 1 ||
64      ERR_GET_FUNC(packed_error) != 2 ||
65      ERR_GET_REASON(packed_error) != 3 ||
66      strcmp(data, "testing") != 0) {
67    fprintf(stderr, "Bad error data returned.\n");
68    return 0;
69  }
70
71  OPENSSL_free(data);
72
73  return 1;
74}
75
76static int test_clear_error(void) {
77  if (ERR_get_error() != 0) {
78    fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
79    return 0;
80  }
81
82  ERR_put_error(1, 2, 3, "test", 4);
83  ERR_clear_error();
84
85  if (ERR_get_error() != 0) {
86    fprintf(stderr, "Error remained after clearing.\n");
87    return 0;
88  }
89
90  return 1;
91}
92
93static int test_print(void) {
94  size_t i;
95  char buf[256];
96  uint32_t packed_error;
97
98  ERR_put_error(1, 2, 3, "test", 4);
99  ERR_add_error_data(1, "testing");
100  packed_error = ERR_get_error();
101
102  for (i = 0; i <= sizeof(buf); i++) {
103    ERR_error_string_n(packed_error, buf, i);
104  }
105
106  return 1;
107}
108
109static int test_release(void) {
110  ERR_put_error(1, 2, 3, "test", 4);
111  ERR_remove_thread_state(NULL);
112  return 1;
113}
114
115int main(void) {
116  CRYPTO_library_init();
117
118  if (!test_overflow() ||
119      !test_put_error() ||
120      !test_clear_error() ||
121      !test_print() ||
122      !test_release()) {
123    return 1;
124  }
125
126  printf("PASS\n");
127  return 0;
128}
129