2 * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include <openssl/opensslconf.h>
12 #include <openssl/err.h>
13 #include <openssl/macros.h>
17 #if defined(OPENSSL_SYS_WINDOWS)
23 #ifndef OPENSSL_NO_DEPRECATED_3_0
24 # define IS_HEX(ch) ((ch >= '0' && ch <='9') || (ch >= 'A' && ch <='F'))
26 static int test_print_error_format(void)
28 /* Variables used to construct an error line */
30 const char *func = OPENSSL_FUNC;
32 # ifdef OPENSSL_NO_ERR
35 # ifndef OPENSSL_NO_FILENAMES
36 const char *file = OPENSSL_FILE;
37 const int line = OPENSSL_LINE;
39 const char *file = "";
42 /* The format for OpenSSL error lines */
43 const char *expected_format = ":error:%08lX:%s:%s:%s:%s:%d";
46 * "library" name --------------------------++ || || || ||
47 * function name ------------------------------++ || || ||
48 * reason string (system error string) -----------++ || ||
49 * file name ----------------------------------------++ ||
50 * line number -----------------------------------------++
54 char *out = NULL, *p = NULL;
57 const int syserr = EPERM;
58 unsigned long errorcode;
59 unsigned long reasoncode;
62 * We set a mark here so we can clear the system error that we generate
63 * with ERR_PUT_error(). That is, after all, just a simulation to verify
64 * ERR_print_errors() output, not a real error.
68 ERR_PUT_error(ERR_LIB_SYS, 0, syserr, file, line);
69 errorcode = ERR_peek_error();
70 reasoncode = ERR_GET_REASON(errorcode);
72 if (!TEST_int_eq(reasoncode, syserr)) {
77 # ifndef OPENSSL_NO_ERR
78 lib = "system library";
79 reason = strerror(syserr);
82 BIO_snprintf(reasonbuf, sizeof(reasonbuf), "reason(%lu)", reasoncode);
86 BIO_snprintf(expected, sizeof(expected), expected_format,
87 errorcode, lib, func, reason, file, line);
89 if (!TEST_ptr(bio = BIO_new(BIO_s_mem())))
92 ERR_print_errors(bio);
94 if (!TEST_int_gt(len = BIO_get_mem_data(bio, &out), 0))
96 /* Skip over the variable thread id at the start of the string */
97 for (p = out; *p != ':' && *p != 0; ++p) {
98 if (!TEST_true(IS_HEX(*p)))
101 if (!TEST_true(*p != 0)
102 || !TEST_strn_eq(expected, p, strlen(expected)))
112 /* Test that querying the error queue preserves the OS error. */
113 static int preserves_system_error(void)
115 #if defined(OPENSSL_SYS_WINDOWS)
116 SetLastError(ERROR_INVALID_FUNCTION);
118 return TEST_int_eq(GetLastError(), ERROR_INVALID_FUNCTION);
122 return TEST_int_eq(errno, EINVAL);
126 /* Test that calls to ERR_add_error_[v]data append */
127 static int vdata_appends(void)
131 ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
132 ERR_add_error_data(1, "hello ");
133 ERR_add_error_data(1, "world");
134 ERR_peek_error_data(&data, NULL);
135 return TEST_str_eq(data, "hello world");
138 static int raised_error(void)
140 const char *f, *data;
145 * When OPENSSL_NO_ERR or OPENSSL_NO_FILENAMES, no file name or line
146 * number is saved, so no point checking them.
148 #if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR)
153 line = __LINE__ + 2; /* The error is generated on the ERR_raise_data line */
155 ERR_raise_data(ERR_LIB_NONE, ERR_R_INTERNAL_ERROR,
157 if (!TEST_ulong_ne(e = ERR_get_error_all(&f, &l, NULL, &data, NULL), 0)
158 || !TEST_int_eq(ERR_GET_REASON(e), ERR_R_INTERNAL_ERROR)
159 #if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR)
160 || !TEST_int_eq(l, line)
161 || !TEST_str_eq(f, file)
163 || !TEST_str_eq(data, "calling exit()"))
168 static int test_marks(void)
170 unsigned long mallocfail, shouldnot;
172 /* Set an initial error */
173 ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
174 mallocfail = ERR_peek_last_error();
175 if (!TEST_ulong_gt(mallocfail, 0))
178 /* Setting and clearing a mark should not affect the error */
179 if (!TEST_true(ERR_set_mark())
180 || !TEST_true(ERR_pop_to_mark())
181 || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())
182 || !TEST_true(ERR_set_mark())
183 || !TEST_true(ERR_clear_last_mark())
184 || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
187 /* Test popping errors */
188 if (!TEST_true(ERR_set_mark()))
190 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
191 if (!TEST_ulong_ne(mallocfail, ERR_peek_last_error())
192 || !TEST_true(ERR_pop_to_mark())
193 || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
196 /* Nested marks should also work */
197 if (!TEST_true(ERR_set_mark())
198 || !TEST_true(ERR_set_mark()))
200 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
201 if (!TEST_ulong_ne(mallocfail, ERR_peek_last_error())
202 || !TEST_true(ERR_pop_to_mark())
203 || !TEST_true(ERR_pop_to_mark())
204 || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
207 if (!TEST_true(ERR_set_mark()))
209 ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
210 shouldnot = ERR_peek_last_error();
211 if (!TEST_ulong_ne(mallocfail, shouldnot)
212 || !TEST_true(ERR_set_mark()))
214 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
215 if (!TEST_ulong_ne(shouldnot, ERR_peek_last_error())
216 || !TEST_true(ERR_pop_to_mark())
217 || !TEST_ulong_eq(shouldnot, ERR_peek_last_error())
218 || !TEST_true(ERR_pop_to_mark())
219 || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
222 /* Setting and clearing a mark should not affect the errors on the stack */
223 if (!TEST_true(ERR_set_mark()))
225 ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
226 if (!TEST_true(ERR_clear_last_mark())
227 || !TEST_ulong_eq(shouldnot, ERR_peek_last_error()))
231 * Popping where no mark has been set should pop everything - but return
234 if (!TEST_false(ERR_pop_to_mark())
235 || !TEST_ulong_eq(0, ERR_peek_last_error()))
238 /* Clearing where there is no mark should fail */
239 ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
240 if (!TEST_false(ERR_clear_last_mark())
241 /* "get" the last error to remove it */
242 || !TEST_ulong_eq(mallocfail, ERR_get_error())
243 || !TEST_ulong_eq(0, ERR_peek_last_error()))
247 * Setting a mark where there are no errors in the stack should fail.
248 * NOTE: This is somewhat surprising behaviour but is historically how this
249 * function behaves. In practice we typically set marks without first
250 * checking whether there is anything on the stack - but we also don't
251 * tend to check the success of this function. It turns out to work anyway
252 * because although setting a mark with no errors fails, a subsequent call
253 * to ERR_pop_to_mark() or ERR_clear_last_mark() will do the right thing
254 * anyway (even though they will report a failure result).
256 if (!TEST_false(ERR_set_mark()))
259 ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
260 if (!TEST_true(ERR_set_mark()))
262 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
263 ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
265 /* Should be able to "pop" past 2 errors */
266 if (!TEST_true(ERR_pop_to_mark())
267 || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
270 if (!TEST_true(ERR_set_mark()))
272 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
273 ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
275 /* Should be able to "clear" past 2 errors */
276 if (!TEST_true(ERR_clear_last_mark())
277 || !TEST_ulong_eq(shouldnot, ERR_peek_last_error()))
280 /* Clear remaining errors from last test */
286 int setup_tests(void)
288 ADD_TEST(preserves_system_error);
289 ADD_TEST(vdata_appends);
290 ADD_TEST(raised_error);
291 #ifndef OPENSSL_NO_DEPRECATED_3_0
292 ADD_TEST(test_print_error_format);
294 ADD_TEST(test_marks);