mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:07:45 +00:00
LibC: Make scanf always copy its va_list
On x86_64 GCC implements va_list as an array. This makes the syntax for taking a pointer to it break & crash. The workaround / solution is to create a copy. Since va_list is a tiny struct referencing the actual varargs, this is little overhead (especially compared to va_args itself)
This commit is contained in:
parent
3cca9e6704
commit
85c2ad94d5
1 changed files with 5 additions and 1 deletions
|
@ -383,6 +383,9 @@ extern "C" int vsscanf(const char* input, const char* format, va_list ap)
|
||||||
|
|
||||||
int elements_matched = 0;
|
int elements_matched = 0;
|
||||||
|
|
||||||
|
va_list copy;
|
||||||
|
__builtin_va_copy(copy, ap);
|
||||||
|
|
||||||
while (!format_lexer.is_eof()) {
|
while (!format_lexer.is_eof()) {
|
||||||
format_lexer.ignore_while(isspace);
|
format_lexer.ignore_while(isspace);
|
||||||
if (!format_lexer.next_is('%')) {
|
if (!format_lexer.next_is('%')) {
|
||||||
|
@ -537,7 +540,7 @@ extern "C" int vsscanf(const char* input, const char* format, va_list ap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* ap_or_null = !suppress_assignment ? (va_list*)&ap : nullptr;
|
auto* ap_or_null = !suppress_assignment ? (va_list*)© : nullptr;
|
||||||
|
|
||||||
// Now try to read.
|
// Now try to read.
|
||||||
switch (conversion_specifier) {
|
switch (conversion_specifier) {
|
||||||
|
@ -616,6 +619,7 @@ extern "C" int vsscanf(const char* input, const char* format, va_list ap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
va_end(copy);
|
||||||
|
|
||||||
return elements_matched;
|
return elements_matched;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue