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