Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ngx_string.c')
-rw-r--r--src/core/ngx_string.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index a236654d7..fc3738234 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -928,3 +928,111 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
return (uintptr_t) dst;
}
+
+
+void
+ngx_unescape_uri(u_char **dst, u_char **src, size_t size)
+{
+ u_char *d, *s, ch, c, decoded;
+ enum {
+ sw_usual = 0,
+ sw_quoted,
+ sw_quoted_second
+ } state;
+
+ d = *dst;
+ s = *src;
+
+ state = 0;
+ decoded = 0;
+
+ while (size--) {
+
+ ch = *s++;
+
+ switch (state) {
+ case sw_usual:
+ if (ch == '?') {
+ *d++ = ch;
+ goto done;
+ }
+
+ if (ch == '%') {
+ state = sw_quoted;
+ break;
+ }
+
+ *d++ = ch;
+ break;
+
+ case sw_quoted:
+
+ if (ch >= '0' && ch <= '9') {
+ decoded = (u_char) (ch - '0');
+ state = sw_quoted_second;
+ break;
+ }
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'f') {
+ decoded = (u_char) (c - 'a' + 10);
+ state = sw_quoted_second;
+ break;
+ }
+
+ /* skip the invalid quoted character */
+
+ s++;
+ size--;
+
+ break;
+
+ case sw_quoted_second:
+
+ if (ch >= '0' && ch <= '9') {
+ ch = (u_char) ((decoded << 4) + ch - '0');
+
+ state = sw_usual;
+
+ if (ch > '%' && ch < 0x7f) {
+ *d++ = ch;
+ break;
+ }
+
+ *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
+
+ break;
+ }
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'f') {
+ ch = (u_char) ((decoded << 4) + c - 'a' + 10);
+
+ if (ch == '?') {
+ *d++ = ch;
+ goto done;
+ }
+
+ state = sw_usual;
+
+ if (ch > '%' && ch < 0x7f) {
+ *d++ = ch;
+ break;
+ }
+
+ *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
+
+ break;
+ }
+
+ /* skip the invalid quoted character */
+
+ break;
+ }
+ }
+
+done:
+
+ *dst = d;
+ *src = s;
+}