diff options
author | Xinchen Hui <laruence@gmail.com> | 2017-08-06 17:48:05 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2017-08-06 17:48:05 +0800 |
commit | 513b0093c2b480bb752fb354012f42c446769486 (patch) | |
tree | 71b34ea413aef37d25f233324122bcdb278b7eda /ext/standard/url.c | |
parent | 6546c516dd61f7f9efecbd9144c02218614d4c51 (diff) | |
download | php-git-513b0093c2b480bb752fb354012f42c446769486.tar.gz |
Refactor php_url struct to save memory dup in common cases
Diffstat (limited to 'ext/standard/url.c')
-rw-r--r-- | ext/standard/url.c | 105 |
1 files changed, 47 insertions, 58 deletions
diff --git a/ext/standard/url.c b/ext/standard/url.c index a3a19a2b22..e909eee347 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -42,19 +42,19 @@ PHPAPI void php_url_free(php_url *theurl) { if (theurl->scheme) - efree(theurl->scheme); + zend_string_release(theurl->scheme); if (theurl->user) - efree(theurl->user); + zend_string_release(theurl->user); if (theurl->pass) - efree(theurl->pass); + zend_string_release(theurl->pass); if (theurl->host) - efree(theurl->host); + zend_string_release(theurl->host); if (theurl->path) - efree(theurl->path); + zend_string_release(theurl->path); if (theurl->query) - efree(theurl->query); + zend_string_release(theurl->query); if (theurl->fragment) - efree(theurl->fragment); + zend_string_release(theurl->fragment); efree(theurl); } /* }}} */ @@ -124,8 +124,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) } if (e + 1 == ue) { /* only scheme is available */ - ret->scheme = estrndup(s, (e - s)); - php_replace_controlchars_ex(ret->scheme, (e - s)); + ret->scheme = zend_string_init(s, (e - s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme)); return ret; } @@ -146,18 +146,18 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) goto parse_port; } - ret->scheme = estrndup(s, (e-s)); - php_replace_controlchars_ex(ret->scheme, (e - s)); + ret->scheme = zend_string_init(s, (e-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme)); s = e + 1; goto just_path; } else { - ret->scheme = estrndup(s, (e-s)); - php_replace_controlchars_ex(ret->scheme, (e - s)); + ret->scheme = zend_string_init(s, (e-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme)); if (e + 2 < ue && *(e + 2) == '/') { s = e + 3; - if (!strncasecmp("file", ret->scheme, sizeof("file"))) { + if (zend_string_equals_literal_ci(ret->scheme, "file")) { if (e + 3 < ue && *(e + 3) == '/') { /* support windows drive letters as in: file:///c:/somedir/file.txt @@ -193,13 +193,11 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) s += 2; } } else { - if (ret->scheme) efree(ret->scheme); - efree(ret); + php_url_free(ret); return NULL; } } else if (p == pp && pp == ue) { - if (ret->scheme) efree(ret->scheme); - efree(ret); + php_url_free(ret); return NULL; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; @@ -228,15 +226,15 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { if ((pp = memchr(s, ':', (p-s)))) { - ret->user = estrndup(s, (pp-s)); - php_replace_controlchars_ex(ret->user, (pp - s)); + ret->user = zend_string_init(s, (pp-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); pp++; - ret->pass = estrndup(pp, (p-pp)); - php_replace_controlchars_ex(ret->pass, (p-pp)); + ret->pass = zend_string_init(pp, (p-pp), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass)); } else { - ret->user = estrndup(s, (p-s)); - php_replace_controlchars_ex(ret->user, (p-s)); + ret->user = zend_string_init(s, (p-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); } s = p + 1; @@ -256,10 +254,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (!ret->port) { p++; if (e-p > 5) { /* port cannot be longer then 5 characters */ - if (ret->scheme) efree(ret->scheme); - if (ret->user) efree(ret->user); - if (ret->pass) efree(ret->pass); - efree(ret); + php_url_free(ret); return NULL; } else if (e - p > 0) { zend_long port; @@ -269,10 +264,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (port > 0 && port <= 65535) { ret->port = (unsigned short)port; } else { - if (ret->scheme) efree(ret->scheme); - if (ret->user) efree(ret->user); - if (ret->pass) efree(ret->pass); - efree(ret); + php_url_free(ret); return NULL; } } @@ -284,15 +276,12 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) /* check if we have a valid host, if we don't reject the string as url */ if ((p-s) < 1) { - if (ret->scheme) efree(ret->scheme); - if (ret->user) efree(ret->user); - if (ret->pass) efree(ret->pass); - efree(ret); + php_url_free(ret); return NULL; } - ret->host = estrndup(s, (p-s)); - php_replace_controlchars_ex(ret->host, (p - s)); + ret->host = zend_string_init(s, (p-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->host), ZSTR_LEN(ret->host)); if (e == ue) { return ret; @@ -307,8 +296,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (p) { p++; if (p < e) { - ret->fragment = estrndup(p, (e - p)); - php_replace_controlchars_ex(ret->fragment, (e - p)); + ret->fragment = zend_string_init(p, (e - p), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->fragment), ZSTR_LEN(ret->fragment)); } e = p-1; } @@ -317,15 +306,15 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (p) { p++; if (p < e) { - ret->query = estrndup(p, (e - p)); - php_replace_controlchars_ex(ret->query, (e - p)); + ret->query = zend_string_init(p, (e - p), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->query), ZSTR_LEN(ret->query)); } e = p-1; } if (s < e || s == ue) { - ret->path = estrndup(s, (e - s)); - php_replace_controlchars_ex(ret->path, (e - s)); + ret->path = zend_string_init(s, (e - s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->path), ZSTR_LEN(ret->path)); } return ret; @@ -357,28 +346,28 @@ PHP_FUNCTION(parse_url) if (key > -1) { switch (key) { case PHP_URL_SCHEME: - if (resource->scheme != NULL) RETVAL_STRING(resource->scheme); + if (resource->scheme != NULL) RETVAL_STR_COPY(resource->scheme); break; case PHP_URL_HOST: - if (resource->host != NULL) RETVAL_STRING(resource->host); + if (resource->host != NULL) RETVAL_STR_COPY(resource->host); break; case PHP_URL_PORT: if (resource->port != 0) RETVAL_LONG(resource->port); break; case PHP_URL_USER: - if (resource->user != NULL) RETVAL_STRING(resource->user); + if (resource->user != NULL) RETVAL_STR_COPY(resource->user); break; case PHP_URL_PASS: - if (resource->pass != NULL) RETVAL_STRING(resource->pass); + if (resource->pass != NULL) RETVAL_STR_COPY(resource->pass); break; case PHP_URL_PATH: - if (resource->path != NULL) RETVAL_STRING(resource->path); + if (resource->path != NULL) RETVAL_STR_COPY(resource->path); break; case PHP_URL_QUERY: - if (resource->query != NULL) RETVAL_STRING(resource->query); + if (resource->query != NULL) RETVAL_STR_COPY(resource->query); break; case PHP_URL_FRAGMENT: - if (resource->fragment != NULL) RETVAL_STRING(resource->fragment); + if (resource->fragment != NULL) RETVAL_STR_COPY(resource->fragment); break; default: php_error_docref(NULL, E_WARNING, "Invalid URL component identifier " ZEND_LONG_FMT, key); @@ -392,11 +381,11 @@ PHP_FUNCTION(parse_url) /* add the various elements to the array */ if (resource->scheme != NULL) { - ZVAL_STRING(&tmp, resource->scheme); + ZVAL_STR_COPY(&tmp, resource->scheme); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_SCHEME), &tmp); } if (resource->host != NULL) { - ZVAL_STRING(&tmp, resource->host); + ZVAL_STR_COPY(&tmp, resource->host); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_HOST), &tmp); } if (resource->port != 0) { @@ -404,23 +393,23 @@ PHP_FUNCTION(parse_url) zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_PORT), &tmp); } if (resource->user != NULL) { - ZVAL_STRING(&tmp, resource->user); + ZVAL_STR_COPY(&tmp, resource->user); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_USER), &tmp); } if (resource->pass != NULL) { - ZVAL_STRING(&tmp, resource->pass); + ZVAL_STR_COPY(&tmp, resource->pass); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_PASS), &tmp); } if (resource->path != NULL) { - ZVAL_STRING(&tmp, resource->path); + ZVAL_STR_COPY(&tmp, resource->path); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_PATH), &tmp); } if (resource->query != NULL) { - ZVAL_STRING(&tmp, resource->query); + ZVAL_STR_COPY(&tmp, resource->query); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_QUERY), &tmp); } if (resource->fragment != NULL) { - ZVAL_STRING(&tmp, resource->fragment); + ZVAL_STR_COPY(&tmp, resource->fragment); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_FRAGMENT), &tmp); } done: |