Use functions that do not depend on the current locale.
X.509 functions and the like should not vary their behaviour based on
the configured locale, but tolower(3), strcasecmp(3) and strncasecmp(3)
change behaviour based on that.
For example, with tr_TR.utf8, 'I' is not the upper-case version of 'i'.
Change-Id: I896a285767ae0c22e6ce06b9908331c625e90af2
Reviewed-on: https://boringssl-review.googlesource.com/18412
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/mem.c b/crypto/mem.c
index 390ca2e..f451a12 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -159,27 +159,50 @@
char *OPENSSL_strdup(const char *s) { return _strdup(s); }
-int OPENSSL_strcasecmp(const char *a, const char *b) {
- return _stricmp(a, b);
-}
-
-int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
- return _strnicmp(a, b, n);
-}
-
#else
char *OPENSSL_strdup(const char *s) { return strdup(s); }
+#endif
+
+int OPENSSL_tolower(int c) {
+ if (c >= 'A' && c <= 'Z') {
+ return c + ('a' - 'A');
+ }
+ return c;
+}
+
int OPENSSL_strcasecmp(const char *a, const char *b) {
- return strcasecmp(a, b);
+ for (size_t i = 0;; i++) {
+ const int aa = OPENSSL_tolower(a[i]);
+ const int bb = OPENSSL_tolower(b[i]);
+
+ if (aa < bb) {
+ return -1;
+ } else if (aa > bb) {
+ return 1;
+ } else if (aa == 0) {
+ return 0;
+ }
+ }
}
int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
- return strncasecmp(a, b, n);
-}
+ for (size_t i = 0; i < n; i++) {
+ const int aa = OPENSSL_tolower(a[i]);
+ const int bb = OPENSSL_tolower(b[i]);
-#endif
+ if (aa < bb) {
+ return -1;
+ } else if (aa > bb) {
+ return 1;
+ } else if (aa == 0) {
+ return 0;
+ }
+ }
+
+ return 0;
+}
int BIO_snprintf(char *buf, size_t n, const char *format, ...) {
va_list args;
diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c
index e6eeb95..5fa9077 100644
--- a/crypto/x509/x_name.c
+++ b/crypto/x509/x_name.c
@@ -492,7 +492,7 @@
}
while (!(*from & 0x80) && isspace(*from));
} else {
- *to++ = tolower(*from);
+ *to++ = OPENSSL_tolower(*from);
from++;
i++;
}
diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c
index fe7787b..feb3dc6 100644
--- a/crypto/x509v3/v3_utl.c
+++ b/crypto/x509v3/v3_utl.c
@@ -454,15 +454,13 @@
OPENSSL_free(hexbuf);
return NULL;
}
- if (isupper(ch))
- ch = tolower(ch);
- if (isupper(cl))
- cl = tolower(cl);
if ((ch >= '0') && (ch <= '9'))
ch -= '0';
else if ((ch >= 'a') && (ch <= 'f'))
ch -= 'a' - 10;
+ else if ((ch >= 'A') && (ch <= 'F'))
+ ch -= 'A' - 10;
else
goto badhex;
@@ -470,6 +468,8 @@
cl -= '0';
else if ((cl >= 'a') && (cl <= 'f'))
cl -= 'a' - 10;
+ else if ((cl >= 'A') && (cl <= 'F'))
+ cl -= 'A' - 10;
else
goto badhex;
diff --git a/include/openssl/mem.h b/include/openssl/mem.h
index 5d96a2d..c43a16a 100644
--- a/include/openssl/mem.h
+++ b/include/openssl/mem.h
@@ -104,10 +104,13 @@
/* OPENSSL_strnlen has the same behaviour as strnlen(3). */
OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len);
-/* OPENSSL_strcasecmp has the same behaviour as strcasecmp(3). */
+/* OPENSSL_tolower is a locale-independent version of tolower(3). */
+OPENSSL_EXPORT int OPENSSL_tolower(int c);
+
+/* OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). */
OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b);
-/* OPENSSL_strncasecmp has the same behaviour as strncasecmp(3). */
+/* OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). */
OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n);
/* DECIMAL_SIZE returns an upper bound for the length of the decimal