Skip to content

Commit ffa22fd

Browse files
committed
add CURLOPT_SAFE_UPLOAD option
1 parent 9681fa9 commit ffa22fd

File tree

3 files changed

+56
-31
lines changed

3 files changed

+56
-31
lines changed

ext/curl/interface.c

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ ZEND_END_ARG_INFO()
317317
#if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
318318
ZEND_BEGIN_ARG_INFO(arginfo_curl_reset, 0)
319319
ZEND_ARG_INFO(0, ch)
320-
ZEND_END_ARG_INFO()
320+
ZEND_END_ARG_INFO()
321321
#endif
322322

323323
#if LIBCURL_VERSION_NUM > 0x070f03 /* 7.15.4 */
@@ -526,7 +526,7 @@ PHP_MINFO_FUNCTION(curl)
526526
#endif
527527
#if LIBCURL_VERSION_NUM >= 0x071600 /* 7.22.0 */
528528
{"NTLMWB", CURL_VERSION_NTLM_WB},
529-
#endif
529+
#endif
530530
#if LIBCURL_VERSION_NUM >= 0x070a08 /* 7.10.8 */
531531
{"SPNEGO", CURL_VERSION_SPNEGO},
532532
#endif
@@ -804,7 +804,7 @@ PHP_MINIT_FUNCTION(curl)
804804
REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME);
805805
REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME);
806806

807-
/* Other */
807+
/* Other */
808808
REGISTER_CURL_CONSTANT(CURLMSG_DONE);
809809
REGISTER_CURL_CONSTANT(CURLVERSION_NOW);
810810

@@ -846,7 +846,7 @@ PHP_MINIT_FUNCTION(curl)
846846
REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv2);
847847
REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv3);
848848
REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1);
849-
849+
850850
/* Curl TIMECOND constants (CURLOPT_TIMECONDITION) */
851851
REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE);
852852
REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE);
@@ -910,15 +910,15 @@ PHP_MINIT_FUNCTION(curl)
910910

911911
#if LIBCURL_VERSION_NUM >= 0x070d00 /* Available since 7.13.0 */
912912
REGISTER_CURL_CONSTANT(CURLOPT_FTP_ACCOUNT);
913-
#endif
913+
#endif
914914

915915
#if LIBCURL_VERSION_NUM >= 0x070b02 /* Available since 7.11.2 */
916916
REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY);
917917
#endif
918918

919919
#if LIBCURL_VERSION_NUM >= 0x070c02 /* Available since 7.12.2 */
920920
REGISTER_CURL_CONSTANT(CURLINFO_OS_ERRNO);
921-
#endif
921+
#endif
922922

923923
#if LIBCURL_VERSION_NUM >= 0x070c03 /* Available since 7.12.3 */
924924
REGISTER_CURL_CONSTANT(CURLINFO_NUM_CONNECTS);
@@ -959,7 +959,7 @@ PHP_MINIT_FUNCTION(curl)
959959
REGISTER_CURL_CONSTANT(CURLOPT_FTP_ALTERNATIVE_TO_USER);
960960
REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE);
961961
REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE);
962-
#endif
962+
#endif
963963

964964
#if LIBCURL_VERSION_NUM >= 0x071000 /* Available since 7.16.0 */
965965
REGISTER_CURL_CONSTANT(CURLOPT_SSL_SESSIONID_CACHE);
@@ -1003,7 +1003,7 @@ PHP_MINIT_FUNCTION(curl)
10031003
REGISTER_CURL_CONSTANT(CURLUSESSL_CONTROL);
10041004
REGISTER_CURL_CONSTANT(CURLUSESSL_NONE);
10051005
REGISTER_CURL_CONSTANT(CURLUSESSL_TRY);
1006-
#endif
1006+
#endif
10071007

