Skip to content

Commit d87ba95

Browse files
MaxKellermanniluuu1994
authored andcommitted
sapi/*: move duplicate "--define" code to library
1 parent 462dc9d commit d87ba95

File tree

8 files changed

+220
-168
lines changed

8 files changed

+220
-168
lines changed

configure.ac

+1
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,7 @@ PHP_ADD_SOURCES(TSRM, TSRM.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
16101610

16111611
PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \
16121612
fopen_wrappers.c alloca.c php_scandir.c \
1613+
php_ini_builder.c \
16131614
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
16141615
strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \
16151616
network.c php_open_temporary_file.c \

main/php_ini_builder.c

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| [email protected] so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Authors: Max Kellermann <[email protected]> |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#include "php_ini_builder.h"
18+
19+
#include <ctype.h>
20+
#include <string.h>
21+
22+
PHPAPI void php_ini_builder_prepend(struct php_ini_builder *b, const char *src, size_t length)
23+
{
24+
php_ini_builder_realloc(b, length);
25+
if (b->length > 0)
26+
memmove(b->value + length, b->value, b->length);
27+
memcpy(b->value, src, length);
28+
b->length += length;
29+
}
30+
31+
PHPAPI void php_ini_builder_unquoted(struct php_ini_builder *b, const char *name, size_t name_length, const char *value, size_t value_length)
32+
{
33+
php_ini_builder_realloc(b, name_length + 1 + value_length + 1);
34+
35+
memcpy(b->value + b->length, name, name_length);
36+
b->length += name_length;
37+
38+
b->value[b->length++] = '=';
39+
40+
memcpy(b->value + b->length, value, value_length);
41+
b->length += value_length;
42+
43+
b->value[b->length++] = '\n';
44+
}
45+
46+
PHPAPI void php_ini_builder_quoted(struct php_ini_builder *b, const char *name, size_t name_length, const char *value, size_t value_length)
47+
{
48+
php_ini_builder_realloc(b, name_length + 2 + value_length + 2);
49+
50+
memcpy(b->value + b->length, name, name_length);
51+
b->length += name_length;
52+
53+
b->value[b->length++] = '=';
54+
b->value[b->length++] = '"';
55+
56+
memcpy(b->value + b->length, value, value_length);
57+
b->length += value_length;
58+
59+
b->value[b->length++] = '"';
60+
b->value[b->length++] = '\n';
61+
}
62+
63+
PHPAPI void php_ini_builder_define(struct php_ini_builder *b, const char *arg)
64+
{
65+
const size_t len = strlen(arg);
66+
const char *val = strchr(arg, '=');
67+
68+
if (val != NULL) {
69+
val++;
70+
if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
71+
php_ini_builder_quoted(b, arg, val - arg - 1, val, arg + len - val);
72+
} else {
73+
php_ini_builder_realloc(b, len + strlen("\n"));
74+
memcpy(b->value + b->length, arg, len);
75+
b->length += len;
76+
b->value[b->length++] = '\n';
77+
}
78+
} else {
79+
php_ini_builder_unquoted(b, arg, len, "1", 1);
80+
}
81+
}
82+

main/php_ini_builder.h

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| [email protected] so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Authors: Max Kellermann <[email protected]> |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#ifndef PHP_INI_BUILDER_H
18+
#define PHP_INI_BUILDER_H
19+
20+
#include "php.h"
21+
22+
/**
23+
* A class which helps with constructing INI entries from the command
24+
* line.
25+
*/
26+
struct php_ini_builder {
27+
char *value;
28+
size_t length;
29+
};
30+
31+
BEGIN_EXTERN_C()
32+
33+
static inline void php_ini_builder_init(struct php_ini_builder *b)
34+
{
35+
b->value = NULL;
36+
b->length = 0;
37+
}
38+
39+
static inline void php_ini_builder_deinit(struct php_ini_builder *b)
40+
{
41+
free(b->value);
42+
}
43+
44+
/**
45+
* Null-terminate the buffer and return it.
46+
*/
47+
static inline char *php_ini_builder_finish(struct php_ini_builder *b)
48+
{
49+
if (b->value != NULL) {
50+
/* null-terminate the string */
51+
b->value[b->length] = '\0';
52+
}
53+
54+
return b->value;
55+
}
56+
57+
/**
58+
* Make room for more data.
59+
*
60+
* @param delta the number of bytes to be appended
61+
*/
62+
static inline void php_ini_builder_realloc(struct php_ini_builder *b, size_t delta)
63+
{
64+
/* reserve enough space for the null terminator */
65+
b->value = realloc(b->value, b->length + delta + 1);
66+
}
67+
68+
/**
69+
* Prepend a string.
70+
*
71+
* @param src the source string
72+
* @param length the size of the source string
73+
*/
74+
PHPAPI void php_ini_builder_prepend(struct php_ini_builder *b, const char *src, size_t length);
75+
76+
#define php_ini_builder_prepend_literal(b, l) php_ini_builder_prepend(b, l, strlen(l))
77+
78+
/**
79+
* Append an unquoted name/value pair.
80+
*/
81+
PHPAPI void php_ini_builder_unquoted(struct php_ini_builder *b, const char *name, size_t name_length, const char *value, size_t value_length);
82+
83+
/**
84+
* Append a quoted name/value pair.
85+
*/
86+
PHPAPI void php_ini_builder_quoted(struct php_ini_builder *b, const char *name, size_t name_length, const char *value, size_t value_length);
87+
88+
/**
89+
* Parse an INI entry from the command-line option "--define".
90+
*/
91+
PHPAPI void php_ini_builder_define(struct php_ini_builder *b, const char *arg);
92+
93+
END_EXTERN_C()
94+
95+
#endif

