As can be seen in earlier commits, there can be two OEM strings with the same index. But since our parser (virSysinfoParseOEMStrings()) doesn't expect that, it increments index in each run and thus skips over these strings. Fortunately, we have the right index at hand - we're just skipping over it in a loop. Just reconstruct the index back inside the loop. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/util/virsysinfo.c | 19 ++++++++++++------- .../aarch64-hpe-apollosysinfo.expect | 4 +--- tests/sysinfotest.c | 6 +++++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c index 1fd8261dc1..8823af0469 100644 --- a/src/util/virsysinfo.c +++ b/src/util/virsysinfo.c @@ -895,13 +895,13 @@ virSysinfoParseX86Chassis(const char *base, static int -virSysinfoDMIDecodeOEMString(size_t i, +virSysinfoDMIDecodeOEMString(unsigned int idx, char **str) { g_autofree char *err = NULL; g_autoptr(virCommand) cmd = virCommandNewArgList(DMIDECODE, "--dump", "--oem-string", NULL); - virCommandAddArgFormat(cmd, "%zu", i); + virCommandAddArgFormat(cmd, "%u", idx); virCommandSetOutputBuffer(cmd, str); virCommandSetErrorBuffer(cmd, &err); @@ -937,7 +937,6 @@ virSysinfoParseOEMStrings(const char *base, virSysinfoOEMStringsDef **stringsRet) { virSysinfoOEMStringsDef *strings = NULL; - size_t i = 1; int ret = -1; const char *cur; @@ -947,6 +946,8 @@ virSysinfoParseOEMStrings(const char *base, strings = g_new0(virSysinfoOEMStringsDef, 1); while ((cur = strstr(cur, "String "))) { + char *collon = NULL; + unsigned int idx = 0; char *eol; cur += 7; @@ -957,8 +958,13 @@ virSysinfoParseOEMStrings(const char *base, goto cleanup; } - while (g_ascii_isdigit(*cur)) - cur++; + if (virStrToLong_ui(cur, &collon, 10, &idx) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Malformed output of dmidecode")); + goto cleanup; + } + + cur = collon; if (*cur != ':') { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -981,7 +987,7 @@ virSysinfoParseOEMStrings(const char *base, if (memchr(cur, '.', eol - cur)) { char *str; - if (virSysinfoDMIDecodeOEMString(i, &str) < 0) + if (virSysinfoDMIDecodeOEMString(idx, &str) < 0) goto cleanup; strings->values[strings->nvalues - 1] = g_steal_pointer(&str); @@ -989,7 +995,6 @@ virSysinfoParseOEMStrings(const char *base, strings->values[strings->nvalues - 1] = g_strndup(cur, eol - cur); } - i++; cur = eol; } diff --git a/tests/sysinfodata/aarch64-hpe-apollosysinfo.expect b/tests/sysinfodata/aarch64-hpe-apollosysinfo.expect index 331454834d..2b886f74fd 100644 --- a/tests/sysinfodata/aarch64-hpe-apollosysinfo.expect +++ b/tests/sysinfodata/aarch64-hpe-apollosysinfo.expect @@ -82,9 +82,7 @@ <oemStrings> <entry>Default string</entry> <entry>ThunderX2 System</entry> - <entry>Ha ha ha try parsing\n - String 3: this correctly - String 4:then</entry> + <entry>Some valid OEM string</entry> <entry>Comanche</entry> </oemStrings> </sysinfo> diff --git a/tests/sysinfotest.c b/tests/sysinfotest.c index d8bd1f38ba..b666847379 100644 --- a/tests/sysinfotest.c +++ b/tests/sysinfotest.c @@ -63,7 +63,11 @@ testDMIDecodeDryRun(const char *const*args G_GNUC_UNUSED, return; } - if (STREQ(args[3], "3")) { + if (STREQ(args[3], "2")) { + *output = g_strdup("Some valid OEM string\n"); + *error = g_strdup_printf("No OEM string number %s", args[3]); + return; + } else if (STREQ(args[3], "3")) { *output = g_strdup("Ha ha ha try parsing\\n\n" " String 3: this correctly\n" " String 4:then\n"); -- 2.44.2