From 1ab452fc5776e7c34834388d7fbd806c8dcc198b Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 5 Jul 2023 13:33:11 -0700
Subject: [PATCH] Fixed printf formatting for "%p" and added a unit test to
check it
(cherry picked from commit c63aa9545eb800390176fd2fd86036da81f91100)
---
src/stdlib/SDL_string.c | 17 +++++++++++++++++
test/testautomation_stdlib.c | 6 ++++++
2 files changed, 23 insertions(+)
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index 616e3e125e9c..a5efb3795630 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -1662,6 +1662,20 @@ static size_t SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, do
return length;
}
+static size_t SDL_PrintPointer(char *text, size_t maxlen, SDL_FormatInfo *info, const void *value)
+{
+ char num[130];
+ size_t length;
+
+ if (!value) {
+ return SDL_PrintString(text, maxlen, info, NULL);
+ }
+
+ SDL_ulltoa((unsigned long long)(uintptr_t)value, num, 16);
+ length = SDL_PrintString(text, maxlen, info, "0x");
+ return length + SDL_PrintString(TEXT_AND_LEN_ARGS, info, num);
+}
+
/* NOLINTNEXTLINE(readability-non-const-parameter) */
int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap)
{
@@ -1794,6 +1808,9 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *f
done = SDL_TRUE;
break;
case 'p':
+ info.force_case = SDL_CASE_LOWER;
+ length += SDL_PrintPointer(TEXT_AND_LEN_ARGS, &info, va_arg(ap, void *));
+ break;
case 'x':
info.force_case = SDL_CASE_LOWER;
SDL_FALLTHROUGH;
diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c
index ba7ba88f71c4..43a235d32e01 100644
--- a/test/testautomation_stdlib.c
+++ b/test/testautomation_stdlib.c
@@ -175,6 +175,12 @@ int stdlib_snprintf(void *arg)
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
SDLTest_AssertCheck(result == 7, "Check result value, expected: 7, got: %d", result);
+ result = SDL_snprintf(text, sizeof(text), "%p", (void *)0x1234abcd);
+ expected = "0x1234abcd";
+ SDLTest_AssertPass("Call to SDL_snprintf(text, sizeof(text), \"%%p\", 0x1234abcd)");
+ SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == SDL_strlen(expected), "Check result value, expected: %d, got: %d", (int)SDL_strlen(expected), result);
+
return TEST_COMPLETED;
}