diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp --- a/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -157,14 +157,17 @@ __dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, dfsan_label *ret_label) { for (size_t i = 0;; ++i) { - if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0) { + char s1_lower = tolower(s1[i]); + char s2_lower = tolower(s2[i]); + + if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0) { if (flags().strict_data_dependencies) { *ret_label = 0; } else { *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), dfsan_read_label(s2, i + 1)); } - return s1[i] - s2[i]; + return s1_lower - s2_lower; } } return 0; @@ -212,15 +215,17 @@ } for (size_t i = 0;; ++i) { - if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0 || - i == n - 1) { + char s1_lower = tolower(s1[i]); + char s2_lower = tolower(s2[i]); + + if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 || i == n - 1) { if (flags().strict_data_dependencies) { *ret_label = 0; } else { *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), dfsan_read_label(s2, i + 1)); } - return s1[i] - s2[i]; + return s1_lower - s2_lower; } } return 0; diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp --- a/compiler-rt/test/dfsan/custom.cpp +++ b/compiler-rt/test/dfsan/custom.cpp @@ -207,6 +207,19 @@ #else ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); #endif + + char s1[] = "ABCz"; + char s2[] = "abcY"; + dfsan_set_label(i_label, &s1[3], 1); + dfsan_set_label(j_label, &s2[3], 1); + + rv = strcasecmp(s1, s2); + assert(rv > 0); // 'z' > 'Y' +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); +#endif } void test_strncasecmp() { @@ -225,6 +238,35 @@ rv = strncasecmp(str1, str2, 3); assert(rv == 0); ASSERT_ZERO_LABEL(rv); + + char s1[] = "ABCz"; + char s2[] = "abcY"; + dfsan_set_label(i_label, &s1[3], 1); + dfsan_set_label(j_label, &s2[3], 1); + + rv = strncasecmp(s1, s2, 0); + assert(rv == 0); // Compare zero chars. + ASSERT_ZERO_LABEL(rv); + + rv = strncasecmp(s1, s2, 1); + assert(rv == 0); // 'a' == 'A' + ASSERT_ZERO_LABEL(rv); + + rv = strncasecmp(s1, s2, 2); + assert(rv == 0); // 'b' == 'B' + ASSERT_ZERO_LABEL(rv); + + rv = strncasecmp(s1, s2, 3); + assert(rv == 0); // 'c' == 'C' + ASSERT_ZERO_LABEL(rv); + + rv = strncasecmp(s1, s2, 4); + assert(rv > 0); // 'z' > 'Y' +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); +#endif } void test_strchr() {