Skip to content

Commit

Permalink
sapi/*: move duplicate "--define" code to library
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxKellermann authored and iluuu1994 committed Apr 18, 2022
1 parent 462dc9d commit d87ba95
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 168 deletions.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ PHP_ADD_SOURCES(TSRM, TSRM.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)

PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \
fopen_wrappers.c alloca.c php_scandir.c \
php_ini_builder.c \
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \
network.c php_open_temporary_file.c \
Expand Down
82 changes: 82 additions & 0 deletions main/php_ini_builder.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Max Kellermann <[email protected]> |
+----------------------------------------------------------------------+
*/

#include "php_ini_builder.h"

#include <ctype.h>
#include <string.h>

PHPAPI void php_ini_builder_prepend(struct php_ini_builder *b, const char *src, size_t length)
{
php_ini_builder_realloc(b, length);
if (b->length > 0)
memmove(b->value + length, b->value, b->length);
memcpy(b->value, src, length);
b->length += length;
}

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)
{
php_ini_builder_realloc(b, name_length + 1 + value_length + 1);

memcpy(b->value + b->length, name, name_length);
b->length += name_length;

b->value[b->length++] = '=';

memcpy(b->value + b->length, value, value_length);
b->length += value_length;

b->value[b->length++] = '\n';
}

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)
{
php_ini_builder_realloc(b, name_length + 2 + value_length + 2);

memcpy(b->value + b->length, name, name_length);
b->length += name_length;

b->value[b->length++] = '=';
b->value[b->length++] = '"';

memcpy(b->value + b->length, value, value_length);
b->length += value_length;

b->value[b->length++] = '"';
b->value[b->length++] = '\n';
}

PHPAPI void php_ini_builder_define(struct php_ini_builder *b, const char *arg)
{
const size_t len = strlen(arg);
const char *val = strchr(arg, '=');

if (val != NULL) {
val++;
if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
php_ini_builder_quoted(b, arg, val - arg - 1, val, arg + len - val);
} else {
php_ini_builder_realloc(b, len + strlen("\n"));
memcpy(b->value + b->length, arg, len);
b->length += len;
b->value[b->length++] = '\n';
}
} else {
php_ini_builder_unquoted(b, arg, len, "1", 1);
}
}

95 changes: 95 additions & 0 deletions main/php_ini_builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Max Kellermann <[email protected]> |
+----------------------------------------------------------------------+
*/

#ifndef PHP_INI_BUILDER_H
#define PHP_INI_BUILDER_H

#include "php.h"

/**
* A class which helps with constructing INI entries from the command
* line.
*/
struct php_ini_builder {
char *value;
size_t length;
};

BEGIN_EXTERN_C()

static inline void php_ini_builder_init(struct php_ini_builder *b)
{
b->value = NULL;
b->length = 0;
}

static inline void php_ini_builder_deinit(struct php_ini_builder *b)
{
free(b->value);
}

/**
* Null-terminate the buffer and return it.
*/
static inline char *php_ini_builder_finish(struct php_ini_builder *b)
{
if (b->value != NULL) {
/* null-terminate the string */
b->value[b->length] = '\0';
}

return b->value;
}

/**
* Make room for more data.
*
* @param delta the number of bytes to be appended
*/
static inline void php_ini_builder_realloc(struct php_ini_builder *b, size_t delta)
{
/* reserve enough space for the null terminator */
b->value = realloc(b->value, b->length + delta + 1);
}

/**
* Prepend a string.
*
* @param src the source string
* @param length the size of the source string
*/
PHPAPI void php_ini_builder_prepend(struct php_ini_builder *b, const char *src, size_t length);

#define php_ini_builder_prepend_literal(b, l) php_ini_builder_prepend(b, l, strlen(l))

/**
* Append an unquoted name/value pair.
*/
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);

/**
* Append a quoted name/value pair.
*/
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);

/**
* Parse an INI entry from the command-line option "--define".
*/
PHPAPI void php_ini_builder_define(struct php_ini_builder *b, const char *arg);

END_EXTERN_C()

#endif
42 changes: 9 additions & 33 deletions sapi/cgi/cgi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "php.h"
#include "php_globals.h"
#include "php_variables.h"
#include "php_ini_builder.h"
#include "zend_modules.h"

#include "SAPI.h"
Expand Down Expand Up @@ -1727,7 +1728,7 @@ int main(int argc, char *argv[])
int orig_optind = php_optind;
char *orig_optarg = php_optarg;
char *script_file = NULL;
size_t ini_entries_len = 0;
struct php_ini_builder ini_builder;
/* end of temporary locals */

int max_requests = 500;
Expand Down Expand Up @@ -1812,6 +1813,8 @@ int main(int argc, char *argv[])
free(decoded_query_string);
}

php_ini_builder_init(&ini_builder);

