Line data Source code
1 : /*
2 : * Copyright (C) Xiaozhe Wang (chaoslawful)
3 : * Copyright (C) Yichun Zhang (agentzh)
4 : */
5 :
6 :
7 : #ifndef DDEBUG
8 : #define DDEBUG 0
9 : #endif
10 : #include "ddebug.h"
11 :
12 :
13 : #include "ngx_http_lua_string.h"
14 : #include "ngx_http_lua_util.h"
15 : #include "ngx_http_lua_args.h"
16 : #include "ngx_crc32.h"
17 :
18 : #if (NGX_HAVE_SHA1)
19 : #include "ngx_sha1.h"
20 : #endif
21 :
22 : #include "ngx_md5.h"
23 :
24 : #if (NGX_OPENSSL)
25 : #include <openssl/evp.h>
26 : #include <openssl/hmac.h>
27 : #endif
28 :
29 :
30 : #ifndef SHA_DIGEST_LENGTH
31 : #define SHA_DIGEST_LENGTH 20
32 : #endif
33 :
34 :
35 : static uintptr_t ngx_http_lua_ngx_escape_sql_str(u_char *dst, u_char *src,
36 : size_t size);
37 : static int ngx_http_lua_ngx_escape_uri(lua_State *L);
38 : static int ngx_http_lua_ngx_unescape_uri(lua_State *L);
39 : static int ngx_http_lua_ngx_quote_sql_str(lua_State *L);
40 : static int ngx_http_lua_ngx_md5(lua_State *L);
41 : static int ngx_http_lua_ngx_md5_bin(lua_State *L);
42 :
43 : #if (NGX_HAVE_SHA1)
44 : static int ngx_http_lua_ngx_sha1_bin(lua_State *L);
45 : #endif
46 :
47 : static int ngx_http_lua_ngx_decode_base64(lua_State *L);
48 : static int ngx_http_lua_ngx_encode_base64(lua_State *L);
49 : static int ngx_http_lua_ngx_crc32_short(lua_State *L);
50 : static int ngx_http_lua_ngx_crc32_long(lua_State *L);
51 : static int ngx_http_lua_ngx_encode_args(lua_State *L);
52 : static int ngx_http_lua_ngx_decode_args(lua_State *L);
53 : #if (NGX_OPENSSL)
54 : static int ngx_http_lua_ngx_hmac_sha1(lua_State *L);
55 : #endif
56 :
57 :
58 : void
59 18 : ngx_http_lua_inject_string_api(lua_State *L)
60 : {
61 18 : lua_pushcfunction(L, ngx_http_lua_ngx_escape_uri);
62 18 : lua_setfield(L, -2, "escape_uri");
63 :
64 18 : lua_pushcfunction(L, ngx_http_lua_ngx_unescape_uri);
65 18 : lua_setfield(L, -2, "unescape_uri");
66 :
67 18 : lua_pushcfunction(L, ngx_http_lua_ngx_encode_args);
68 18 : lua_setfield(L, -2, "encode_args");
69 :
70 18 : lua_pushcfunction(L, ngx_http_lua_ngx_decode_args);
71 18 : lua_setfield(L, -2, "decode_args");
72 :
73 18 : lua_pushcfunction(L, ngx_http_lua_ngx_quote_sql_str);
74 18 : lua_setfield(L, -2, "quote_sql_str");
75 :
76 18 : lua_pushcfunction(L, ngx_http_lua_ngx_decode_base64);
77 18 : lua_setfield(L, -2, "decode_base64");
78 :
79 18 : lua_pushcfunction(L, ngx_http_lua_ngx_encode_base64);
80 18 : lua_setfield(L, -2, "encode_base64");
81 :
82 18 : lua_pushcfunction(L, ngx_http_lua_ngx_md5_bin);
83 18 : lua_setfield(L, -2, "md5_bin");
84 :
85 18 : lua_pushcfunction(L, ngx_http_lua_ngx_md5);
86 18 : lua_setfield(L, -2, "md5");
87 :
88 : #if (NGX_HAVE_SHA1)
89 18 : lua_pushcfunction(L, ngx_http_lua_ngx_sha1_bin);
90 18 : lua_setfield(L, -2, "sha1_bin");
91 : #endif
92 :
93 18 : lua_pushcfunction(L, ngx_http_lua_ngx_crc32_short);
94 18 : lua_setfield(L, -2, "crc32_short");
95 :
96 18 : lua_pushcfunction(L, ngx_http_lua_ngx_crc32_long);
97 18 : lua_setfield(L, -2, "crc32_long");
98 :
99 : #if (NGX_OPENSSL)
100 18 : lua_pushcfunction(L, ngx_http_lua_ngx_hmac_sha1);
101 18 : lua_setfield(L, -2, "hmac_sha1");
102 : #endif
103 18 : }
104 :
105 :
106 : static int
107 0 : ngx_http_lua_ngx_escape_uri(lua_State *L)
108 : {
109 : size_t len, dlen;
110 : uintptr_t escape;
111 : u_char *src, *dst;
112 :
113 0 : if (lua_gettop(L) != 1) {
114 0 : return luaL_error(L, "expecting one argument");
115 : }
116 :
117 0 : if (lua_isnil(L, 1)) {
118 0 : lua_pushliteral(L, "");
119 0 : return 1;
120 : }
121 :
122 0 : src = (u_char *) luaL_checklstring(L, 1, &len);
123 :
124 0 : if (len == 0) {
125 0 : return 1;
126 : }
127 :
128 0 : escape = 2 * ngx_http_lua_escape_uri(NULL, src, len,
129 : NGX_ESCAPE_URI_COMPONENT);
130 :
131 0 : if (escape) {
132 0 : dlen = escape + len;
133 0 : dst = lua_newuserdata(L, dlen);
134 0 : ngx_http_lua_escape_uri(dst, src, len, NGX_ESCAPE_URI_COMPONENT);
135 0 : lua_pushlstring(L, (char *) dst, dlen);
136 : }
137 :
138 0 : return 1;
139 : }
140 :
141 :
142 : static int
143 0 : ngx_http_lua_ngx_unescape_uri(lua_State *L)
144 : {
145 : size_t len, dlen;
146 : u_char *p;
147 : u_char *src, *dst;
148 :
149 0 : if (lua_gettop(L) != 1) {
150 0 : return luaL_error(L, "expecting one argument");
151 : }
152 :
153 0 : if (lua_isnil(L, 1)) {
154 0 : lua_pushliteral(L, "");
155 0 : return 1;
156 : }
157 :
158 0 : src = (u_char *) luaL_checklstring(L, 1, &len);
159 :
160 : /* the unescaped string can only be smaller */
161 0 : dlen = len;
162 :
163 0 : p = lua_newuserdata(L, dlen);
164 :
165 0 : dst = p;
166 :
167 0 : ngx_http_lua_unescape_uri(&dst, &src, len, NGX_UNESCAPE_URI_COMPONENT);
168 :
169 0 : lua_pushlstring(L, (char *) p, dst - p);
170 :
171 0 : return 1;
172 : }
173 :
174 :
175 : static int
176 0 : ngx_http_lua_ngx_quote_sql_str(lua_State *L)
177 : {
178 : size_t len, dlen, escape;
179 : u_char *p;
180 : u_char *src, *dst;
181 :
182 0 : if (lua_gettop(L) != 1) {
183 0 : return luaL_error(L, "expecting one argument");
184 : }
185 :
186 0 : src = (u_char *) luaL_checklstring(L, 1, &len);
187 :
188 0 : if (len == 0) {
189 0 : dst = (u_char *) "''";
190 0 : dlen = sizeof("''") - 1;
191 0 : lua_pushlstring(L, (char *) dst, dlen);
192 0 : return 1;
193 : }
194 :
195 0 : escape = ngx_http_lua_ngx_escape_sql_str(NULL, src, len);
196 :
197 0 : dlen = sizeof("''") - 1 + len + escape;
198 :
199 0 : p = lua_newuserdata(L, dlen);
200 :
201 0 : dst = p;
202 :
203 0 : *p++ = '\'';
204 :
205 0 : if (escape == 0) {
206 0 : p = ngx_copy(p, src, len);
207 :
208 : } else {
209 0 : p = (u_char *) ngx_http_lua_ngx_escape_sql_str(p, src, len);
210 : }
211 :
212 0 : *p++ = '\'';
213 :
214 0 : if (p != dst + dlen) {
215 0 : return NGX_ERROR;
216 : }
217 :
218 0 : lua_pushlstring(L, (char *) dst, p - dst);
219 :
220 0 : return 1;
221 : }
222 :
223 :
224 : static uintptr_t
225 0 : ngx_http_lua_ngx_escape_sql_str(u_char *dst, u_char *src, size_t size)
226 : {
227 : ngx_uint_t n;
228 :
229 0 : if (dst == NULL) {
230 : /* find the number of chars to be escaped */
231 0 : n = 0;
232 0 : while (size) {
233 : /* the highest bit of all the UTF-8 chars
234 : * is always 1 */
235 0 : if ((*src & 0x80) == 0) {
236 0 : switch (*src) {
237 0 : case '\0':
238 : case '\b':
239 : case '\n':
240 : case '\r':
241 : case '\t':
242 : case 26: /* \Z */
243 : case '\\':
244 : case '\'':
245 : case '"':
246 0 : n++;
247 0 : break;
248 0 : default:
249 0 : break;
250 : }
251 0 : }
252 0 : src++;
253 0 : size--;
254 : }
255 :
256 0 : return (uintptr_t) n;
257 : }
258 :
259 0 : while (size) {
260 0 : if ((*src & 0x80) == 0) {
261 0 : switch (*src) {
262 0 : case '\0':
263 0 : *dst++ = '\\';
264 0 : *dst++ = '0';
265 0 : break;
266 :
267 0 : case '\b':
268 0 : *dst++ = '\\';
269 0 : *dst++ = 'b';
270 0 : break;
271 :
272 0 : case '\n':
273 0 : *dst++ = '\\';
274 0 : *dst++ = 'n';
275 0 : break;
276 :
277 0 : case '\r':
278 0 : *dst++ = '\\';
279 0 : *dst++ = 'r';
280 0 : break;
281 :
282 0 : case '\t':
283 0 : *dst++ = '\\';
284 0 : *dst++ = 't';
285 0 : break;
286 :
287 0 : case 26:
288 0 : *dst++ = '\\';
289 0 : *dst++ = 'Z';
290 0 : break;
291 :
292 0 : case '\\':
293 0 : *dst++ = '\\';
294 0 : *dst++ = '\\';
295 0 : break;
296 :
297 0 : case '\'':
298 0 : *dst++ = '\\';
299 0 : *dst++ = '\'';
300 0 : break;
301 :
302 0 : case '"':
303 0 : *dst++ = '\\';
304 0 : *dst++ = '"';
305 0 : break;
306 :
307 0 : default:
308 0 : *dst++ = *src;
309 0 : break;
310 : }
311 : } else {
312 0 : *dst++ = *src;
313 : }
314 0 : src++;
315 0 : size--;
316 : } /* while (size) */
317 :
318 0 : return (uintptr_t) dst;
319 : }
320 :
321 :
322 : static int
323 0 : ngx_http_lua_ngx_md5(lua_State *L)
324 : {
325 : u_char *src;
326 : size_t slen;
327 :
328 : ngx_md5_t md5;
329 : u_char md5_buf[MD5_DIGEST_LENGTH];
330 : u_char hex_buf[2 * sizeof(md5_buf)];
331 :
332 0 : if (lua_gettop(L) != 1) {
333 0 : return luaL_error(L, "expecting one argument");
334 : }
335 :
336 0 : if (lua_isnil(L, 1)) {
337 0 : src = (u_char *) "";
338 0 : slen = 0;
339 :
340 : } else {
341 0 : src = (u_char *) luaL_checklstring(L, 1, &slen);
342 : }
343 :
344 0 : ngx_md5_init(&md5);
345 0 : ngx_md5_update(&md5, src, slen);
346 0 : ngx_md5_final(md5_buf, &md5);
347 :
348 0 : ngx_hex_dump(hex_buf, md5_buf, sizeof(md5_buf));
349 :
350 0 : lua_pushlstring(L, (char *) hex_buf, sizeof(hex_buf));
351 :
352 0 : return 1;
353 : }
354 :
355 :
356 : static int
357 0 : ngx_http_lua_ngx_md5_bin(lua_State *L)
358 : {
359 : u_char *src;
360 : size_t slen;
361 :
362 : ngx_md5_t md5;
363 : u_char md5_buf[MD5_DIGEST_LENGTH];
364 :
365 0 : if (lua_gettop(L) != 1) {
366 0 : return luaL_error(L, "expecting one argument");
367 : }
368 :
369 0 : if (lua_isnil(L, 1)) {
370 0 : src = (u_char *) "";
371 0 : slen = 0;
372 :
373 : } else {
374 0 : src = (u_char *) luaL_checklstring(L, 1, &slen);
375 : }
376 :
377 : dd("slen: %d", (int) slen);
378 :
379 0 : ngx_md5_init(&md5);
380 0 : ngx_md5_update(&md5, src, slen);
381 0 : ngx_md5_final(md5_buf, &md5);
382 :
383 0 : lua_pushlstring(L, (char *) md5_buf, sizeof(md5_buf));
384 :
385 0 : return 1;
386 : }
387 :
388 :
389 : #if (NGX_HAVE_SHA1)
390 : static int
391 0 : ngx_http_lua_ngx_sha1_bin(lua_State *L)
392 : {
393 : u_char *src;
394 : size_t slen;
395 :
396 : ngx_sha1_t sha;
397 : u_char sha_buf[SHA_DIGEST_LENGTH];
398 :
399 0 : if (lua_gettop(L) != 1) {
400 0 : return luaL_error(L, "expecting one argument");
401 : }
402 :
403 0 : if (lua_isnil(L, 1)) {
404 0 : src = (u_char *) "";
405 0 : slen = 0;
406 :
407 : } else {
408 0 : src = (u_char *) luaL_checklstring(L, 1, &slen);
409 : }
410 :
411 : dd("slen: %d", (int) slen);
412 :
413 0 : ngx_sha1_init(&sha);
414 0 : ngx_sha1_update(&sha, src, slen);
415 0 : ngx_sha1_final(sha_buf, &sha);
416 :
417 0 : lua_pushlstring(L, (char *) sha_buf, sizeof(sha_buf));
418 :
419 0 : return 1;
420 : }
421 : #endif
422 :
423 :
424 : static int
425 0 : ngx_http_lua_ngx_decode_base64(lua_State *L)
426 : {
427 : ngx_str_t p, src;
428 :
429 0 : if (lua_gettop(L) != 1) {
430 0 : return luaL_error(L, "expecting one argument");
431 : }
432 :
433 0 : if (lua_type(L, 1) != LUA_TSTRING) {
434 0 : return luaL_error(L, "string argument only");
435 : }
436 :
437 0 : src.data = (u_char *) luaL_checklstring(L, 1, &src.len);
438 :
439 0 : p.len = ngx_base64_decoded_length(src.len);
440 :
441 0 : p.data = lua_newuserdata(L, p.len);
442 :
443 0 : if (ngx_decode_base64(&p, &src) == NGX_OK) {
444 0 : lua_pushlstring(L, (char *) p.data, p.len);
445 :
446 : } else {
447 0 : lua_pushnil(L);
448 : }
449 :
450 0 : return 1;
451 : }
452 :
453 :
454 : static void
455 0 : ngx_http_lua_encode_base64(ngx_str_t *dst, ngx_str_t *src, int no_padding)
456 : {
457 : u_char *d, *s;
458 : size_t len;
459 : static u_char basis[] =
460 : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
461 :
462 0 : len = src->len;
463 0 : s = src->data;
464 0 : d = dst->data;
465 :
466 0 : while (len > 2) {
467 0 : *d++ = basis[(s[0] >> 2) & 0x3f];
468 0 : *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
469 0 : *d++ = basis[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
470 0 : *d++ = basis[s[2] & 0x3f];
471 :
472 0 : s += 3;
473 0 : len -= 3;
474 : }
475 :
476 0 : if (len) {
477 0 : *d++ = basis[(s[0] >> 2) & 0x3f];
478 :
479 0 : if (len == 1) {
480 0 : *d++ = basis[(s[0] & 3) << 4];
481 0 : if (!no_padding) {
482 0 : *d++ = '=';
483 : }
484 :
485 : } else {
486 0 : *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
487 0 : *d++ = basis[(s[1] & 0x0f) << 2];
488 : }
489 :
490 0 : if (!no_padding) {
491 0 : *d++ = '=';
492 : }
493 : }
494 :
495 0 : dst->len = d - dst->data;
496 0 : }
497 :
498 :
499 : static size_t
500 0 : ngx_http_lua_base64_encoded_length(size_t n, int no_padding)
501 : {
502 0 : return no_padding ? (n * 8 + 5) / 6 : ngx_base64_encoded_length(n);
503 : }
504 :
505 :
506 : static int
507 0 : ngx_http_lua_ngx_encode_base64(lua_State *L)
508 : {
509 : int n;
510 0 : int no_padding = 0;
511 : ngx_str_t p, src;
512 :
513 0 : n = lua_gettop(L);
514 0 : if (n != 1 && n != 2) {
515 0 : return luaL_error(L, "expecting one or two arguments");
516 : }
517 :
518 0 : if (lua_isnil(L, 1)) {
519 0 : src.data = (u_char *) "";
520 0 : src.len = 0;
521 :
522 : } else {
523 0 : src.data = (u_char *) luaL_checklstring(L, 1, &src.len);
524 : }
525 :
526 0 : if (n == 2) {
527 : /* get the 2nd optional argument */
528 0 : luaL_checktype(L, 2, LUA_TBOOLEAN);
529 0 : no_padding = lua_toboolean(L, 2);
530 : }
531 :
532 0 : p.len = ngx_http_lua_base64_encoded_length(src.len, no_padding);
533 :
534 0 : p.data = lua_newuserdata(L, p.len);
535 :
536 0 : ngx_http_lua_encode_base64(&p, &src, no_padding);
537 :
538 0 : lua_pushlstring(L, (char *) p.data, p.len);
539 :
540 0 : return 1;
541 : }
542 :
543 :
544 : static int
545 0 : ngx_http_lua_ngx_crc32_short(lua_State *L)
546 : {
547 : u_char *p;
548 : size_t len;
549 :
550 0 : if (lua_gettop(L) != 1) {
551 0 : return luaL_error(L, "expecting one argument, but got %d",
552 : lua_gettop(L));
553 : }
554 :
555 0 : p = (u_char *) luaL_checklstring(L, 1, &len);
556 :
557 0 : lua_pushnumber(L, (lua_Number) ngx_crc32_short(p, len));
558 0 : return 1;
559 : }
560 :
561 :
562 : static int
563 0 : ngx_http_lua_ngx_crc32_long(lua_State *L)
564 : {
565 : u_char *p;
566 : size_t len;
567 :
568 0 : if (lua_gettop(L) != 1) {
569 0 : return luaL_error(L, "expecting one argument, but got %d",
570 : lua_gettop(L));
571 : }
572 :
573 0 : p = (u_char *) luaL_checklstring(L, 1, &len);
574 :
575 0 : lua_pushnumber(L, (lua_Number) ngx_crc32_long(p, len));
576 0 : return 1;
577 : }
578 :
579 :
580 : static int
581 0 : ngx_http_lua_ngx_encode_args(lua_State *L)
582 : {
583 : ngx_str_t args;
584 :
585 0 : if (lua_gettop(L) != 1) {
586 0 : return luaL_error(L, "expecting 1 argument but seen %d",
587 : lua_gettop(L));
588 : }
589 :
590 0 : luaL_checktype(L, 1, LUA_TTABLE);
591 0 : ngx_http_lua_process_args_option(NULL, L, 1, &args);
592 0 : lua_pushlstring(L, (char *) args.data, args.len);
593 0 : return 1;
594 : }
595 :
596 :
597 : static int
598 0 : ngx_http_lua_ngx_decode_args(lua_State *L)
599 : {
600 : u_char *buf;
601 : u_char *tmp;
602 0 : size_t len = 0;
603 : int n;
604 : int max;
605 :
606 0 : n = lua_gettop(L);
607 :
608 0 : if (n != 1 && n != 2) {
609 0 : return luaL_error(L, "expecting 1 or 2 arguments but seen %d", n);
610 : }
611 :
612 0 : buf = (u_char *) luaL_checklstring(L, 1, &len);
613 :
614 0 : if (n == 2) {
615 0 : max = luaL_checkint(L, 2);
616 0 : lua_pop(L, 1);
617 :
618 : } else {
619 0 : max = NGX_HTTP_LUA_MAX_ARGS;
620 : }
621 :
622 0 : tmp = lua_newuserdata(L, len);
623 0 : ngx_memcpy(tmp, buf, len);
624 :
625 0 : lua_createtable(L, 0, 4);
626 :
627 0 : return ngx_http_lua_parse_args(L, tmp, tmp + len, max);
628 : }
629 :
630 :
631 : #if (NGX_OPENSSL)
632 : static int
633 0 : ngx_http_lua_ngx_hmac_sha1(lua_State *L)
634 : {
635 : u_char *sec, *sts;
636 : size_t lsec, lsts;
637 : unsigned int md_len;
638 : unsigned char md[EVP_MAX_MD_SIZE];
639 : const EVP_MD *evp_md;
640 :
641 0 : if (lua_gettop(L) != 2) {
642 0 : return luaL_error(L, "expecting 2 arguments, but got %d",
643 : lua_gettop(L));
644 : }
645 :
646 0 : sec = (u_char *) luaL_checklstring(L, 1, &lsec);
647 0 : sts = (u_char *) luaL_checklstring(L, 2, &lsts);
648 :
649 0 : evp_md = EVP_sha1();
650 :
651 0 : HMAC(evp_md, sec, lsec, sts, lsts, md, &md_len);
652 :
653 0 : lua_pushlstring(L, (char *) md, md_len);
654 :
655 0 : return 1;
656 : }
657 : #endif
658 :
659 :
660 : #ifndef NGX_LUA_NO_FFI_API
661 : void
662 0 : ngx_http_lua_ffi_md5_bin(const u_char *src, size_t len, u_char *dst)
663 : {
664 : ngx_md5_t md5;
665 :
666 0 : ngx_md5_init(&md5);
667 0 : ngx_md5_update(&md5, src, len);
668 0 : ngx_md5_final(dst, &md5);
669 0 : }
670 :
671 :
672 : void
673 0 : ngx_http_lua_ffi_md5(const u_char *src, size_t len, u_char *dst)
674 : {
675 : ngx_md5_t md5;
676 : u_char md5_buf[MD5_DIGEST_LENGTH];
677 :
678 0 : ngx_md5_init(&md5);
679 0 : ngx_md5_update(&md5, src, len);
680 0 : ngx_md5_final(md5_buf, &md5);
681 :
682 0 : ngx_hex_dump(dst, md5_buf, sizeof(md5_buf));
683 0 : }
684 :
685 :
686 : int
687 0 : ngx_http_lua_ffi_sha1_bin(const u_char *src, size_t len, u_char *dst)
688 : {
689 : #if (NGX_HAVE_SHA1)
690 : ngx_sha1_t sha;
691 :
692 0 : ngx_sha1_init(&sha);
693 0 : ngx_sha1_update(&sha, src, len);
694 0 : ngx_sha1_final(dst, &sha);
695 :
696 0 : return 1;
697 : #else
698 : return 0;
699 : #endif
700 : }
701 :
702 :
703 : size_t
704 0 : ngx_http_lua_ffi_encode_base64(const u_char *src, size_t slen, u_char *dst,
705 : int no_padding)
706 : {
707 : ngx_str_t in, out;
708 :
709 0 : in.data = (u_char *) src;
710 0 : in.len = slen;
711 :
712 0 : out.data = dst;
713 :
714 0 : ngx_http_lua_encode_base64(&out, &in, no_padding);
715 :
716 0 : return out.len;
717 : }
718 :
719 :
720 : int
721 0 : ngx_http_lua_ffi_decode_base64(const u_char *src, size_t slen, u_char *dst,
722 : size_t *dlen)
723 : {
724 : ngx_int_t rc;
725 : ngx_str_t in, out;
726 :
727 0 : in.data = (u_char *) src;
728 0 : in.len = slen;
729 :
730 0 : out.data = dst;
731 :
732 0 : rc = ngx_decode_base64(&out, &in);
733 :
734 0 : *dlen = out.len;
735 :
736 0 : return rc == NGX_OK;
737 : }
738 :
739 :
740 : size_t
741 0 : ngx_http_lua_ffi_unescape_uri(const u_char *src, size_t len, u_char *dst)
742 : {
743 0 : u_char *p = dst;
744 :
745 0 : ngx_http_lua_unescape_uri(&p, (u_char **) &src, len,
746 : NGX_UNESCAPE_URI_COMPONENT);
747 0 : return p - dst;
748 : }
749 :
750 :
751 : size_t
752 0 : ngx_http_lua_ffi_uri_escaped_length(const u_char *src, size_t len)
753 : {
754 0 : return len + 2 * ngx_http_lua_escape_uri(NULL, (u_char *) src, len,
755 : NGX_ESCAPE_URI_COMPONENT);
756 : }
757 :
758 :
759 : void
760 0 : ngx_http_lua_ffi_escape_uri(const u_char *src, size_t len, u_char *dst)
761 : {
762 0 : ngx_http_lua_escape_uri(dst, (u_char *) src, len, NGX_ESCAPE_URI_COMPONENT);
763 0 : }
764 :
765 : #endif
766 :
767 : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|