Skip to content

Commit 5be213c

Browse files
committed
Refactor test_escape.c for additional ways of testing.
Start the file with static functions not specific to pe_test_vectors tests. This way, new tests can use them without disrupting the file's layout. Change report_result() PQExpBuffer arguments to plain strings. Back-patch to v13 (all supported versions), for the next commit. Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Backpatch-through: 13 Security: CVE-2025-4207
1 parent 18c4fff commit 5be213c

File tree

1 file changed

+82
-80
lines changed

1 file changed

+82
-80
lines changed

src/test/modules/test_escape/test_escape.c

Lines changed: 82 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ typedef struct pe_test_config
3131
int failure_count;
3232
} pe_test_config;
3333

34+
#define NEVER_ACCESS_STR "\xff never-to-be-touched"
35+
3436

3537
/*
3638
* An escape function to be tested by this test.
@@ -86,6 +88,82 @@ static const PsqlScanCallbacks test_scan_callbacks = {
8688
};
8789

8890

91+
/*
92+
* Print the string into buf, making characters outside of plain ascii
93+
* somewhat easier to recognize.
94+
*
95+
* The output format could stand to be improved significantly, it's not at all
96+
* unambiguous.
97+
*/
98+
static void
99+
escapify(PQExpBuffer buf, const char *str, size_t len)
100+
{
101+
for (size_t i = 0; i < len; i++)
102+
{
103+
char c = *str;
104+
105+
if (c == '\n')
106+
appendPQExpBufferStr(buf, "\\n");
107+
else if (c == '\0')
108+
appendPQExpBufferStr(buf, "\\0");
109+
else if (c < ' ' || c > '~')
110+
appendPQExpBuffer(buf, "\\x%2x", (uint8_t) c);
111+
else
112+
appendPQExpBufferChar(buf, c);
113+
str++;
114+
}
115+
}
116+
117+
static void
118+
report_result(pe_test_config *tc,
119+
bool success,
120+
const char *testname,
121+
const char *details,
122+
const char *subname,
123+
const char *resultdesc)
124+
{
125+
int test_id = ++tc->test_count;
126+
bool print_details = true;
127+
bool print_result = true;
128+
129+
if (success)
130+
{
131+
if (tc->verbosity <= 0)
132+
print_details = false;
133+
if (tc->verbosity < 0)
134+
print_result = false;
135+
}
136+
else
137+
tc->failure_count++;
138+
139+
if (print_details)
140+
printf("%s", details);
141+
142+
if (print_result)
143+
printf("%s %d - %s: %s: %s\n",
144+
success ? "ok" : "not ok",
145+
test_id, testname,
146+
subname,
147+
resultdesc);
148+
}
149+
150+
/*
151+
* Return true for encodings in which bytes in a multi-byte character look
152+
* like valid ascii characters.
153+
*/
154+
static bool
155+
encoding_conflicts_ascii(int encoding)
156+
{
157+
/*
158+
* We don't store this property directly anywhere, but whether an encoding
159+
* is a client-only encoding is a good proxy.
160+
*/
161+
if (encoding > PG_ENCODING_BE_LAST)
162+
return true;
163+
return false;
164+
}
165+
166+
89167
static bool
90168
escape_literal(PGconn *conn, PQExpBuffer target,
91169
const char *unescaped, size_t unescaped_len,
@@ -380,81 +458,6 @@ static pe_test_vector pe_test_vectors[] =
380458
};
381459

382460

383-
/*
384-
* Print the string into buf, making characters outside of plain ascii
385-
* somewhat easier to recognize.
386-
*
387-
* The output format could stand to be improved significantly, it's not at all
388-
* unambiguous.
389-
*/
390-
static void
391-
escapify(PQExpBuffer buf, const char *str, size_t len)
392-
{
393-
for (size_t i = 0; i < len; i++)
394-
{
395-
char c = *str;
396-
397-
if (c == '\n')
398-
appendPQExpBufferStr(buf, "\\n");
399-
else if (c == '\0')
400-
appendPQExpBufferStr(buf, "\\0");
401-
else if (c < ' ' || c > '~')
402-
appendPQExpBuffer(buf, "\\x%2x", (uint8_t) c);
403-
else
404-
appendPQExpBufferChar(buf, c);
405-
str++;
406-
}
407-
}
408-
409-
static void
410-
report_result(pe_test_config *tc,
411-
bool success,
412-
PQExpBuffer testname,
413-
PQExpBuffer details,
414-
const char *subname,
415-
const char *resultdesc)
416-
{
417-
int test_id = ++tc->test_count;
418-
bool print_details = true;
419-
bool print_result = true;
420-
421-
if (success)
422-
{
423-
if (tc->verbosity <= 0)
424-
print_details = false;
425-
if (tc->verbosity < 0)
426-
print_result = false;
427-
}
428-
else
429-
tc->failure_count++;
430-
431-
if (print_details)
432-
printf("%s", details->data);
433-
434-
if (print_result)
435-
printf("%s %d - %s: %s: %s\n",
436-
success ? "ok" : "not ok",
437-
test_id, testname->data,
438-
subname,
439-
resultdesc);
440-
}
441-
442-
/*
443-
* Return true for encodings in which bytes in a multi-byte character look
444-
* like valid ascii characters.
445-
*/
446-
static bool
447-
encoding_conflicts_ascii(int encoding)
448-
{
449-
/*
450-
* We don't store this property directly anywhere, but whether an encoding
451-
* is a client-only encoding is a good proxy.
452-
*/
453-
if (encoding > PG_ENCODING_BE_LAST)
454-
return true;
455-
return false;
456-
}
457-
458461
static const char *
459462
scan_res_s(PsqlScanResult res)
460463
{
@@ -529,7 +532,7 @@ test_psql_parse(pe_test_config *tc, PQExpBuffer testname,
529532
else
530533
resdesc = "ok";
531534

532-
report_result(tc, !test_fails, testname, details,
535+
report_result(tc, !test_fails, testname->data, details->data,
533536
"psql parse",
534537
resdesc);
535538
}
@@ -614,7 +617,6 @@ test_one_vector_escape(pe_test_config *tc, const pe_test_vector *tv, const pe_te
614617
*/
615618
appendBinaryPQExpBuffer(raw_buf, tv->escape, tv->escape_len);
616619

617-
#define NEVER_ACCESS_STR "\xff never-to-be-touched"
618620
if (ef->supports_input_length)
619621
{
620622
/*
@@ -668,7 +670,7 @@ test_one_vector_escape(pe_test_config *tc, const pe_test_vector *tv, const pe_te
668670
* here, but that's not available everywhere.
669671
*/
670672
contains_never = strstr(escape_buf->data, NEVER_ACCESS_STR) == NULL;
671-
report_result(tc, contains_never, testname, details,
673+
report_result(tc, contains_never, testname->data, details->data,
672674
"escaped data beyond end of input",
673675
contains_never ? "no" : "all secrets revealed");
674676
}
@@ -711,7 +713,7 @@ test_one_vector_escape(pe_test_config *tc, const pe_test_vector *tv, const pe_te
711713
resdesc = "valid input failed to escape, due to zero byte";
712714
}
713715

714-
report_result(tc, ok, testname, details,
716+
report_result(tc, ok, testname->data, details->data,
715717
"input validity vs escape success",
716718
resdesc);
717719
}
@@ -741,7 +743,7 @@ test_one_vector_escape(pe_test_config *tc, const pe_test_vector *tv, const pe_te
741743
resdesc = "invalid input produced valid output";
742744
}
743745

744-
report_result(tc, ok, testname, details,
746+
report_result(tc, ok, testname->data, details->data,
745747
"input and escaped encoding validity",
746748
resdesc);
747749
}

0 commit comments

Comments
 (0)