From eb0a7735ba1ede6a35b80d73f6c371a8b1220552 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Wed, 12 Sep 2007 20:49:27 +0000 Subject: Perform post-escaping encoding validity checks on SQL literals and COPY input so that invalidly encoded data cannot enter the database by these means. --- src/backend/commands/copy.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/backend/commands/copy.c') diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index d28a6ad11c2..fdfe5ea965f 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.286 2007/09/07 20:59:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.287 2007/09/12 20:49:27 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -2685,6 +2685,7 @@ CopyReadAttributesText(CopyState cstate, int maxfields, char **fieldvals) char *start_ptr; char *end_ptr; int input_len; + bool saw_high_bit = false; /* Make sure space remains in fieldvals[] */ if (fieldno >= maxfields) @@ -2749,6 +2750,8 @@ CopyReadAttributesText(CopyState cstate, int maxfields, char **fieldvals) } } c = val & 0377; + if (IS_HIGHBIT_SET(c)) + saw_high_bit = true; } break; case 'x': @@ -2772,6 +2775,8 @@ CopyReadAttributesText(CopyState cstate, int maxfields, char **fieldvals) } } c = val & 0xff; + if (IS_HIGHBIT_SET(c)) + saw_high_bit = true; } } break; @@ -2799,7 +2804,7 @@ CopyReadAttributesText(CopyState cstate, int maxfields, char **fieldvals) * literally */ } - } + } /* Add c to output string */ *output_ptr++ = c; @@ -2808,6 +2813,16 @@ CopyReadAttributesText(CopyState cstate, int maxfields, char **fieldvals) /* Terminate attribute value in output area */ *output_ptr++ = '\0'; + /* If we de-escaped a char with the high bit set, make sure + * we still have valid data for the db encoding. Avoid calling strlen + * here for the sake of efficiency. + */ + if (saw_high_bit) + { + char *fld = fieldvals[fieldno]; + pg_verifymbstr(fld, output_ptr - (fld + 1), false); + } + /* Check whether raw input matched null marker */ input_len = end_ptr - start_ptr; if (input_len == cstate->null_print_len && -- cgit v1.2.3