while (!skip_getopt && (c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
switch (c) {
case 'c':
Expand All @@ -1823,37 +1826,10 @@ int main(int argc, char *argv[])
case 'n':
cgi_sapi_module.php_ini_ignore = 1;
break;
case 'd': {
case 'd':
/* define ini entries on command line */
size_t len = strlen(php_optarg);
char *val;

if ((val = strchr(php_optarg, '='))) {
val++;
if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
ini_entries_len += (val - php_optarg);
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, "\"", 1);
ini_entries_len++;
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, val, len - (val - php_optarg));
ini_entries_len += len - (val - php_optarg);
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
ini_entries_len += sizeof("\n\0\"") - 2;
} else {
cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\n\0"));
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, len);
memcpy(cgi_sapi_module.ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0"));
ini_entries_len += len + sizeof("\n\0") - 2;
}
} else {
cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("=1\n\0"));
memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, len);
memcpy(cgi_sapi_module.ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0"));
ini_entries_len += len + sizeof("=1\n\0") - 2;
}
php_ini_builder_define(&ini_builder, php_optarg);
break;
}
/* if we're started on command line, check to see if
* we are being started as an 'external' fastcgi
* server by accepting a bindpath parameter. */
Expand All @@ -1870,6 +1846,8 @@ int main(int argc, char *argv[])
php_optind = orig_optind;
php_optarg = orig_optarg;

cgi_sapi_module.ini_entries = php_ini_builder_finish(&ini_builder);

if (fastcgi || bindpath) {
/* Override SAPI callbacks */
cgi_sapi_module.ub_write = sapi_fcgi_ub_write;
Expand Down Expand Up @@ -2619,9 +2597,7 @@ consult the installation file that came with this distribution, or visit \n\
if (cgi_sapi_module.php_ini_path_override) {
free(cgi_sapi_module.php_ini_path_override);
}
if (cgi_sapi_module.ini_entries) {
free(cgi_sapi_module.ini_entries);
}
php_ini_builder_deinit(&ini_builder);
} zend_catch {
exit_status = 255;
} zend_end_try();
Expand Down
55 changes: 10 additions & 45 deletions sapi/cli/php_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "php.h"
#include "php_globals.h"
#include "php_variables.h"
#include "php_ini_builder.h"
#include "zend_hash.h"
#include "zend_modules.h"
#include "zend_interfaces.h"
Expand Down Expand Up @@ -131,7 +132,7 @@ const char HARDCODED_INI[] =
"implicit_flush=1\n"
"output_buffering=0\n"
"max_execution_time=0\n"
"max_input_time=-1\n\0";
"max_input_time=-1\n";


const opt_struct OPTIONS[] = {
Expand Down Expand Up @@ -1176,8 +1177,7 @@ int main(int argc, char *argv[])
char *php_optarg = NULL;
int php_optind = 1, use_extended_info = 0;
char *ini_path_override = NULL;
char *ini_entries = NULL;
size_t ini_entries_len = 0;
struct php_ini_builder ini_builder;
int ini_ignore = 0;
sapi_module_struct *sapi_module = &cli_sapi_module;

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

php_ini_builder_init(&ini_builder);

while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1, 2))!=-1) {
switch (c) {
case 'c':
Expand All @@ -1250,37 +1252,10 @@ int main(int argc, char *argv[])
case 'n':
ini_ignore = 1;
break;
case 'd': {
case 'd':
/* define ini entries on command line */
size_t len = strlen(php_optarg);
char *val;

if ((val = strchr(php_optarg, '='))) {
val++;
if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
ini_entries_len += (val - php_optarg);
memcpy(ini_entries + ini_entries_len, "\"", 1);
ini_entries_len++;
memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg));
ini_entries_len += len - (val - php_optarg);
memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
ini_entries_len += sizeof("\n\0\"") - 2;
} else {
ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0"));
memcpy(ini_entries + ini_entries_len, php_optarg, len);
memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0"));
ini_entries_len += len + sizeof("\n\0") - 2;
}
} else {
ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0"));
memcpy(ini_entries + ini_entries_len, php_optarg, len);
memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0"));
ini_entries_len += len + sizeof("=1\n\0") - 2;
}
php_ini_builder_define(&ini_builder, php_optarg);
break;
}
#ifndef PHP_CLI_WIN32_NO_CONSOLE
case 'S':
sapi_module = &cli_server_sapi_module;
Expand Down Expand Up @@ -1317,18 +1292,10 @@ int main(int argc, char *argv[])
sapi_module->executable_location = argv[0];

if (sapi_module == &cli_sapi_module) {
if (ini_entries) {
ini_entries = realloc(ini_entries, ini_entries_len + sizeof(HARDCODED_INI));
memmove(ini_entries + sizeof(HARDCODED_INI) - 2, ini_entries, ini_entries_len + 1);
memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI) - 2);
} else {
ini_entries = malloc(sizeof(HARDCODED_INI));
memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
}
ini_entries_len += sizeof(HARDCODED_INI) - 2;
php_ini_builder_prepend_literal(&ini_builder, HARDCODED_INI);
}

sapi_module->ini_entries = ini_entries;
sapi_module->ini_entries = php_ini_builder_finish(&ini_builder);

/* startup after we get the above ini override se we get things right */
if (sapi_module->startup(sapi_module) == FAILURE) {
Expand Down Expand Up @@ -1375,9 +1342,7 @@ int main(int argc, char *argv[])
if (ini_path_override) {
free(ini_path_override);
}
if (ini_entries) {
free(ini_entries);
}
php_ini_builder_deinit(&ini_builder);
if (module_started) {
php_module_shutdown();
}
Expand Down
Loading

0 comments on commit d87ba95

Please sign in to comment.