From 1c92751a73f873e3e2af2973948a7dd03f6a9224 Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Sat, 17 Nov 2018 20:26:43 +0100 Subject: [PATCH] Don't rely on integer wrapping in ctype Don't rely on integer wrapping in ctype and fix strcasecmp on non-alphabetic characters --- src/header/ctype/mod.rs | 18 +++++++++--------- src/header/strings/mod.rs | 3 ++- tests/strings.c | 3 +++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/header/ctype/mod.rs b/src/header/ctype/mod.rs index 8506f8425..59e5c0ce6 100644 --- a/src/header/ctype/mod.rs +++ b/src/header/ctype/mod.rs @@ -24,27 +24,27 @@ pub extern "C" fn isblank(c: c_int) -> c_int { #[no_mangle] pub extern "C" fn iscntrl(c: c_int) -> c_int { - ((c as c_uint) < 0x20 || c == 0x7f) as c_int + (c < 0x20 || c == 0x7f) as c_int } #[no_mangle] pub extern "C" fn isdigit(c: c_int) -> c_int { - (((c - 0x30) as c_uint) < 10) as c_int + (c >= b'0' as c_int && c <= b'9' as c_int) as c_int } #[no_mangle] pub extern "C" fn isgraph(c: c_int) -> c_int { - (((c - 0x21) as c_uint) < 0x5e) as c_int + (c >= 0x21 && c < 0x7e) as c_int } #[no_mangle] pub extern "C" fn islower(c: c_int) -> c_int { - (((c - 0x61) as c_uint) < 26) as c_int + (c >= b'a' as c_int && c <= b'z' as c_int) as c_int } #[no_mangle] pub extern "C" fn isprint(c: c_int) -> c_int { - (((c - 0x20) as c_uint) < 0x5f) as c_int + (c >= 0x20 && c < 0x7f) as c_int } #[no_mangle] @@ -59,12 +59,12 @@ pub extern "C" fn isspace(c: c_int) -> c_int { #[no_mangle] pub extern "C" fn isupper(c: c_int) -> c_int { - (((c - 0x41) as c_uint) < 26) as c_int + (c >= b'A' as c_int && c <= b'Z' as c_int) as c_int } #[no_mangle] pub extern "C" fn isxdigit(c: c_int) -> c_int { - (isdigit(c) != 0 || ((c as c_int) | 32) - ('a' as c_int) < 6) as c_int + (isdigit(c) != 0 || (c | 32 >= b'a' as c_int && c | 32 <= 'f' as c_int)) as c_int } #[no_mangle] @@ -77,7 +77,7 @@ pub extern "C" fn toascii(c: c_int) -> c_int { #[no_mangle] pub extern "C" fn tolower(c: c_int) -> c_int { if isupper(c) != 0 { - c + 0x20 + c | 0x20 } else { c } @@ -86,7 +86,7 @@ pub extern "C" fn tolower(c: c_int) -> c_int { #[no_mangle] pub extern "C" fn toupper(c: c_int) -> c_int { if islower(c) != 0 { - c - 0x20 + c & !0x20 } else { c } diff --git a/src/header/strings/mod.rs b/src/header/strings/mod.rs index 562f5d805..78d2a5c44 100644 --- a/src/header/strings/mod.rs +++ b/src/header/strings/mod.rs @@ -2,6 +2,7 @@ use core::ptr; +use header::ctype; use platform::types::*; #[no_mangle] @@ -76,7 +77,7 @@ pub unsafe extern "C" fn strncasecmp( mut n: size_t, ) -> c_int { while n > 0 && (*first != 0 || *second != 0) { - let cmp = (*first & !32) as c_int - (*second & !32) as c_int; + let cmp = ctype::tolower(*first as c_int) - ctype::tolower(*second as c_int); if cmp != 0 { return cmp; } diff --git a/tests/strings.c b/tests/strings.c index ecc098a02..fefb631a6 100644 --- a/tests/strings.c +++ b/tests/strings.c @@ -22,6 +22,9 @@ int main() { assert(strncasecmp("FLOOR0_1", "FLOOR0_1FLOOR4_1", 8) == 0); assert(strncasecmp("FL00RO_1", "FLOOR0_1FLOOR4_1", 8) < 0); + // Ensure we aren't relying on the 5th (lowercase) bit on non-alpha characters + assert(strcasecmp("{[", "[{") > 0); + bzero(new, 1); assert(*new == 0); assert(*(new+1) == 'i'); -- GitLab