10081008
#if LIBCURL_VERSION_NUM >= 0x071101 /* Available since 7.17.1 */
10091009
REGISTER_CURL_CONSTANT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5);
@@ -1053,7 +1053,7 @@ PHP_MINIT_FUNCTION(curl)
10531053
REGISTER_CURL_CONSTANT(CURLOPT_USERNAME);
10541054
#endif
10551055

1056-
#if LIBCURL_VERSION_NUM >= 0x071303 /* Available since 7.19.3 */
1056+
#if LIBCURL_VERSION_NUM >= 0x071303 /* Available since 7.19.3 */
10571057
REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST_IE);
10581058
#endif
10591059

@@ -1135,7 +1135,7 @@ PHP_MINIT_FUNCTION(curl)
11351135
REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_FAIL);
11361136
REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_MATCH);
11371137
REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_NOMATCH);
1138-
#endif
1138+
#endif
11391139

11401140
#if LIBCURL_VERSION_NUM >= 0x071502 /* Available since 7.21.2 */
11411141
REGISTER_CURL_CONSTANT(CURLPROTO_GOPHER);
@@ -1187,6 +1187,7 @@ PHP_MINIT_FUNCTION(curl)
11871187
#if CURLOPT_PASSWDFUNCTION != 0
11881188
REGISTER_CURL_CONSTANT(CURLOPT_PASSWDFUNCTION);
11891189
#endif
1190+
REGISTER_CURL_CONSTANT(CURLOPT_SAFE_UPLOAD);
11901191

11911192
#ifdef PHP_CURL_NEED_OPENSSL_TSL
11921193
if (!CRYPTO_get_id_callback()) {
@@ -1814,6 +1815,7 @@ static void alloc_curl_handle(php_curl **ch)
18141815
zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0);
18151816
zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist, 0);
18161817
zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0);
1818+
(*ch)->safe_upload = 0; /* for now, for BC reason we allow unsafe API */
18171819
}
18181820
/* }}} */
18191821

@@ -1835,7 +1837,7 @@ static void split_certinfo(char *string, zval *hash)
18351837
split = strstr(s, "; ");
18361838
if(split)
18371839
*split = '\0';
1838-
1840+
18391841
key = s;
18401842
tmp = memchr(key, '=', 64);
18411843
if(tmp) {
@@ -2061,7 +2063,7 @@ PHP_FUNCTION(curl_copy_handle)
20612063
if (ch->handlers->fnmatch->func_name) {
20622064
zval_add_ref(&ch->handlers->fnmatch->func_name);
20632065
dupch->handlers->fnmatch->func_name = ch->handlers->fnmatch->func_name;
2064-
}
2066+
}
20652067
dupch->handlers->fnmatch->method = ch->handlers->fnmatch->method;
20662068
curl_easy_setopt(dupch->cp, CURLOPT_FNMATCH_DATA, (void *) dupch);
20672069
}
@@ -2140,7 +2142,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
21402142
#if LIBCURL_VERSION_NUM >= 0x070a06 /* Available since 7.10.6 */
21412143
case CURLOPT_HTTPAUTH:
21422144
#endif
2143-
#if LIBCURL_VERSION_NUM >= 0x070a07 /* Available since 7.10.7 */
2145+
#if LIBCURL_VERSION_NUM >= 0x070a07 /* Available since 7.10.7 */
21442146
case CURLOPT_FTP_CREATE_MISSING_DIRS:
21452147
case CURLOPT_PROXYAUTH:
21462148
#endif
@@ -2190,11 +2192,11 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
21902192
case CURLOPT_USE_SSL:
21912193
#elif LIBCURL_VERSION_NUM >= 0x070b00 /* Available since 7.11.0 */
21922194
case CURLOPT_FTP_SSL:
2193-
#endif
2195+
#endif
21942196
#if LIBCURL_VERSION_NUM >= 0x071100 /* Available since 7.17.0 */
21952197
case CURLOPT_APPEND:
21962198
case CURLOPT_DIRLISTONLY:
2197-
#else
2199+
#else
21982200
case CURLOPT_FTPAPPEND:
21992201
case CURLOPT_FTPLISTONLY:
22002202
#endif
@@ -2252,6 +2254,10 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
22522254
#endif
22532255
error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
22542256
break;
2257+
case CURLOPT_SAFE_UPLOAD:
2258+
convert_to_long_ex(zvalue);
2259+
ch->safe_upload = (Z_LVAL_PP(zvalue) != 0);
2260+
break;
22552261

