fake_outputs: Use %n format specifier instead of sprintf

fake_outputs_init used a sprintf invocation with a throw-away buffer
to estimate how many characters the sscanf invocation consumed. This
was unnecessary, and also potentially incorrect, as differences
between the read and formatted strings (such as leading zeros) could
lead to fake_outputs_init to lose its track.

Instead, use the %n format specifier which allows saving the number of
characters consumed by sscanf so far. %n is part of C99.
next
Vladimir Panteleev 2017-09-19 14:33:51 +00:00
parent a3a7d04a43
commit 755b223278
No known key found for this signature in database
GPG Key ID: 5004F0FAD051576D
1 changed files with 3 additions and 4 deletions

View File

@ -33,10 +33,10 @@ static Output *get_screen_at(unsigned int x, unsigned int y) {
*
*/
void fake_outputs_init(const char *output_spec) {
char useless_buffer[1024];
const char *walk = output_spec;
unsigned int x, y, width, height;
while (sscanf(walk, "%ux%u+%u+%u", &width, &height, &x, &y) == 4) {
int chars_consumed;
while (sscanf(walk, "%ux%u+%u+%u%n", &width, &height, &x, &y, &chars_consumed) == 4) {
DLOG("Parsed output as width = %u, height = %u at (%u, %u)\n",
width, height, x, y);
Output *new_output = get_screen_at(x, y);
@ -68,8 +68,7 @@ void fake_outputs_init(const char *output_spec) {
num_screens++;
}
/* Figure out how long the input was to skip it */
walk += sprintf(useless_buffer, "%ux%u+%u+%u", width, height, x, y) + 1;
walk += chars_consumed + 1;
}
if (num_screens == 0) {