virsysinfo: Calculate OEM string index better

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@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Michal Privoznik 2024-07-18 15:09:22 +02:00
parent 5bb4540dbb
commit bd11c753f3
3 changed files with 18 additions and 11 deletions

View File

@ -895,13 +895,13 @@ virSysinfoParseX86Chassis(const char *base,
static int static int
virSysinfoDMIDecodeOEMString(size_t i, virSysinfoDMIDecodeOEMString(unsigned int idx,
char **str) char **str)
{ {
g_autofree char *err = NULL; g_autofree char *err = NULL;
g_autoptr(virCommand) cmd = virCommandNewArgList(DMIDECODE, "--dump", g_autoptr(virCommand) cmd = virCommandNewArgList(DMIDECODE, "--dump",
"--oem-string", NULL); "--oem-string", NULL);
virCommandAddArgFormat(cmd, "%zu", i); virCommandAddArgFormat(cmd, "%u", idx);
virCommandSetOutputBuffer(cmd, str); virCommandSetOutputBuffer(cmd, str);
virCommandSetErrorBuffer(cmd, &err); virCommandSetErrorBuffer(cmd, &err);
@ -936,7 +936,6 @@ virSysinfoParseOEMStrings(const char *base,
virSysinfoOEMStringsDef **stringsRet) virSysinfoOEMStringsDef **stringsRet)
{ {
virSysinfoOEMStringsDef *strings = NULL; virSysinfoOEMStringsDef *strings = NULL;
size_t i = 1;
int ret = -1; int ret = -1;
const char *cur; const char *cur;
@ -946,6 +945,8 @@ virSysinfoParseOEMStrings(const char *base,
strings = g_new0(virSysinfoOEMStringsDef, 1); strings = g_new0(virSysinfoOEMStringsDef, 1);
while ((cur = strstr(cur, "String "))) { while ((cur = strstr(cur, "String "))) {
char *collon = NULL;
unsigned int idx = 0;
char *eol; char *eol;
cur += 7; cur += 7;
@ -956,8 +957,13 @@ virSysinfoParseOEMStrings(const char *base,
goto cleanup; goto cleanup;
} }
while (g_ascii_isdigit(*cur)) if (virStrToLong_ui(cur, &collon, 10, &idx) < 0) {
cur++; virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Malformed output of dmidecode"));
goto cleanup;
}
cur = collon;
if (*cur != ':') { if (*cur != ':') {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -980,7 +986,7 @@ virSysinfoParseOEMStrings(const char *base,
if (memchr(cur, '.', eol - cur)) { if (memchr(cur, '.', eol - cur)) {
char *str; char *str;
if (virSysinfoDMIDecodeOEMString(i, &str) < 0) if (virSysinfoDMIDecodeOEMString(idx, &str) < 0)
goto cleanup; goto cleanup;
strings->values[strings->nvalues - 1] = g_steal_pointer(&str); strings->values[strings->nvalues - 1] = g_steal_pointer(&str);
@ -988,7 +994,6 @@ virSysinfoParseOEMStrings(const char *base,
strings->values[strings->nvalues - 1] = g_strndup(cur, eol - cur); strings->values[strings->nvalues - 1] = g_strndup(cur, eol - cur);
} }
i++;
cur = eol; cur = eol;
} }

View File

@ -82,9 +82,7 @@
<oemStrings> <oemStrings>
<entry>Default string</entry> <entry>Default string</entry>
<entry>ThunderX2 System</entry> <entry>ThunderX2 System</entry>
<entry>Ha ha ha try parsing\n <entry>Some valid OEM string</entry>
String 3: this correctly
String 4:then</entry>
<entry>Comanche</entry> <entry>Comanche</entry>
</oemStrings> </oemStrings>
</sysinfo> </sysinfo>

View File

@ -63,7 +63,11 @@ testDMIDecodeDryRun(const char *const*args G_GNUC_UNUSED,
return; 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" *output = g_strdup("Ha ha ha try parsing\\n\n"
" String 3: this correctly\n" " String 3: this correctly\n"
" String 4:then\n"); " String 4:then\n");