22562262
/* String options */
22572263
case CURLOPT_CAINFO:
@@ -2287,7 +2293,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
22872293
#endif
22882294
#if LIBCURL_VERSION_NUM >= 0x071004 /* Available since 7.16.4 */
22892295
case CURLOPT_KRBLEVEL:
2290-
#else
2296+
#else
22912297
case CURLOPT_KRB4LEVEL:
22922298
#endif
22932299
#if LIBCURL_VERSION_NUM >= 0x071101 /* Available since 7.17.1 */
@@ -2312,15 +2318,15 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
23122318
case CURLOPT_TLSAUTH_PASSWORD:
23132319
case CURLOPT_TLSAUTH_USERNAME:
23142320
#endif
2315-
#if LIBCURL_VERSION_NUM >= 0x071506 /* Available since 7.21.6 */
2321+
#if LIBCURL_VERSION_NUM >= 0x071506 /* Available since 7.21.6 */
23162322
case CURLOPT_ACCEPT_ENCODING:
23172323
case CURLOPT_TRANSFER_ENCODING:
23182324
#else
23192325
case CURLOPT_ENCODING:
23202326
#endif
23212327
#if LIBCURL_VERSION_NUM >= 0x071800 /* Available since 7.24.0 */
23222328
case CURLOPT_DNS_SERVERS:
2323-
#endif
2329+
#endif
23242330
#if LIBCURL_VERSION_NUM >= 0x071900 /* Available since 7.25.0 */
23252331
case CURLOPT_MAIL_AUTH:
23262332
#endif
@@ -2355,7 +2361,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
23552361
/* Curl file handle options */
23562362
case CURLOPT_FILE:
23572363
case CURLOPT_INFILE:
2358-
case CURLOPT_STDERR:
2364+
case CURLOPT_STDERR:
23592365
case CURLOPT_WRITEHEADER: {
23602366
FILE *fp = NULL;
23612367
int type;
@@ -2623,7 +2629,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
26232629
/* The arguments after _NAMELENGTH and _CONTENTSLENGTH
26242630
* must be explicitly cast to long in curl_formadd
26252631
* use since curl needs a long not an int. */
2626-
if (*postval == '@') {
2632+
if (!ch->safe_upload && *postval == '@') {
26272633
char *type, *filename;
26282634
++postval;
26292635

@@ -2771,7 +2777,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
27712777
/* the following options deal with files, therefore the open_basedir check
27722778
* is required.
27732779
*/
2774-
case CURLOPT_COOKIEFILE:
2780+
case CURLOPT_COOKIEFILE:
27752781
case CURLOPT_COOKIEJAR:
27762782
case CURLOPT_RANDOM_FILE:
27772783
case CURLOPT_SSLCERT:
@@ -2875,7 +2881,7 @@ PHP_FUNCTION(curl_setopt)
28752881

28762882
ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
28772883

2878-
if (options <= 0) {
2884+
if (options <= 0 && options != CURLOPT_SAFE_UPLOAD) {
28792885
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl configuration option");
28802886
RETURN_FALSE;
28812887
}
@@ -3091,7 +3097,7 @@ PHP_FUNCTION(curl_getinfo)
30913097
CAAS("redirect_url", s_code);
30923098
}
30933099
#endif
3094-
#if LIBCURL_VERSION_NUM >= 0x071300 /* Available since 7.19.0 */
3100+
#if LIBCURL_VERSION_NUM >= 0x071300 /* Available since 7.19.0 */
30953101
if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) {
30963102
CAAS("primary_ip", s_code);
30973103
}
@@ -3146,7 +3152,7 @@ PHP_FUNCTION(curl_getinfo)
31463152
case CURLINFO_STRING:
31473153
{
31483154
char *s_code = NULL;
3149-
3155+
31503156
if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) {
31513157
RETURN_STRING(s_code, 1);
31523158
} else {
@@ -3157,7 +3163,7 @@ PHP_FUNCTION(curl_getinfo)
31573163
case CURLINFO_LONG:
31583164
{
31593165
long code = 0;
3160-
3166+
31613167
if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
31623168
RETURN_LONG(code);
31633169
} else {
@@ -3399,7 +3405,7 @@ static void _php_curl_reset_handlers(php_curl *ch)
33993405
}
34003406
ch->handlers->write->fp = NULL;
34013407
ch->handlers->write->method = PHP_CURL_STDOUT;
3402-
3408+
34033409
if (ch->handlers->write_header->stream) {
34043410
Z_DELREF_P(ch->handlers->write_header->stream);
34053411
ch->handlers->write_header->stream = NULL;
@@ -3493,7 +3499,7 @@ PHP_FUNCTION(curl_escape)
34933499

34943500
/* {{{ proto void curl_unescape(resource ch, string str)
34953501
URL decodes the given string */
3496-
PHP_FUNCTION(curl_unescape)
3502+
PHP_FUNCTION(curl_unescape)
34973503
{
34983504
char *str = NULL, *out = NULL;
34993505
int str_len = 0, out_len;
@@ -3531,7 +3537,7 @@ PHP_FUNCTION(curl_pause)
35313537

35323538
ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
35333539

3534-
RETURN_LONG(curl_easy_pause(ch->cp, bitmask));
3540+
RETURN_LONG(curl_easy_pause(ch->cp, bitmask));
35353541
}
35363542
/* }}} */
35373543
#endif

ext/curl/php_curl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,11 @@ typedef struct {
180180
unsigned int uses;
181181
zend_bool in_callback;
182182
zval *clone;
183+
zend_bool safe_upload;
183184
} php_curl;
184185

186+
#define CURLOPT_SAFE_UPLOAD -1
187+
185188
typedef struct {
186189
int still_running;
187190
CURLM *multi;

ext/curl/tests/curl_file_upload.phpt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--TEST--
22
CURL file uploading
33
--SKIPIF--
4-
<?php
4+
<?php
55
if (!extension_loaded("curl")) {
66
exit("skip curl extension not loaded");
77
}
@@ -15,9 +15,9 @@ if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) {
1515
function testcurl($ch, $name, $mime = '', $postname = '')
1616
{
1717
if(!empty($postname)) {
18-
$file = new CurlFile($name, $mime, $postname);
18+
$file = new CurlFile($name, $mime, $postname);
1919
} else if(!empty($mime)) {
20-
$file = new CurlFile($name, $mime);
20+
$file = new CurlFile($name, $mime);
2121
} else {
2222
$file = new CurlFile($name);
2323
}
@@ -52,6 +52,16 @@ $params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt');
5252
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
5353
var_dump(curl_exec($ch));
5454

55+
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
56+
$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt');
57+
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
58+
var_dump(curl_exec($ch));
59+
60+
curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=post");
61+
$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt');
62+
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
63+
var_dump(curl_exec($ch));
64+
5565
curl_close($ch);
5666
?>
5767
--EXPECTF--
@@ -67,3 +77,9 @@ string(%d) "foo.txt|application/octet-stream"
6777

6878
Deprecated: curl_setopt(): Usage of @filename API for file uploading is deprecated. Please use CURLFile parameter instead in %s on line %d
6979
string(%d) "curl_testdata1.txt|application/octet-stream"
80+
string(0) ""
81+
string(%d) "array(1) {
82+
["file"]=>
83+
string(%d) "@%s/curl_testdata1.txt"
84+
}
85+
"

0 commit comments

Comments
 (0)