Fix build on OPENSSL_SYS_TANDEM and older POSIXes
It also allows for passing -DOPENSSL_NO_LOCALE as a workaround
to ./Configure command.
Fixes #18233
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18282)
diff --git a/crypto/ctype.c b/crypto/ctype.c
index e60ccd2..f90ef19 100644
--- a/crypto/ctype.c
+++ b/crypto/ctype.c
@@ -14,16 +14,12 @@
#include "internal/e_os.h"
#include "internal/core.h"
-
-#ifndef OPENSSL_SYS_WINDOWS
-#include <strings.h>
+#ifndef OPENSSL_NO_LOCALE
+# include <locale.h>
+# ifdef OPENSSL_SYS_MACOSX
+# include <xlocale.h>
+# endif
#endif
-#include <locale.h>
-
-#ifdef OPENSSL_SYS_MACOSX
-#include <xlocale.h>
-#endif
-
/*
* Define the character classes for each character in the seven bit ASCII
* character set. This is independent of the host's character set, characters
@@ -291,24 +287,14 @@
return 0;
}
-/* str[n]casecmp_l is defined in POSIX 2008-01. Value is taken accordingly
- * https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html */
-
-#if (defined OPENSSL_SYS_WINDOWS) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
-
-# if defined OPENSSL_SYS_WINDOWS
-# define locale_t _locale_t
-# define freelocale _free_locale
-# define strcasecmp_l _stricmp_l
-# define strncasecmp_l _strnicmp_l
-# endif
+#ifndef OPENSSL_NO_LOCALE
+# ifndef FIPS_MODULE
static locale_t loc;
-# ifndef FIPS_MODULE
+
void *ossl_c_locale() {
return (void *)loc;
}
-# endif
int ossl_init_casecmp_int() {
# ifdef OPENSSL_SYS_WINDOWS
@@ -322,6 +308,7 @@
void ossl_deinit_casecmp() {
freelocale(loc);
}
+# endif
int OPENSSL_strcasecmp(const char *s1, const char *s2)
{
diff --git a/include/internal/e_os.h b/include/internal/e_os.h
index 514de96..fd45d20 100644
--- a/include/internal/e_os.h
+++ b/include/internal/e_os.h
@@ -409,4 +409,23 @@
# endif
# endif
+/*
+ * str[n]casecmp_l is defined in POSIX 2008-01. Value is taken accordingly
+ * https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
+ * There are also equivalent functions on Windows.
+ * There is no locale_t on NONSTOP.
+ */
+# if defined(OPENSSL_SYS_WINDOWS)
+# define locale_t _locale_t
+# define freelocale _free_locale
+# define strcasecmp_l _stricmp_l
+# define strncasecmp_l _strnicmp_l
+# define strcasecmp _stricmp
+# elif !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L \
+ || defined(OPENSSL_SYS_TANDEM)
+# ifndef OPENSSL_NO_LOCALE
+# define OPENSSL_NO_LOCALE
+# endif
+# endif
+
#endif
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 1b79c00..5436c48 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -24,6 +24,7 @@
#include "self_test.h"
#include "crypto/context.h"
#include "internal/core.h"
+#include "internal/e_os.h"
static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes";
static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no";
@@ -38,17 +39,13 @@
static OSSL_FUNC_provider_query_operation_fn fips_query;
/* Locale object accessor functions */
-#ifdef OPENSSL_SYS_MACOSX
-# include <xlocale.h>
-#else
+#ifndef OPENSSL_NO_LOCALE
# include <locale.h>
-#endif
-
-#if defined OPENSSL_SYS_WINDOWS
-# define locale_t _locale_t
-# define freelocale _free_locale
-#endif
+# ifdef OPENSSL_SYS_MACOSX
+# include <xlocale.h>
+# endif
static locale_t loc;
+#endif
static int fips_init_casecmp(void);
static void fips_deinit_casecmp(void);
@@ -495,22 +492,35 @@
return NULL;
}
+# ifndef OPENSSL_NO_LOCALE
void *ossl_c_locale() {
return (void *)loc;
}
static int fips_init_casecmp(void) {
-# ifdef OPENSSL_SYS_WINDOWS
+# ifdef OPENSSL_SYS_WINDOWS
loc = _create_locale(LC_COLLATE, "C");
-# else
+# else
loc = newlocale(LC_COLLATE_MASK, "C", (locale_t) 0);
-# endif
+# endif
return (loc == (locale_t) 0) ? 0 : 1;
}
static void fips_deinit_casecmp(void) {
freelocale(loc);
}
+# else
+void *ossl_c_locale() {
+ return NULL;
+}
+
+static int fips_init_casecmp(void) {
+ return 1;
+}
+
+static void fips_deinit_casecmp(void) {
+}
+# endif
static void fips_teardown(void *provctx)
{
diff --git a/test/localetest.c b/test/localetest.c
index 270236a..9f13d38 100644
--- a/test/localetest.c
+++ b/test/localetest.c
@@ -1,3 +1,11 @@
+/*
+ * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (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 <stdio.h>
#include <string.h>
@@ -6,12 +14,12 @@
#include "testutil/output.h"
#include <stdlib.h>
-#include <locale.h>
-#ifdef OPENSSL_SYS_WINDOWS
-# define strcasecmp _stricmp
-#else
-# include <strings.h>
-#endif
+#include "internal/e_os.h"
+#ifndef OPENSSL_NO_LOCALE
+# include <locale.h>
+# ifdef OPENSSL_SYS_MACOSX
+# include <xlocale.h>
+# endif
int setup_tests(void)
{
@@ -117,7 +125,12 @@
X509_free(cert);
return 1;
}
-
+#else
+int setup_tests(void)
+{
+ return TEST_skip("Locale support not available");
+}
+#endif /* OPENSSL_NO_LOCALE */
void cleanup_tests(void)
{
}