forked from OSchip/llvm-project
[dfsan] Fix a bug in strcasecmp() and strncasecmp(): Compare the lowercase versions of the characters when choosing a return value.
Summary: Resolves this bug: https://bugs.llvm.org/show_bug.cgi?id=38369 Reviewers: morehouse, pcc Reviewed By: morehouse Subscribers: #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D78490
This commit is contained in:
parent
22219cfc6a
commit
e5ce95c660
|
@ -157,14 +157,17 @@ SANITIZER_INTERFACE_ATTRIBUTE int
|
||||||
__dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label,
|
__dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label,
|
||||||
dfsan_label s2_label, dfsan_label *ret_label) {
|
dfsan_label s2_label, dfsan_label *ret_label) {
|
||||||
for (size_t i = 0;; ++i) {
|
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) {
|
if (flags().strict_data_dependencies) {
|
||||||
*ret_label = 0;
|
*ret_label = 0;
|
||||||
} else {
|
} else {
|
||||||
*ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
|
*ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
|
||||||
dfsan_read_label(s2, i + 1));
|
dfsan_read_label(s2, i + 1));
|
||||||
}
|
}
|
||||||
return s1[i] - s2[i];
|
return s1_lower - s2_lower;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -212,15 +215,17 @@ __dfsw_strncasecmp(const char *s1, const char *s2, size_t n,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0;; ++i) {
|
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]);
|
||||||
i == n - 1) {
|
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) {
|
if (flags().strict_data_dependencies) {
|
||||||
*ret_label = 0;
|
*ret_label = 0;
|
||||||
} else {
|
} else {
|
||||||
*ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
|
*ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
|
||||||
dfsan_read_label(s2, i + 1));
|
dfsan_read_label(s2, i + 1));
|
||||||
}
|
}
|
||||||
return s1[i] - s2[i];
|
return s1_lower - s2_lower;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -207,6 +207,19 @@ void test_strcasecmp() {
|
||||||
#else
|
#else
|
||||||
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
|
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char s1[] = "AbZ";
|
||||||
|
char s2[] = "aBy";
|
||||||
|
dfsan_set_label(i_label, &s1[2], 1);
|
||||||
|
dfsan_set_label(j_label, &s2[2], 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() {
|
void test_strncasecmp() {
|
||||||
|
@ -225,6 +238,31 @@ void test_strncasecmp() {
|
||||||
rv = strncasecmp(str1, str2, 3);
|
rv = strncasecmp(str1, str2, 3);
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
ASSERT_ZERO_LABEL(rv);
|
ASSERT_ZERO_LABEL(rv);
|
||||||
|
|
||||||
|
char s1[] = "AbZ";
|
||||||
|
char s2[] = "aBy";
|
||||||
|
dfsan_set_label(i_label, &s1[2], 1);
|
||||||
|
dfsan_set_label(j_label, &s2[2], 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); // 'Z' > 'y'
|
||||||
|
#ifdef STRICT_DATA_DEPENDENCIES
|
||||||
|
ASSERT_ZERO_LABEL(rv);
|
||||||
|
#else
|
||||||
|
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_strchr() {
|
void test_strchr() {
|
||||||
|
|
Loading…
Reference in New Issue