From 1caae3e9e448e9ec728faa9b13e058f5d63189e0 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 10 Mar 2025 14:25:11 -0700
Subject: [PATCH] Fixed sscanf("026", "%1x%1x%1x", &r, &g, &b)
Fixes https://github.com/libsdl-org/SDL/issues/12510
(cherry picked from commit be6ed6e9c4c74f1973597214517ac3f8f89feb85)
---
src/stdlib/SDL_string.c | 12 +++++-------
test/testautomation_stdlib.c | 12 ++++++++++++
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index 2ce22186e3c56..38b5201c624a0 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -81,14 +81,12 @@ static size_t SDL_ScanUnsignedLongLongInternal(const char *text, int count, int
negative = *text == '-';
++text;
}
- if ((radix == 0 || radix == 16) && *text == '0' && text[1] != '\0') {
+ if ((radix == 0 || radix == 16) && *text == '0' && (text[1] == 'x' || text[1] == 'X')) {
+ text += 2;
+ radix = 16;
+ } else if (radix == 0 && *text == '0' && (text[1] >= '0' && text[1] <= '9')) {
++text;
- if (*text == 'x' || *text == 'X') {
- radix = 16;
- ++text;
- } else if (radix == 0) {
- radix = 8;
- }
+ radix = 8;
} else if (radix == 0) {
radix = 10;
}
diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c
index e62069da4b1ae..b83d9a1ea37a0 100644
--- a/test/testautomation_stdlib.c
+++ b/test/testautomation_stdlib.c
@@ -412,6 +412,7 @@ int stdlib_sscanf(void *arg)
long long long_long_output, expected_long_long_output, long_long_length;
size_t size_output, expected_size_output;
char text[128], text2[128];
+ unsigned int r = 0, g = 0, b = 0;
expected_output = output = 123;
expected_result = -1;
@@ -447,6 +448,17 @@ int stdlib_sscanf(void *arg)
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
SDLTest_AssertCheck(length == 1, "Check length, expected: 1, got: %i", length);
+ expected_result = 3;
+ result = SDL_sscanf("#026", "#%1x%1x%1x", &r, &g, &b);
+ SDLTest_AssertPass("Call to SDL_sscanf(\"#026\", \"#%%1x%%1x%%1x\", &r, &g, &b)");
+ expected_output = 0;
+ SDLTest_AssertCheck(r == expected_output, "Check output for r, expected: %i, got: %i", expected_output, r);
+ expected_output = 2;
+ SDLTest_AssertCheck(g == expected_output, "Check output for g, expected: %i, got: %i", expected_output, g);
+ expected_output = 6;
+ SDLTest_AssertCheck(b == expected_output, "Check output for b, expected: %i, got: %i", expected_output, b);
+ SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
#define SIZED_TEST_CASE(type, var, printf_specifier, scanf_specifier) \
var##_output = 123; \
var##_length = 0; \