sapi/cgi/cgi_main.c

+9-33
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "php.h"
2323
#include "php_globals.h"
2424
#include "php_variables.h"
25+
#include "php_ini_builder.h"
2526
#include "zend_modules.h"
2627

2728
#include "SAPI.h"
@@ -1727,7 +1728,7 @@ int main(int argc, char *argv[])
17271728
int orig_optind = php_optind;
17281729
char *orig_optarg = php_optarg;
17291730
char *script_file = NULL;
1730-
size_t ini_entries_len = 0;
1731+
struct php_ini_builder ini_builder;
17311732
/* end of temporary locals */
17321733

17331734
int max_requests = 500;
@@ -1812,6 +1813,8 @@ int main(int argc, char *argv[])
18121813
free(decoded_query_string);
18131814
}
18141815

1816+
php_ini_builder_init(&ini_builder);
1817+
18151818
while (!skip_getopt && (c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
18161819
switch (c) {
18171820
case 'c':
@@ -1823,37 +1826,10 @@ int main(int argc, char *argv[])
18231826
case 'n':
18241827
cgi_sapi_module.php_ini_ignore = 1;
18251828
break;
1826-
case 'd': {
1829+
case 'd':
18271830
/* define ini entries on command line */
1828-
size_t len = strlen(php_optarg);
1829-
char *val;
1830-
1831-
if ((val = strchr(php_optarg, '='))) {
1832-
val++;
1833-
if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
1834-
cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
1835-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
1836-
ini_entries_len += (val - php_optarg);
1837-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, "\"", 1);
1838-
ini_entries_len++;
1839-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, val, len - (val - php_optarg));
1840-
ini_entries_len += len - (val - php_optarg);
1841-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
1842-
ini_entries_len += sizeof("\n\0\"") - 2;
1843-
} else {
1844-
cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\n\0"));
1845-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, len);
1846-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0"));
1847-
ini_entries_len += len + sizeof("\n\0") - 2;
1848-
}
1849-
} else {
1850-
cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("=1\n\0"));
1851-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, len);
1852-
memcpy(cgi_sapi_module.ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0"));
1853-
ini_entries_len += len + sizeof("=1\n\0") - 2;
1854-
}
1831+
php_ini_builder_define(&ini_builder, php_optarg);
18551832
break;
1856-
}
18571833
/* if we're started on command line, check to see if
18581834
* we are being started as an 'external' fastcgi
18591835
* server by accepting a bindpath parameter. */
@@ -1870,6 +1846,8 @@ int main(int argc, char *argv[])
18701846
php_optind = orig_optind;
18711847
php_optarg = orig_optarg;
18721848

1849+
cgi_sapi_module.ini_entries = php_ini_builder_finish(&ini_builder);
1850+
18731851
if (fastcgi || bindpath) {
18741852
/* Override SAPI callbacks */
18751853
cgi_sapi_module.ub_write = sapi_fcgi_ub_write;
@@ -2619,9 +2597,7 @@ consult the installation file that came with this distribution, or visit \n\
26192597
if (cgi_sapi_module.php_ini_path_override) {
26202598
free(cgi_sapi_module.php_ini_path_override);
26212599
}
2622-
if (cgi_sapi_module.ini_entries) {
2623-
free(cgi_sapi_module.ini_entries);
2624-
}
2600+
php_ini_builder_deinit(&ini_builder);
26252601
} zend_catch {
26262602
exit_status = 255;
26272603
} zend_end_try();

