Add escape/unescape functions
This commit is contained in:
parent
817deaaa30
commit
290dd477f3
2
Makefile
2
Makefile
|
@ -13,7 +13,7 @@ endif
|
|||
PG_CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I liburiparser)
|
||||
SHLIB_LINK += $(shell $(PKG_CONFIG) --libs liburiparser)
|
||||
|
||||
REGRESS = init test
|
||||
REGRESS = init test escape
|
||||
REGRESS_OPTS = --inputdir=test
|
||||
|
||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||
|
|
19
README.md
19
README.md
|
@ -126,3 +126,22 @@ Other functions:
|
|||
without normalization. If you want to consider distinct URIs
|
||||
without regard for mostly irrelevant syntax differences, pass them
|
||||
through this function.
|
||||
|
||||
- `uri_escape(text, space_to_plus boolean DEFAULT false, normalize_breaks boolean DEFAULT false) returns text`
|
||||
|
||||
Percent-encodes all reserved characters from the text. This can
|
||||
be useful for constructing URIs from strings.
|
||||
|
||||
If `space_to_plus` is true, then spaces are replaced by plus
|
||||
signs. If `normalize_breaks` is true, then line breaks are
|
||||
converted to CR LF pairs (and subsequently percent-encoded). Note
|
||||
that these two conversions come from the HTML standard for
|
||||
encoding form data but are not part of the specification for URIs.
|
||||
|
||||
- `uri_unescape(text, plus_to_space boolean DEFAULT false, break_conversion boolean DEFAULT false) returns text`
|
||||
|
||||
Decodes all percent-encodings in the text.
|
||||
|
||||
If `plus_to_space` is true, then plus signs are converted to
|
||||
spaces. If `break_conversion` is true, then CR LF pairs are
|
||||
converted to simple newlines (`\n`).
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
SELECT uri_escape('foobar');
|
||||
uri_escape
|
||||
------------
|
||||
foobar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape(':/?#[]@!$&''()*+,;=');
|
||||
uri_escape
|
||||
--------------------------------------------------------
|
||||
%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape('foo bar');
|
||||
uri_escape
|
||||
------------
|
||||
foo%20bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape('foo bar', space_to_plus := false);
|
||||
uri_escape
|
||||
------------
|
||||
foo%20bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape('foo bar', space_to_plus := true);
|
||||
uri_escape
|
||||
------------
|
||||
foo+bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape(E'foo\nbar');
|
||||
uri_escape
|
||||
------------
|
||||
foo%0Abar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape(E'foo\nbar', normalize_breaks := false);
|
||||
uri_escape
|
||||
------------
|
||||
foo%0Abar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_escape(E'foo\nbar', normalize_breaks := true);
|
||||
uri_escape
|
||||
--------------
|
||||
foo%0D%0Abar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foobar');
|
||||
uri_unescape
|
||||
--------------
|
||||
foobar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D');
|
||||
uri_unescape
|
||||
--------------------
|
||||
:/?#[]@!$&'()*+,;=
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foo+bar');
|
||||
uri_unescape
|
||||
--------------
|
||||
foo+bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foo+bar', plus_to_space := false);
|
||||
uri_unescape
|
||||
--------------
|
||||
foo+bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foo+bar', plus_to_space := true);
|
||||
uri_unescape
|
||||
--------------
|
||||
foo bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foo%0D%0Abar');
|
||||
uri_unescape
|
||||
--------------
|
||||
foo +
|
||||
bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foo%0D%0Abar', break_conversion := false);
|
||||
uri_unescape
|
||||
--------------
|
||||
foo +
|
||||
bar
|
||||
(1 row)
|
||||
|
||||
SELECT uri_unescape('foo%0D%0Abar', break_conversion := true);
|
||||
uri_unescape
|
||||
--------------
|
||||
foo\r +
|
||||
bar
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
SELECT uri_escape('foobar');
|
||||
SELECT uri_escape(':/?#[]@!$&''()*+,;=');
|
||||
|
||||
SELECT uri_escape('foo bar');
|
||||
SELECT uri_escape('foo bar', space_to_plus := false);
|
||||
SELECT uri_escape('foo bar', space_to_plus := true);
|
||||
|
||||
SELECT uri_escape(E'foo\nbar');
|
||||
SELECT uri_escape(E'foo\nbar', normalize_breaks := false);
|
||||
SELECT uri_escape(E'foo\nbar', normalize_breaks := true);
|
||||
|
||||
SELECT uri_unescape('foobar');
|
||||
SELECT uri_unescape('%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D');
|
||||
|
||||
SELECT uri_unescape('foo+bar');
|
||||
SELECT uri_unescape('foo+bar', plus_to_space := false);
|
||||
SELECT uri_unescape('foo+bar', plus_to_space := true);
|
||||
|
||||
SELECT uri_unescape('foo%0D%0Abar');
|
||||
SELECT uri_unescape('foo%0D%0Abar', break_conversion := false);
|
||||
SELECT uri_unescape('foo%0D%0Abar', break_conversion := true);
|
|
@ -8,3 +8,15 @@ CREATE OPERATOR CLASS uri_ops_hash
|
|||
DEFAULT FOR TYPE uri USING hash AS
|
||||
OPERATOR 1 =,
|
||||
FUNCTION 1 uri_hash(uri);
|
||||
|
||||
CREATE FUNCTION uri_escape(text, space_to_plus boolean DEFAULT false, normalize_breaks boolean DEFAULT false) RETURNS text
|
||||
IMMUTABLE
|
||||
STRICT
|
||||
LANGUAGE C
|
||||
AS '$libdir/uri';
|
||||
|
||||
CREATE FUNCTION uri_unescape(text, plus_to_space boolean DEFAULT false, break_conversion boolean DEFAULT false) RETURNS text
|
||||
IMMUTABLE
|
||||
STRICT
|
||||
LANGUAGE C
|
||||
AS '$libdir/uri';
|
||||
|
|
12
uri--1.sql
12
uri--1.sql
|
@ -211,3 +211,15 @@ CREATE OPERATOR CLASS uri_ops_hash
|
|||
DEFAULT FOR TYPE uri USING hash AS
|
||||
OPERATOR 1 =,
|
||||
FUNCTION 1 uri_hash(uri);
|
||||
|
||||
CREATE FUNCTION uri_escape(text, space_to_plus boolean DEFAULT false, normalize_breaks boolean DEFAULT false) RETURNS text
|
||||
IMMUTABLE
|
||||
STRICT
|
||||
LANGUAGE C
|
||||
AS '$libdir/uri';
|
||||
|
||||
CREATE FUNCTION uri_unescape(text, plus_to_space boolean DEFAULT false, break_conversion boolean DEFAULT false) RETURNS text
|
||||
IMMUTABLE
|
||||
STRICT
|
||||
LANGUAGE C
|
||||
AS '$libdir/uri';
|
||||
|
|
36
uri.c
36
uri.c
|
@ -455,3 +455,39 @@ uri_hash(PG_FUNCTION_ARGS)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(uri_escape);
|
||||
Datum
|
||||
uri_escape(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *arg = PG_GETARG_TEXT_PP(0);
|
||||
bool space_to_plus = PG_GETARG_BOOL(1);
|
||||
bool normalize_breaks = PG_GETARG_BOOL(2);
|
||||
|
||||
size_t chars_required;
|
||||
char *ret;
|
||||
|
||||
chars_required = (VARSIZE(arg) - 4) * (normalize_breaks ? 6 : 3) + 1;
|
||||
ret = palloc(chars_required);
|
||||
uriEscapeExA(VARDATA(arg),
|
||||
VARDATA(arg) + VARSIZE(arg) - 4,
|
||||
ret,
|
||||
space_to_plus, normalize_breaks);
|
||||
|
||||
PG_RETURN_TEXT_P(cstring_to_text(ret));
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(uri_unescape);
|
||||
Datum
|
||||
uri_unescape(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *arg = PG_GETARG_TEXT_PP(0);
|
||||
bool plus_to_space = PG_GETARG_BOOL(1);
|
||||
bool break_conversion = PG_GETARG_BOOL(2);
|
||||
|
||||
char *s = text_to_cstring(arg);
|
||||
|
||||
uriUnescapeInPlaceExA(s, plus_to_space, break_conversion);
|
||||
|
||||
PG_RETURN_TEXT_P(cstring_to_text(s));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue