diff --git a/CMakeLists.txt b/CMakeLists.txt index 072c9873..68527d05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -805,6 +805,13 @@ IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_MOCK_TESTS) TARGET_LINK_LIBRARIES(zenfone-2e-test PRIVATE cpuinfo_mock gtest) ADD_TEST(NAME zenfone-2e-test COMMAND zenfone-2e-test) ENDIF() + + IF(CPUINFO_TARGET_PROCESSOR MATCHES "^(armv[5-8].*|aarch64|arm64.*)$") + ADD_EXECUTABLE(repro-cpuinfo-test test/mock/repro_cpuinfo.c) + TARGET_INCLUDE_DIRECTORIES(repro-cpuinfo-test BEFORE PRIVATE src) + TARGET_LINK_LIBRARIES(repro-cpuinfo-test PRIVATE cpuinfo_mock) + ADD_TEST(NAME repro-cpuinfo-test COMMAND repro-cpuinfo-test) + ENDIF() ENDIF() # ---[ cpuinfo unit tests diff --git a/src/arm/linux/cpuinfo.c b/src/arm/linux/cpuinfo.c index 081d9aab..6ba5bdfc 100644 --- a/src/arm/linux/cpuinfo.c +++ b/src/arm/linux/cpuinfo.c @@ -872,31 +872,29 @@ static bool parse_line( /* BogoMIPS is useless, don't parse */ } else if (memcmp(line_start, "Hardware", key_length) == 0) { size_t value_length = value_end - value_start; - if (value_length > CPUINFO_HARDWARE_VALUE_MAX) { + if (value_length >= CPUINFO_HARDWARE_VALUE_MAX) { cpuinfo_log_warning( "length of Hardware value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit", (int)value_length, value_start, - CPUINFO_HARDWARE_VALUE_MAX); - value_length = CPUINFO_HARDWARE_VALUE_MAX; - } else { - state->hardware[value_length] = '\0'; + CPUINFO_HARDWARE_VALUE_MAX - 1); + value_length = CPUINFO_HARDWARE_VALUE_MAX - 1; } + state->hardware[value_length] = '\0'; memcpy(state->hardware, value_start, value_length); cpuinfo_log_debug( "parsed /proc/cpuinfo Hardware = \"%.*s\"", (int)value_length, value_start); } else if (memcmp(line_start, "Revision", key_length) == 0) { size_t value_length = value_end - value_start; - if (value_length > CPUINFO_REVISION_VALUE_MAX) { + if (value_length >= CPUINFO_REVISION_VALUE_MAX) { cpuinfo_log_warning( "length of Revision value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit", (int)value_length, value_start, - CPUINFO_REVISION_VALUE_MAX); - value_length = CPUINFO_REVISION_VALUE_MAX; - } else { - state->revision[value_length] = '\0'; + CPUINFO_REVISION_VALUE_MAX - 1); + value_length = CPUINFO_REVISION_VALUE_MAX - 1; } + state->revision[value_length] = '\0'; memcpy(state->revision, value_start, value_length); cpuinfo_log_debug( "parsed /proc/cpuinfo Revision = \"%.*s\"", (int)value_length, value_start); diff --git a/test/mock/repro_cpuinfo.c b/test/mock/repro_cpuinfo.c new file mode 100644 index 00000000..22d71c37 --- /dev/null +++ b/test/mock/repro_cpuinfo.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +static struct cpuinfo_mock_file mock_files[] = { + { + .path = "/proc/cpuinfo", + .size = 0, // Will be initialized in main + .content = + "Hardware\t: " + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", + }, + {.path = NULL}}; + +int main() { + mock_files[0].size = strlen(mock_files[0].content); + cpuinfo_mock_filesystem(mock_files); + + char hardware[64]; + char revision[9]; + struct cpuinfo_arm_linux_processor processors[1]; + + printf("Calling cpuinfo_arm_linux_parse_proc_cpuinfo...\n"); + cpuinfo_arm_linux_parse_proc_cpuinfo(hardware, revision, 1, processors); + + printf("Hardware parsed: %s\n", hardware); + + char expected[64]; + memset(expected, 'A', 63); + expected[63] = '\0'; + + if (strcmp(hardware, expected) != 0) { + fprintf(stderr, "FAIL: expected length 63, got %s (length %zu)\n", hardware, strlen(hardware)); + return 1; + } + printf("PASS\n"); + return 0; +}