|
12 | 12 | #include "crypto/ctype.h" |
13 | 13 | #include <openssl/ebcdic.h> |
14 | 14 |
|
| 15 | +#include <openssl/crypto.h> |
| 16 | +#include "internal/core.h" |
| 17 | +#include "internal/thread_once.h" |
| 18 | + |
| 19 | +#ifndef OPENSSL_SYS_WINDOWS |
| 20 | +#include <strings.h> |
| 21 | +#endif |
| 22 | +#include <locale.h> |
| 23 | + |
| 24 | +#ifdef OPENSSL_SYS_MACOSX |
| 25 | +#include <xlocale.h> |
| 26 | +#endif |
| 27 | + |
15 | 28 | /* |
16 | 29 | * Define the character classes for each character in the seven bit ASCII |
17 | 30 | * character set. This is independent of the host's character set, characters |
@@ -278,3 +291,90 @@ int ossl_ascii_isdigit(const char inchar) { |
278 | 291 | return 1; |
279 | 292 | return 0; |
280 | 293 | } |
| 294 | + |
| 295 | +/* str[n]casecmp_l is defined in POSIX 2008-01. Value is taken accordingly |
| 296 | + * https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html */ |
| 297 | + |
| 298 | +#if (defined OPENSSL_SYS_WINDOWS) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) |
| 299 | + |
| 300 | +# if defined OPENSSL_SYS_WINDOWS |
| 301 | +# define locale_t _locale_t |
| 302 | +# define freelocale _free_locale |
| 303 | +# define strcasecmp_l _stricmp_l |
| 304 | +# define strncasecmp_l _strnicmp_l |
| 305 | +# endif |
| 306 | + |
| 307 | +# ifndef FIPS_MODULE |
| 308 | +static locale_t loc; |
| 309 | + |
| 310 | +static int locale_base_inited = 0; |
| 311 | +static CRYPTO_ONCE locale_base = CRYPTO_ONCE_STATIC_INIT; |
| 312 | +static CRYPTO_ONCE locale_base_deinit = CRYPTO_ONCE_STATIC_INIT; |
| 313 | + |
| 314 | +void *ossl_c_locale() { |
| 315 | + return (void *)loc; |
| 316 | +} |
| 317 | + |
| 318 | +DEFINE_RUN_ONCE_STATIC(ossl_init_locale_base) |
| 319 | +{ |
| 320 | +# ifdef OPENSSL_SYS_WINDOWS |
| 321 | + loc = _create_locale(LC_COLLATE, "C"); |
| 322 | +# else |
| 323 | + loc = newlocale(LC_COLLATE_MASK, "C", (locale_t) 0); |
| 324 | +# endif |
| 325 | + locale_base_inited = 1; |
| 326 | + return (loc == (locale_t) 0) ? 0 : 1; |
| 327 | +} |
| 328 | + |
| 329 | +DEFINE_RUN_ONCE_STATIC(ossl_deinit_locale_base) |
| 330 | +{ |
| 331 | + if (locale_base_inited && loc) { |
| 332 | + freelocale(loc); |
| 333 | + loc = NULL; |
| 334 | + } |
| 335 | + return 1; |
| 336 | +} |
| 337 | + |
| 338 | +int ossl_init_casecmp() |
| 339 | +{ |
| 340 | + return RUN_ONCE(&locale_base, ossl_init_locale_base); |
| 341 | +} |
| 342 | + |
| 343 | +void ossl_deinit_casecmp() { |
| 344 | + (void)RUN_ONCE(&locale_base_deinit, ossl_deinit_locale_base); |
| 345 | +} |
| 346 | +# endif |
| 347 | + |
| 348 | +int OPENSSL_strcasecmp(const char *s1, const char *s2) |
| 349 | +{ |
| 350 | + return strcasecmp_l(s1, s2, (locale_t)ossl_c_locale()); |
| 351 | +} |
| 352 | + |
| 353 | +int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n) |
| 354 | +{ |
| 355 | + return strncasecmp_l(s1, s2, n, (locale_t)ossl_c_locale()); |
| 356 | +} |
| 357 | +#else |
| 358 | +# ifndef FIPS_MODULE |
| 359 | +void *ossl_c_locale() { |
| 360 | + return NULL; |
| 361 | +} |
| 362 | +# endif |
| 363 | + |
| 364 | +int ossl_init_casecmp() { |
| 365 | + return 1; |
| 366 | +} |
| 367 | + |
| 368 | +void ossl_deinit_casecmp() { |
| 369 | +} |
| 370 | + |
| 371 | +int OPENSSL_strcasecmp(const char *s1, const char *s2) |
| 372 | +{ |
| 373 | + return strcasecmp(s1, s2); |
| 374 | +} |
| 375 | + |
| 376 | +int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n) |
| 377 | +{ |
| 378 | + return strncasecmp(s1, s2, n); |
| 379 | +} |
| 380 | +#endif |
0 commit comments