mirror of https://github.com/postgres/postgres
When in SQL_ASCII encoding, strings passed around are not necessarily
UTF8-safe. We had already fixed this in some places, but it looks like
we missed some.
I had to backpatch Peter Eisentraut's a8b92b60
to 9.1 in order for this
patch to cherry-pick more cleanly.
Patch from Alex Hunsaker, tweaked by Kyotaro HORIGUCHI and myself.
Some desultory cleanup and comment addition by me, during patch review.
Per bug report from Christoph Berg in
20120209102116.GA14429@msgid.df7cb.de
pull/3/head
parent
fc4a8a6d74
commit
379607c9e8
@ -0,0 +1,33 @@ |
||||
-- |
||||
-- Make sure strings are validated |
||||
-- Should fail for all encodings, as nul bytes are never permitted. |
||||
-- |
||||
CREATE OR REPLACE FUNCTION perl_zerob() RETURNS TEXT AS $$ |
||||
return "abcd\0efg"; |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_zerob(); |
||||
ERROR: invalid byte sequence for encoding "UTF8": 0x00 |
||||
CONTEXT: PL/Perl function "perl_zerob" |
||||
CREATE OR REPLACE FUNCTION perl_0x80_in(text) RETURNS BOOL AS $$ |
||||
return ($_[0] eq "abc\x80de" ? "true" : "false"); |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_0x80_in(E'abc\x80de'); |
||||
ERROR: invalid byte sequence for encoding "UTF8": 0x80 |
||||
CREATE OR REPLACE FUNCTION perl_0x80_out() RETURNS TEXT AS $$ |
||||
return "abc\x80de"; |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_0x80_out() = E'abc\x80de'; |
||||
ERROR: invalid byte sequence for encoding "UTF8": 0x80 |
||||
CREATE OR REPLACE FUNCTION perl_utf_inout(text) RETURNS TEXT AS $$ |
||||
$str = $_[0]; $code = "NotUTF8:"; $match = "ab\xe5\xb1\xb1cd"; |
||||
if (utf8::is_utf8($str)) { |
||||
$code = "UTF8:"; utf8::decode($str); $match="ab\x{5c71}cd"; |
||||
} |
||||
return ($str ne $match ? $code."DIFFER" : $code."ab\x{5ddd}cd"); |
||||
$$ LANGUAGE plperl; |
||||
SELECT encode(perl_utf_inout(E'ab\xe5\xb1\xb1cd')::bytea, 'escape') |
||||
encode |
||||
----------------------- |
||||
UTF8:ab\345\267\235cd |
||||
(1 row) |
||||
|
@ -0,0 +1,41 @@ |
||||
-- |
||||
-- Make sure strings are validated |
||||
-- Should fail for all encodings, as nul bytes are never permitted. |
||||
-- |
||||
CREATE OR REPLACE FUNCTION perl_zerob() RETURNS TEXT AS $$ |
||||
return "abcd\0efg"; |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_zerob(); |
||||
ERROR: invalid byte sequence for encoding "SQL_ASCII": 0x00 |
||||
CONTEXT: PL/Perl function "perl_zerob" |
||||
CREATE OR REPLACE FUNCTION perl_0x80_in(text) RETURNS BOOL AS $$ |
||||
return ($_[0] eq "abc\x80de" ? "true" : "false"); |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_0x80_in(E'abc\x80de'); |
||||
perl_0x80_in |
||||
-------------- |
||||
t |
||||
(1 row) |
||||
|
||||
CREATE OR REPLACE FUNCTION perl_0x80_out() RETURNS TEXT AS $$ |
||||
return "abc\x80de"; |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_0x80_out() = E'abc\x80de'; |
||||
?column? |
||||
---------- |
||||
t |
||||
(1 row) |
||||
|
||||
CREATE OR REPLACE FUNCTION perl_utf_inout(text) RETURNS TEXT AS $$ |
||||
$str = $_[0]; $code = "NotUTF8:"; $match = "ab\xe5\xb1\xb1cd"; |
||||
if (utf8::is_utf8($str)) { |
||||
$code = "UTF8:"; utf8::decode($str); $match="ab\x{5c71}cd"; |
||||
} |
||||
return ($str ne $match ? $code."DIFFER" : $code."ab\x{5ddd}cd"); |
||||
$$ LANGUAGE plperl; |
||||
SELECT encode(perl_utf_inout(E'ab\xe5\xb1\xb1cd')::bytea, 'escape') |
||||
encode |
||||
-------------------------- |
||||
NotUTF8:ab\345\267\235cd |
||||
(1 row) |
||||
|
@ -0,0 +1,24 @@ |
||||
-- |
||||
-- Make sure strings are validated |
||||
-- Should fail for all encodings, as nul bytes are never permitted. |
||||
-- |
||||
CREATE OR REPLACE FUNCTION perl_zerob() RETURNS TEXT AS $$ |
||||
return "abcd\0efg"; |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_zerob(); |
||||
CREATE OR REPLACE FUNCTION perl_0x80_in(text) RETURNS BOOL AS $$ |
||||
return ($_[0] eq "abc\x80de" ? "true" : "false"); |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_0x80_in(E'abc\x80de'); |
||||
CREATE OR REPLACE FUNCTION perl_0x80_out() RETURNS TEXT AS $$ |
||||
return "abc\x80de"; |
||||
$$ LANGUAGE plperl; |
||||
SELECT perl_0x80_out() = E'abc\x80de'; |
||||
CREATE OR REPLACE FUNCTION perl_utf_inout(text) RETURNS TEXT AS $$ |
||||
$str = $_[0]; $code = "NotUTF8:"; $match = "ab\xe5\xb1\xb1cd"; |
||||
if (utf8::is_utf8($str)) { |
||||
$code = "UTF8:"; utf8::decode($str); $match="ab\x{5c71}cd"; |
||||
} |
||||
return ($str ne $match ? $code."DIFFER" : $code."ab\x{5ddd}cd"); |
||||
$$ LANGUAGE plperl; |
||||
SELECT encode(perl_utf_inout(E'ab\xe5\xb1\xb1cd')::bytea, 'escape') |
Loading…
Reference in new issue