sapi/cli/php_cli.c

+10-45
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "php.h"
2222
#include "php_globals.h"
2323
#include "php_variables.h"
24+
#include "php_ini_builder.h"
2425
#include "zend_hash.h"
2526
#include "zend_modules.h"
2627
#include "zend_interfaces.h"
@@ -131,7 +132,7 @@ const char HARDCODED_INI[] =
131132
"implicit_flush=1\n"
132133
"output_buffering=0\n"
133134
"max_execution_time=0\n"
134-
"max_input_time=-1\n\0";
135+
"max_input_time=-1\n";
135136

136137

137138
const opt_struct OPTIONS[] = {
@@ -1176,8 +1177,7 @@ int main(int argc, char *argv[])
11761177
char *php_optarg = NULL;
11771178
int php_optind = 1, use_extended_info = 0;
11781179
char *ini_path_override = NULL;
1179-
char *ini_entries = NULL;
1180-
size_t ini_entries_len = 0;
1180+
struct php_ini_builder ini_builder;
11811181
int ini_ignore = 0;
11821182
sapi_module_struct *sapi_module = &cli_sapi_module;
11831183

@@ -1239,6 +1239,8 @@ int main(int argc, char *argv[])
12391239
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
12401240
#endif
12411241

1242+
php_ini_builder_init(&ini_builder);
1243+
12421244
while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1, 2))!=-1) {
12431245
switch (c) {
12441246
case 'c':
@@ -1250,37 +1252,10 @@ int main(int argc, char *argv[])
12501252
case 'n':
12511253
ini_ignore = 1;
12521254
break;
1253-
case 'd': {
1255+
case 'd':
12541256
/* define ini entries on command line */
1255-
size_t len = strlen(php_optarg);
1256-
char *val;
1257-
1258-
if ((val = strchr(php_optarg, '='))) {
1259-
val++;
1260-
if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
1261-
ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
1262-
memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
1263-
ini_entries_len += (val - php_optarg);
1264-
memcpy(ini_entries + ini_entries_len, "\"", 1);
1265-
ini_entries_len++;
1266-
memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg));
1267-
ini_entries_len += len - (val - php_optarg);
1268-
memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
1269-
ini_entries_len += sizeof("\n\0\"") - 2;
1270-
} else {
1271-
ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0"));
1272-
memcpy(ini_entries + ini_entries_len, php_optarg, len);
1273-
memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0"));
1274-
ini_entries_len += len + sizeof("\n\0") - 2;
1275-
}
1276-
} else {
1277-
ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0"));
1278-
memcpy(ini_entries + ini_entries_len, php_optarg, len);
1279-
memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0"));
1280-
ini_entries_len += len + sizeof("=1\n\0") - 2;
1281-
}
1257+
php_ini_builder_define(&ini_builder, php_optarg);
12821258
break;
1283-
}
12841259
#ifndef PHP_CLI_WIN32_NO_CONSOLE
12851260
case 'S':
12861261
sapi_module = &cli_server_sapi_module;
@@ -1317,18 +1292,10 @@ int main(int argc, char *argv[])
13171292
sapi_module->executable_location = argv[0];
13181293

13191294
if (sapi_module == &cli_sapi_module) {
1320-
if (ini_entries) {
1321-
ini_entries = realloc(ini_entries, ini_entries_len + sizeof(HARDCODED_INI));
1322-
memmove(ini_entries + sizeof(HARDCODED_INI) - 2, ini_entries, ini_entries_len + 1);
1323-
memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI) - 2);
1324-
} else {
1325-
ini_entries = malloc(sizeof(HARDCODED_INI));
1326-
memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
1327-
}
1328-
ini_entries_len += sizeof(HARDCODED_INI) - 2;
1295+
php_ini_builder_prepend_literal(&ini_builder, HARDCODED_INI);
13291296
}
13301297

1331-
sapi_module->ini_entries = ini_entries;
1298+
sapi_module->ini_entries = php_ini_builder_finish(&ini_builder);
13321299

13331300
/* startup after we get the above ini override se we get things right */
13341301
if (sapi_module->startup(sapi_module) == FAILURE) {
@@ -1375,9 +1342,7 @@ int main(int argc, char *argv[])
13751342
if (ini_path_override) {
13761343
free(ini_path_override);
13771344
}
1378-
if (ini_entries) {
1379-
free(ini_entries);
1380-
}
1345+
php_ini_builder_deinit(&ini_builder);
13811346
if (module_started) {
13821347
php_module_shutdown();
13831348
}

0 commit comments

Comments
 (0)