|
24 | 24 | #include "url.h"
|
25 | 25 | #include "file.h"
|
26 | 26 | #include "zend_simd.h"
|
| 27 | +#include "Zend/zend_smart_str.h" |
27 | 28 |
|
28 | 29 | /* {{{ free_url */
|
29 | 30 | PHPAPI void php_url_free(php_url *theurl)
|
@@ -446,16 +447,13 @@ static int php_htoi(const char *s)
|
446 | 447 |
|
447 | 448 | static const unsigned char hexchars[] = "0123456789ABCDEF";
|
448 | 449 |
|
449 |
| -static zend_always_inline zend_string *php_url_encode_impl(const char *s, size_t len, bool raw) /* {{{ */ { |
| 450 | +static zend_always_inline size_t php_url_encode_impl(unsigned char *to, const char *s, size_t len, bool raw) /* {{{ */ { |
450 | 451 | unsigned char c;
|
451 |
| - unsigned char *to; |
452 | 452 | unsigned char const *from, *end;
|
453 |
| - zend_string *start; |
| 453 | + const unsigned char *to_init = to; |
454 | 454 |
|
455 | 455 | from = (unsigned char *)s;
|
456 | 456 | end = (unsigned char *)s + len;
|
457 |
| - start = zend_string_safe_alloc(3, len, 0, 0); |
458 |
| - to = (unsigned char*)ZSTR_VAL(start); |
459 | 457 |
|
460 | 458 | #ifdef XSSE2
|
461 | 459 | while (from + 16 < end) {
|
@@ -534,19 +532,24 @@ static zend_always_inline zend_string *php_url_encode_impl(const char *s, size_t
|
534 | 532 | *to++ = c;
|
535 | 533 | }
|
536 | 534 | }
|
537 |
| - *to = '\0'; |
538 | 535 |
|
539 |
| - ZEND_ASSERT(!ZSTR_IS_INTERNED(start) && GC_REFCOUNT(start) == 1); |
540 |
| - start = zend_string_truncate(start, to - (unsigned char*)ZSTR_VAL(start), 0); |
541 |
| - |
542 |
| - return start; |
| 536 | + return to - to_init; |
543 | 537 | }
|
544 | 538 | /* }}} */
|
545 | 539 |
|
| 540 | +static zend_always_inline zend_string *php_url_encode_helper(char const *s, size_t len, bool raw) |
| 541 | +{ |
| 542 | + zend_string *result = zend_string_safe_alloc(3, len, 0, false); |
| 543 | + size_t length = php_url_encode_impl((unsigned char *) ZSTR_VAL(result), s, len, raw); |
| 544 | + ZSTR_VAL(result)[length] = '\0'; |
| 545 | + ZEND_ASSERT(!ZSTR_IS_INTERNED(result) && GC_REFCOUNT(result) == 1); |
| 546 | + return zend_string_truncate(result, length, false); |
| 547 | +} |
| 548 | + |
546 | 549 | /* {{{ php_url_encode */
|
547 | 550 | PHPAPI zend_string *php_url_encode(char const *s, size_t len)
|
548 | 551 | {
|
549 |
| - return php_url_encode_impl(s, len, 0); |
| 552 | + return php_url_encode_helper(s, len, false); |
550 | 553 | }
|
551 | 554 | /* }}} */
|
552 | 555 |
|
@@ -613,10 +616,19 @@ PHPAPI size_t php_url_decode(char *str, size_t len)
|
613 | 616 | /* {{{ php_raw_url_encode */
|
614 | 617 | PHPAPI zend_string *php_raw_url_encode(char const *s, size_t len)
|
615 | 618 | {
|
616 |
| - return php_url_encode_impl(s, len, 1); |
| 619 | + return php_url_encode_helper(s, len, true); |
617 | 620 | }
|
618 | 621 | /* }}} */
|
619 | 622 |
|
| 623 | +PHPAPI void php_url_encode_to_smart_str(smart_str *buf, char const *s, size_t len, bool raw) |
| 624 | +{ |
| 625 | + size_t start_length = smart_str_get_len(buf); |
| 626 | + size_t extend = zend_safe_address_guarded(3, len, 0); |
| 627 | + char *dest = smart_str_extend(buf, extend); |
| 628 | + size_t length = php_url_encode_impl((unsigned char *) dest, s, len, raw); |
| 629 | + ZSTR_LEN(buf->s) = start_length + length; |
| 630 | +} |
| 631 | + |
620 | 632 | /* {{{ URL-encodes string */
|
621 | 633 | PHP_FUNCTION(rawurlencode)
|
622 | 634 | {
|
|
0 commit comments