[PECL-CVS] [pecl-web_services-oauth] master: Merge pull request #40 from php/memory-safety-audit
[email protected] (Rasmus Lerdorf via GitHub) Sun, 5 Apr 2026 03:02:35 +0000
| Newsgroups | php.pecl.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Rasmus Lerdorf (rlerdorf)
Committer: GitHub (web-flow)
Pusher: rlerdorf
Date: 2026-04-05T04:02:32+01:00
Commit: https://github.com/php/pecl-web_services-oauth/commit/a528c9fc8529f3db40525cac36714c1f0ac8019a
Raw diff: https://github.com/php/pecl-web_services-oauth/commit/a528c9fc8529f3db40525cac36714c1f0ac8019a.diff
Merge pull request #40 from php/memory-safety-audit
memory audit fixes
Changed paths:
M oauth.c
M provider.c
Diff:
diff --git a/oauth.c b/oauth.c
index f1c1c35..f05a95b 100644
--- a/oauth.c
+++ b/oauth.c
@@ -158,10 +158,6 @@ static void so_object_free_storage(zend_object *obj) /* {{{ */
soo->debug_info = NULL;
}
- smart_string_free(&soo->headers_in);
- if (soo->headers_out.c) {
- smart_string_free(&soo->headers_out);
- }
if(Z_TYPE(soo->debugArr) != IS_UNDEF) {
zval_ptr_dtor(&soo->debugArr);
}
@@ -172,6 +168,23 @@ static void so_object_free_storage(zend_object *obj) /* {{{ */
if (soo->timestamp) {
efree(soo->timestamp);
}
+ if (soo->multipart_files || soo->multipart_params) {
+ int mi;
+ for (mi = 0; mi < soo->multipart_files_num; mi++) {
+ if (soo->multipart_files) {
+ efree(soo->multipart_files[mi]);
+ }
+ if (soo->multipart_params) {
+ efree(soo->multipart_params[mi]);
+ }
+ }
+ if (soo->multipart_files) {
+ efree(soo->multipart_files);
+ }
+ if (soo->multipart_params) {
+ efree(soo->multipart_params);
+ }
+ }
}
/* }}} */
@@ -482,8 +495,8 @@ int oauth_http_build_query(php_so_object *soo, smart_string *s, HashTable *args,
soo->multipart_params = erealloc(soo->multipart_params, sizeof(char *) * (soo->multipart_files_num + 1));
convert_to_string_ex(cur_val);
- soo->multipart_files[soo->multipart_files_num] = Z_STRVAL_P(cur_val);
- soo->multipart_params[soo->multipart_files_num] = ZSTR_VAL(cur_key);
+ soo->multipart_files[soo->multipart_files_num] = estrdup(Z_STRVAL_P(cur_val));
+ soo->multipart_params[soo->multipart_files_num] = estrdup(ZSTR_VAL(cur_key));
++soo->multipart_files_num;
/* we don't add multipart files to the params */
@@ -1127,15 +1140,16 @@ long make_req_curl(php_so_object *soo, const char *url, const smart_string *payl
}
for(i=0; i < soo->multipart_files_num; i++) {
- char *type = NULL, *filename = NULL, *postval, *postval_orig;
+ char *type = NULL, *filename = NULL, *postval, *postval_orig, *param_name;
curl_mimepart *part;
/* swiped from ext/curl/interface.c to help with consistency */
postval_orig = postval = estrdup(soo->multipart_files[i]);
+ param_name = soo->multipart_params[i];
- if (postval[0] == '@' && soo->multipart_params[i][0] == '@') {
+ if (postval[0] == '@' && param_name[0] == '@') {
/* :< (chomp) @ */
- ++soo->multipart_params[i];
+ ++param_name;
++postval;
if((type = (char *) php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + strlen(soo->multipart_files[i]) - 1))) {
@@ -1161,7 +1175,7 @@ long make_req_curl(php_so_object *soo, const char *url, const smart_string *payl
efree(postval_orig);
goto cleanup;
}
- mres = curl_mime_name(part, soo->multipart_params[i]);
+ mres = curl_mime_name(part, param_name);
if (mres == CURLE_OK) mres = curl_mime_filedata(part, postval);
if (mres == CURLE_OK && filename) mres = curl_mime_filename(part, filename + sizeof(";filename=") - 1);
if (mres == CURLE_OK) mres = curl_mime_type(part, type ? type + sizeof(";type=") - 1 : "application/octet-stream");
@@ -1180,7 +1194,7 @@ long make_req_curl(php_so_object *soo, const char *url, const smart_string *payl
efree(postval_orig);
goto cleanup;
}
- mres = curl_mime_name(part, soo->multipart_params[i]);
+ mres = curl_mime_name(part, param_name);
if (mres == CURLE_OK) mres = curl_mime_data(part, postval, CURL_ZERO_TERMINATED);
if (mres != CURLE_OK) {
char *em;
@@ -1199,12 +1213,13 @@ long make_req_curl(php_so_object *soo, const char *url, const smart_string *payl
int i;
for(i=0; i < soo->multipart_files_num; i++) {
- char *type = NULL, *filename = NULL, *postval, *postval_orig;
+ char *type = NULL, *filename = NULL, *postval, *postval_orig, *param_name;
postval_orig = postval = estrdup(soo->multipart_files[i]);
+ param_name = soo->multipart_params[i];
- if (postval[0] == '@' && soo->multipart_params[i][0] == '@') {
- ++soo->multipart_params[i];
+ if (postval[0] == '@' && param_name[0] == '@') {
+ ++param_name;
++postval;
if((type = (char *) php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + strlen(soo->multipart_files[i]) - 1))) {
@@ -1225,24 +1240,24 @@ long make_req_curl(php_so_object *soo, const char *url, const smart_string *payl
if (filename) {
curl_formadd(&ff, &lf,
- CURLFORM_COPYNAME, soo->multipart_params[i],
- CURLFORM_NAMELENGTH, (long)strlen(soo->multipart_params[i]),
+ CURLFORM_COPYNAME, param_name,
+ CURLFORM_NAMELENGTH, (long)strlen(param_name),
CURLFORM_FILENAME, filename + sizeof(";filename=") - 1,
CURLFORM_CONTENTTYPE, type ? type + sizeof(";type=") - 1 : "application/octet-stream",
CURLFORM_FILE, postval,
CURLFORM_END);
} else {
curl_formadd(&ff, &lf,
- CURLFORM_COPYNAME, soo->multipart_params[i],
- CURLFORM_NAMELENGTH, (long)strlen(soo->multipart_params[i]),
+ CURLFORM_COPYNAME, param_name,
+ CURLFORM_NAMELENGTH, (long)strlen(param_name),
CURLFORM_CONTENTTYPE, type ? type + sizeof(";type=") - 1 : "application/octet-stream",
CURLFORM_FILE, postval,
CURLFORM_END);
}
} else {
curl_formadd(&ff, &lf,
- CURLFORM_COPYNAME, soo->multipart_params[i],
- CURLFORM_NAMELENGTH, (long)strlen(soo->multipart_params[i]),
+ CURLFORM_COPYNAME, param_name,
+ CURLFORM_NAMELENGTH, (long)strlen(param_name),
CURLFORM_COPYCONTENTS, postval,
CURLFORM_CONTENTSLENGTH, (long)strlen(postval),
CURLFORM_END);
@@ -1713,16 +1728,32 @@ static long oauth_fetch(php_so_object *soo, const char *url, const char *method,
#if OAUTH_USE_CURL
case OAUTH_REQENGINE_CURL:
http_response_code = make_req_curl(soo, surl.c, &payload, final_http_method, &rheaders);
- if (soo->multipart_files_num) {
- efree(soo->multipart_files);
- efree(soo->multipart_params);
- soo->multipart_files_num = 0;
- soo->is_multipart = 0;
- }
break;
#endif
}
+ if (soo->multipart_files || soo->multipart_params) {
+ int mi;
+ for (mi = 0; mi < soo->multipart_files_num; mi++) {
+ if (soo->multipart_files) {
+ efree(soo->multipart_files[mi]);
+ }
+ if (soo->multipart_params) {
+ efree(soo->multipart_params[mi]);
+ }
+ }
+ if (soo->multipart_files) {
+ efree(soo->multipart_files);
+ soo->multipart_files = NULL;
+ }
+ if (soo->multipart_params) {
+ efree(soo->multipart_params);
+ soo->multipart_params = NULL;
+ }
+ soo->multipart_files_num = 0;
+ soo->is_multipart = 0;
+ }
+
is_redirect = HTTP_IS_REDIRECT(http_response_code);
if(soo->debug) {
diff --git a/provider.c b/provider.c
index da09647..295af02 100644
--- a/provider.c
+++ b/provider.c
@@ -195,7 +195,11 @@ static void oauth_provider_set_std_params(zval *provider_obj, HashTable *sbs_var
static inline int oauth_provider_set_param_value(HashTable *ht, char *key, zval *val) /* {{{ */
{
Z_TRY_ADDREF_P(val);
- return zend_hash_str_update(ht, key, strlen(key), val) != NULL;
+ if (zend_hash_str_update(ht, key, strlen(key), val) == NULL) {
+ Z_TRY_DELREF_P(val);
+ return FAILURE;
+ }
+ return SUCCESS;
}
/* }}} */
@@ -206,17 +210,25 @@ static int oauth_provider_parse_auth_header(php_oauth_provider *sop, char *auth_
HashPosition hpos;
zend_string *regex = zend_string_init(OAUTH_REGEX, sizeof(OAUTH_REGEX) - 1, 0);
#if PHP_VERSION_ID >= 70400
- zend_string *s_auth_header = zend_string_init(auth_header, strlen(auth_header), 0);
+ zend_string *s_auth_header;
#endif
size_t decoded_len;
- if(!auth_header || strncasecmp(auth_header, "oauth", 4) || !sop) {
+ if(!auth_header || strncasecmp(auth_header, "oauth ", 6) || !sop) {
+ zend_string_release(regex);
return FAILURE;
}
/* pass "OAuth " */
- auth_header += 5;
+ auth_header += 6;
+
+#if PHP_VERSION_ID >= 70400
+ s_auth_header = zend_string_init(auth_header, strlen(auth_header), 0);
+#endif
if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) {
+#if PHP_VERSION_ID >= 70400
+ zend_string_release(s_auth_header);
+#endif
zend_string_release(regex);
return FAILURE;
}
@@ -246,6 +258,11 @@ static int oauth_provider_parse_auth_header(php_oauth_provider *sop, char *auth_
);
if (0 == Z_LVAL(return_value)) {
+ zval_ptr_dtor(&return_value);
+ zval_ptr_dtor(&subpats);
+#if PHP_VERSION_ID >= 70400
+ zend_string_release(s_auth_header);
+#endif
return FAILURE;
}
@@ -271,16 +288,26 @@ static int oauth_provider_parse_auth_header(php_oauth_provider *sop, char *auth_
tmp = estrndup(Z_STRVAL_P(current_val), Z_STRLEN_P(current_val));
decoded_len = php_url_decode(tmp, Z_STRLEN_P(current_val));
ZVAL_STRINGL(&decoded_val, tmp, decoded_len);
+ efree(tmp);
- if (oauth_provider_set_param_value(sop->oauth_params, Z_STRVAL_P(current_param), &decoded_val)==FAILURE) {
+ if (oauth_provider_set_param_value(sop->oauth_params, Z_STRVAL_P(current_param), &decoded_val) == FAILURE) {
+ zval_ptr_dtor(&decoded_val);
+ zval_ptr_dtor(&return_value);
+ zval_ptr_dtor(&subpats);
+#if PHP_VERSION_ID >= 70400
+ zend_string_release(s_auth_header);
+#endif
return FAILURE;
}
- Z_DELREF(decoded_val);
+ zval_ptr_dtor(&decoded_val);
}
} while (SUCCESS==zend_hash_move_forward_ex(Z_ARRVAL(subpats), &hpos));
zval_ptr_dtor(&return_value);
zval_ptr_dtor(&subpats);
+#if PHP_VERSION_ID >= 70400
+ zend_string_release(s_auth_header);
+#endif
return SUCCESS;
}
@@ -318,6 +345,9 @@ static void oauth_provider_register_cb(INTERNAL_FUNCTION_PARAMETERS, int type) /
tgt_cb = &sop->tsnonce_handler;
break;
default:
+ zval_ptr_dtor(&cb->fcall_info->function_name);
+ efree(cb->fcall_info);
+ efree(cb);
php_error_docref(NULL, E_ERROR, "Invalid callback type for OAuthProvider");
return;
}