|
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