summaryrefslogtreecommitdiffstats
path: root/test/errtest.c
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2018-05-20 17:24:30 -0400
committerDavid Benjamin <davidben@google.com>2018-05-23 17:34:54 -0400
commit2de108dfa343c3e06eb98beb122cd06306bb12fd (patch)
tree3e49b8444a3c29a076eac36a126b77d7891d2f5b /test/errtest.c
parente363534cfe0ae01503dde6963e0631ec5f7fef3f (diff)
Save and restore the Windows error around TlsGetValue.
TlsGetValue clears the last error even on success, so that callers may distinguish it successfully returning NULL or failing. This error-mangling behavior interferes with the caller's use of GetLastError. In particular SSL_get_error queries the error queue to determine whether the caller should look at the OS's errors. To avoid destroying state, save and restore the Windows error. Fixes #6299. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6316)
Diffstat (limited to 'test/errtest.c')
-rw-r--r--test/errtest.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/test/errtest.c b/test/errtest.c
new file mode 100644
index 0000000000..e464d08bc0
--- /dev/null
+++ b/test/errtest.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/opensslconf.h>
+#include <openssl/err.h>
+
+#include "testutil.h"
+
+#if defined(OPENSSL_SYS_WINDOWS)
+# include <windows.h>
+#else
+# include <errno.h>
+#endif
+
+/* Test that querying the error queue preserves the OS error. */
+static int preserves_system_error(void)
+{
+#if defined(OPENSSL_SYS_WINDOWS)
+ SetLastError(ERROR_INVALID_FUNCTION);
+ ERR_get_error();
+ return TEST_int_eq(GetLastError(), ERROR_INVALID_FUNCTION);
+#else
+ errno = EINVAL;
+ ERR_get_error();
+ return TEST_int_eq(errno, EINVAL);
+#endif
+}
+
+int setup_tests(void)
+{
+ ADD_TEST(preserves_system_error);
+ return 1;
+}