Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b128c78a authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "libutils: Fix bug in strstr16."

parents 0f2097c0 bf3fff1a
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -297,9 +297,10 @@ size_t strnlen16(const char16_t *s, size_t maxlen)

char16_t* strstr16(const char16_t* src, const char16_t* target)
{
    const char16_t needle = *target++;
    const size_t target_len = strlen16(target);
    if (needle != '\0') {
    const char16_t needle = *target;
    if (needle == '\0') return (char16_t*)src;

    const size_t target_len = strlen16(++target);
    do {
        do {
            if (*src == '\0') {
@@ -308,12 +309,10 @@ char16_t* strstr16(const char16_t* src, const char16_t* target)
        } while (*src++ != needle);
    } while (strncmp16(src, target, target_len) != 0);
    src--;
    }

    return (char16_t*)src;
}


int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
{
    const char16_t* e1 = s1+n1;
+30 −1
Original line number Diff line number Diff line
@@ -15,7 +15,11 @@
 */

#define LOG_TAG "Unicode_test"
#include <utils/Log.h>

#include <sys/mman.h>
#include <unistd.h>

#include <log/log.h>
#include <utils/Unicode.h>

#include <gtest/gtest.h>
@@ -119,6 +123,31 @@ TEST_F(UnicodeTest, strstr16EmptyTarget) {
            << "should return the original pointer";
}

TEST_F(UnicodeTest, strstr16EmptyTarget_bug) {
    // In the original code when target is an empty string strlen16() would
    // start reading the memory until a "terminating null" (that is, zero)
    // character is found.   This happens because "*target++" in the original
    // code would increment the pointer beyond the actual string.
    void* memptr;
    const size_t alignment = sysconf(_SC_PAGESIZE);
    const size_t size = 2 * alignment;
    ASSERT_EQ(posix_memalign(&memptr, alignment, size), 0);
    // Fill allocated memory.
    memset(memptr, 'A', size);
    // Create a pointer to an "empty" string on the first page.
    char16_t* const emptyString = (char16_t* const)((char*)memptr + alignment - 4);
    *emptyString = (char16_t)0;
    // Protect the second page to show that strstr16() violates that.
    ASSERT_EQ(mprotect((char*)memptr + alignment, alignment, PROT_NONE), 0);
    // Test strstr16(): when bug is present a segmentation fault is raised.
    ASSERT_EQ(strstr16((char16_t*)memptr, emptyString), (char16_t*)memptr)
        << "should not read beyond the first char16_t.";
    // Reset protection of the second page
    ASSERT_EQ(mprotect((char*)memptr + alignment, alignment, PROT_READ | PROT_WRITE), 0);
    // Free allocated memory.
    free(memptr);
}

TEST_F(UnicodeTest, strstr16SameString) {
    const char16_t* result = strstr16(kSearchString, kSearchString);
    EXPECT_EQ(kSearchString, result)