From e03e1eac0b7682884b6628df1305d34299680cb4 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Wed, 30 Jul 2014 16:06:56 -0700 Subject: [PATCH] Fix memchr with a zero length. The memchr implementation for 64 bit fails if these conditions occur: - The buffer is 32 byte aligned. - The buffer contains the character in the first byte. - The count sent in is zero. The function should return NULL, but it's not. Bug: 16676625 Change-Id: Iab33cc7a8b79920350c72f054dff0e0a3cde69ce --- libc/arch-arm64/generic/bionic/memchr.S | 5 +++++ tests/string_test.cpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/libc/arch-arm64/generic/bionic/memchr.S b/libc/arch-arm64/generic/bionic/memchr.S index fbb00caaa..e5ea57d8c 100644 --- a/libc/arch-arm64/generic/bionic/memchr.S +++ b/libc/arch-arm64/generic/bionic/memchr.S @@ -75,6 +75,7 @@ ENTRY(memchr) * Magic constant 0x40100401 allows us to identify which lane matches * the requested byte. */ + cbz cntin, .Lzero_length mov wtmp2, #0x0401 movk wtmp2, #0x4010, lsl #16 dup vrepchr.16b, chrin @@ -157,4 +158,8 @@ ENTRY(memchr) /* Select result or NULL */ csel result, xzr, result, eq ret + +.Lzero_length: + mov result, xzr + ret END(memchr) diff --git a/tests/string_test.cpp b/tests/string_test.cpp index bc2c05b40..73c94c602 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -763,6 +763,14 @@ TEST(string, memchr) { } } +TEST(string, memchr_zero) { + uint8_t* buffer; + ASSERT_EQ(0, posix_memalign(reinterpret_cast(&buffer), 64, 64)); + memset(buffer, 10, 64); + ASSERT_TRUE(NULL == memchr(buffer, 5, 0)); + ASSERT_TRUE(NULL == memchr(buffer, 10, 0)); +} + TEST(string, memrchr) { int seek_char = random() & 255; StringTestState state(SMALL);