Skip to content

Commit df1ebd6

Browse files
committed
main: convert doc_root global to zend_string*
This remove a strlen() computation. While at it clarify path concatenation code by using the zend_string_concat{2|3} APIs rather than a memcpy and strncpy calls
1 parent f8c4bbe commit df1ebd6

5 files changed

Lines changed: 36 additions & 19 deletions

File tree

main/fopen_wrappers.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
359359
char *path_info;
360360
zend_string *filename = NULL;
361361
zend_string *resolved_path = NULL;
362-
size_t length;
363362
bool orig_display_errors;
364363

365364
memset(file_handle, 0, sizeof(zend_file_handle));
@@ -372,7 +371,7 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
372371
if (s) { /* if there is no path name after the file, do not bother */
373372
char user[32]; /* to try open the directory */
374373

375-
length = s - (path_info + 2);
374+
size_t length = s - (path_info + 2);
376375
if (length > sizeof(user) - 1) {
377376
length = sizeof(user) - 1;
378377
}
@@ -421,19 +420,37 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
421420
}
422421
} else
423422
#endif
424-
if (PG(doc_root) && path_info && (length = strlen(PG(doc_root))) &&
425-
IS_ABSOLUTE_PATH(PG(doc_root), length)) {
426-
size_t path_len = strlen(path_info);
427-
filename = zend_string_alloc(length + path_len + 2, 0);
428-
memcpy(ZSTR_VAL(filename), PG(doc_root), length);
429-
if (!IS_SLASH(ZSTR_VAL(filename)[length - 1])) { /* length is never 0 */
430-
ZSTR_VAL(filename)[length++] = PHP_DIR_SEPARATOR;
431-
}
432-
if (IS_SLASH(path_info[0])) {
433-
length--;
434-
}
435-
strncpy(ZSTR_VAL(filename) + length, path_info, path_len + 1);
436-
ZSTR_LEN(filename) = length + path_len;
423+
if (PG(doc_root) && path_info && IS_ABSOLUTE_PATH(ZSTR_VAL(PG(doc_root)), ZSTR_LEN(PG(doc_root)))) {
424+
const size_t path_len = strlen(path_info);
425+
426+
/* We need to concatenate two paths together, there are 3 situations:
427+
* - No trailing slash AND no leading slash
428+
* - Trailing slash AND leading slash
429+
* - Either a trailing slash OR a leading slash
430+
* In the first case we need to add a slash, in the second one we need to skip the leading slash,
431+
* and in the third we can just concatenate them together */
432+
const unsigned int nb_slashes = IS_SLASH(ZSTR_VAL(PG(doc_root))[ZSTR_LEN(PG(doc_root)) - 1]) + IS_SLASH(path_info[0]);
433+
switch (nb_slashes) {
434+
case 0:
435+
filename = zend_string_concat3(
436+
ZSTR_VAL(PG(doc_root)), ZSTR_LEN(PG(doc_root)),
437+
ZEND_STRL("/"),
438+
path_info, path_len
439+
);
440+
break;
441+
case 1:
442+
filename = zend_string_concat2(
443+
ZSTR_VAL(PG(doc_root)), ZSTR_LEN(PG(doc_root)),
444+
path_info, path_len
445+
);
446+
break;
447+
case 2:
448+
filename = zend_string_concat2(
449+
ZSTR_VAL(PG(doc_root)), ZSTR_LEN(PG(doc_root)),
450+
path_info + 1, path_len -1
451+
);
452+
break;
453+
}
437454
} else if (SG(request_info).path_translated) {
438455
filename = zend_string_init(SG(request_info).path_translated,
439456
strlen(SG(request_info).path_translated), 0);

main/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ PHP_INI_BEGIN()
830830

831831
STD_PHP_INI_ENTRY("auto_append_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_append_file, php_core_globals, core_globals)
832832
STD_PHP_INI_ENTRY("auto_prepend_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_prepend_file, php_core_globals, core_globals)
833-
STD_PHP_INI_ENTRY("doc_root", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, doc_root, php_core_globals, core_globals)
833+
STD_PHP_INI_ENTRY("doc_root", NULL, PHP_INI_SYSTEM, OnUpdateStrNotEmpty, doc_root, php_core_globals, core_globals)
834834
STD_PHP_INI_ENTRY("default_charset", PHP_DEFAULT_CHARSET, PHP_INI_ALL, OnUpdateDefaultCharset, default_charset, sapi_globals_struct, sapi_globals)
835835
STD_PHP_INI_ENTRY("default_mimetype", SAPI_DEFAULT_MIMETYPE, PHP_INI_ALL, OnUpdateDefaultMimeTye, default_mimetype, sapi_globals_struct, sapi_globals)
836836
STD_PHP_INI_ENTRY("internal_encoding", NULL, PHP_INI_ALL, OnUpdateInternalEncoding, internal_encoding, php_core_globals, core_globals)

main/php_globals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ struct _php_core_globals {
7676

7777
char *error_log;
7878

79-
char *doc_root;
79+
zend_string *doc_root;
8080
char *user_dir;
8181
char *include_path;
8282
char *open_basedir;

sapi/cgi/cgi_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ static void init_request_info(fcgi_request *request)
12211221
size_t script_path_translated_len;
12221222

12231223
if (!env_document_root && PG(doc_root)) {
1224-
env_document_root = CGI_PUTENV("DOCUMENT_ROOT", PG(doc_root));
1224+
env_document_root = CGI_PUTENV("DOCUMENT_ROOT", ZSTR_VAL(PG(doc_root)));
12251225
/* fix docroot */
12261226
TRANSLATE_SLASHES(env_document_root);
12271227
}

sapi/fpm/fpm/fpm_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ static void init_request_info(void)
10831083
int script_path_translated_len;
10841084

10851085
if (!env_document_root && PG(doc_root)) {
1086-
env_document_root = FCGI_PUTENV(request, "DOCUMENT_ROOT", PG(doc_root));
1086+
env_document_root = FCGI_PUTENV(request, "DOCUMENT_ROOT", ZSTR_VAL(PG(doc_root)));
10871087
}
10881088

10891089
if (!apache_was_here && env_path_translated != NULL && env_redirect_url != NULL &&

0 commit comments

Comments
 (0)