31#define O_RDONLY _O_RDONLY
48#ifdef HAVE_SYS_SOCKET_H
49#include <sys/socket.h>
55#include <netinet/in.h>
57#ifdef HAVE_ARPA_INET_H
62#if defined(PHP_WIN32) || defined(__riscos__)
80 if (
PG(open_basedir_modified)) {
85 PG(open_basedir_modified) =
false;
90 if (!new_value || !*
ZSTR_VAL(new_value)) {
106 smart_str_free(&
buf);
112 smart_str_free(&
buf);
115 if (smart_str_get_len(&
buf) != 0) {
118 smart_str_appends(&
buf, resolved_name);
126 if (
PG(open_basedir_modified)) {
130 PG(open_basedir_modified) =
true;
131 zend_string_release(tmp);
149 size_t resolved_basedir_len;
150 size_t resolved_name_len;
152 int nesting_level = 0;
157 strlcpy(local_open_basedir, basedir,
sizeof(local_open_basedir));
171 path_len =
strlen(resolved_name);
172 memcpy(path_tmp, resolved_name, path_len + 1);
175#if defined(PHP_WIN32) || defined(HAVE_SYMLINK)
176 if (nesting_level == 0) {
186 path_tmp[
ret] =
'\0';
194 path_file =
strrchr(path_tmp,
'/');
203 path_len = path_file - path_tmp + 1;
205 if (path_len > 1 && path_tmp[path_len - 2] ==
':') {
210 path_tmp[path_len] =
'\0';
212 path_tmp[path_len - 1] =
'\0';
215 path_tmp[path_len - 1] =
'\0';
218 if (*path_tmp ==
'\0') {
227 size_t basedir_len =
strlen(basedir);
229 resolved_basedir_len =
strlen(resolved_basedir);
231 if (basedir[basedir_len - 1] ==
PHP_DIR_SEPARATOR || basedir[basedir_len - 1] ==
'/') {
237 resolved_basedir[++resolved_basedir_len] =
'\0';
241 resolved_basedir[resolved_basedir_len] =
'\0';
244 resolved_name_len =
strlen(resolved_name);
248 resolved_name[++resolved_name_len] =
'\0';
254 if (
strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
256 if (
strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
258 if (resolved_name_len > resolved_basedir_len &&
267 if (resolved_basedir_len == (resolved_name_len + 1) && resolved_basedir[resolved_basedir_len - 1] ==
PHP_DIR_SEPARATOR) {
269 if (
strncasecmp(resolved_basedir, resolved_name, resolved_name_len) == 0) {
271 if (
strncmp(resolved_basedir, resolved_name, resolved_name_len) == 0) {
294 if (
PG(open_basedir) && *
PG(open_basedir)) {
339static FILE *php_fopen_and_set_opened_path(
const char *path,
const char *
mode,
zend_string **opened_path)
347 if (fp && opened_path) {
351 *opened_path = zend_string_init(tmp,
strlen(tmp), 0);
366 bool orig_display_errors;
370 path_info =
SG(request_info).request_uri;
372 if (
PG(user_dir) && *
PG(user_dir) && path_info &&
'/' == path_info[0] &&
'~' == path_info[1]) {
373 char *
s =
strchr(path_info + 2,
'/');
378 length =
s - (path_info + 2);
379 if (length >
sizeof(user) - 1) {
380 length =
sizeof(user) - 1;
382 memcpy(user, path_info + 2, length);
386#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
387 struct passwd pwstruc;
388 long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
402 err = getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw);
415 if (pw && pw->pw_dir) {
417 }
else if (
SG(request_info).path_translated) {
418 filename = zend_string_init(
SG(request_info).path_translated,
419 strlen(
SG(request_info).path_translated), 0);
421#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
427 if (
PG(doc_root) && path_info && (length =
strlen(
PG(doc_root))) &&
429 size_t path_len =
strlen(path_info);
430 filename = zend_string_alloc(length + path_len + 2, 0);
438 strncpy(
ZSTR_VAL(filename) + length, path_info, path_len + 1);
439 ZSTR_LEN(filename) = length + path_len;
440 }
else if (
SG(request_info).path_translated) {
441 filename = zend_string_init(
SG(request_info).path_translated,
442 strlen(
SG(request_info).path_translated), 0);
450 if (!resolved_path) {
452 zend_string_release(filename);
458 if (
SG(request_info).path_translated) {
459 efree(
SG(request_info).path_translated);
460 SG(request_info).path_translated =
NULL;
466 orig_display_errors =
PG(display_errors);
467 PG(display_errors) = 0;
471 zend_string_delref(filename);
474 PG(display_errors) = orig_display_errors;
475 if (
SG(request_info).path_translated) {
476 efree(
SG(request_info).path_translated);
477 SG(request_info).path_translated =
NULL;
481 PG(display_errors) = orig_display_errors;
487static zend_string *tsrm_realpath_str(
const char *path) {
505 const char *actual_path;
514 for (
p = filename; isalnum((
int)*
p) || *
p ==
'+' || *
p ==
'-' || *
p ==
'.';
p++);
515 if ((*
p ==
':') && (
p - filename > 1) && (
p[1] ==
'/') && (
p[2] ==
'/')) {
518 if ((resolved_path = tsrm_realpath_str(actual_path))) {
519 return resolved_path;
525 if ((*filename ==
'.' &&
527 ((filename[1] ==
'.') &&
IS_SLASH(filename[2])))) ||
538 return tsrm_realpath_str(filename);
544 int is_stream_wrapper = 0;
546 for (
p =
ptr; isalnum((
int)*
p) || *
p ==
'+' || *
p ==
'-' || *
p ==
'.';
p++);
547 if ((*
p ==
':') && (
p -
ptr > 1) && (
p[1] ==
'/') && (
p[2] ==
'/')) {
549 if (
p[-1] !=
'.' ||
p[-2] !=
'.' ||
p - 2 !=
ptr) {
551 is_stream_wrapper = 1;
562 memcpy(trypath+(
end-
ptr)+1, filename, filename_length+1);
572 memcpy(trypath+
len+1, filename, filename_length+1);
575 actual_path = trypath;
576 if (is_stream_wrapper) {
585 return zend_string_init(trypath,
strlen(trypath), 0);
594 if ((resolved_path = tsrm_realpath_str(actual_path))) {
595 return resolved_path;
603 const char *exec_fname =
ZSTR_VAL(exec_filename);
604 size_t exec_fname_length =
ZSTR_LEN(exec_filename);
606 while (exec_fname_length > 0) {
608 if (
IS_SLASH(exec_fname[exec_fname_length])) {
613 if (exec_fname_length > 0 &&
615 exec_fname_length + 1 + filename_length + 1 <
MAXPATHLEN) {
616 memcpy(trypath, exec_fname, exec_fname_length + 1);
617 memcpy(trypath+exec_fname_length + 1, filename, filename_length+1);
618 actual_path = trypath;
621 for (
p = trypath; isalnum((
int)*
p) || *
p ==
'+' || *
p ==
'-' || *
p ==
'.';
p++);
622 if ((*
p ==
':') && (
p - trypath > 1) && (
p[1] ==
'/') && (
p[2] ==
'/')) {
631 return zend_string_init(trypath,
strlen(trypath), 0);
641 return tsrm_realpath_str(actual_path);
655 char *pathbuf, *
ptr, *
end;
658 size_t filename_length;
669 filename_length =
strlen(filename);
671 (
void) filename_length;
675 if ((*filename ==
'.')
680 return php_fopen_and_set_opened_path(filename,
mode, opened_path);
689 const char *exec_fname =
ZSTR_VAL(exec_filename);
690 size_t exec_fname_length =
ZSTR_LEN(exec_filename);
692 while ((--exec_fname_length <
SIZE_MAX) && !
IS_SLASH(exec_fname[exec_fname_length]));
693 if ((exec_fname && exec_fname[0] ==
'[') || exec_fname_length <= 0) {
697 size_t path_length =
strlen(path);
699 pathbuf = (
char *)
emalloc(exec_fname_length + path_length + 1 + 1);
700 memcpy(pathbuf, path, path_length);
702 memcpy(pathbuf + path_length + 1, exec_fname, exec_fname_length);
703 pathbuf[path_length + exec_fname_length + 1] =
'\0';
720 fp = php_fopen_and_set_opened_path(trypath,
mode, opened_path);
745 if (*
p ==
':' && *(
p + 1) ==
'/' && *(
p + 2) ==
'/') {
747 url_start =
p =
p + 3;
753 for (i = 0; i < 3 && url_start <
p; i++, url_start++) {
798 path_len =
strlen(filepath);
803 const char *iam =
SG(request_info).path_translated;
810 memcpy(
cwd, relative_to, relative_to_len+1U);
815 if (!
result && (iam != filepath)) {
825 memcpy(real_path, filepath, copy_len);
826 real_path[copy_len] =
'\0';
828 real_path =
estrndup(filepath, copy_len);
850 memcpy(real_path, new_state.
cwd, copy_len);
851 real_path[copy_len] =
'\0';
strrchr(string $haystack, string $needle, bool $before_needle=false)
strchr(string $haystack, string $needle, bool $before_needle=false)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
PHPAPI zend_string * php_resolve_path(const char *filename, size_t filename_length, const char *path)
PHPAPI char * php_strip_url_passwd(char *url)
PHPAPI char * expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode)
PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
PHPAPI int php_check_open_basedir(const char *path)
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
PHPAPI int php_check_open_basedir_ex(const char *path, int warn)
PHPAPI FILE * php_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path)
PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path)
PHPAPI char * expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
#define PHP_DIR_SEPARATOR
unsigned const char * end
#define PHP_INI_STAGE_ACTIVATE
#define PHP_INI_STAGE_DEACTIVATE
#define PHP_INI_STAGE_SHUTDOWN
#define PHP_INI_STAGE_STARTUP
PHPAPI php_stream_wrapper php_plain_files_wrapper
#define STREAM_OPEN_FOR_INCLUDE
struct _php_stream_wrapper php_stream_wrapper
PHPAPI php_stream_wrapper * php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options)
#define PHP_STREAM_URL_STAT_QUIET
struct _php_stream_statbuf php_stream_statbuf
int(* url_stat)(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context)
const php_stream_wrapper_ops * wops
ZEND_API zend_string * zend_strpprintf(size_t max_len, const char *format,...)
ZEND_API zend_string *(* zend_resolve_path)(zend_string *filename)
#define CHECK_NULL_PATH(p, l)
#define estrndup(s, length)
#define erealloc(ptr, size)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
#define strncasecmp(s1, s2, n)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API zend_string * zend_get_executed_filename_ex(void)
ZEND_API bool zend_is_executing(void)
#define ZEND_INI_MH(name)
#define ZEND_INI_GET_ADDR()
struct _zend_file_handle zend_file_handle
struct _zend_string zend_string
ZEND_API void zend_stream_init_filename_ex(zend_file_handle *handle, zend_string *filename)
ZEND_API zend_result zend_stream_open(zend_file_handle *handle)
CWD_API char * tsrm_realpath(const char *path, char *real_path)
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath)
#define VCWD_FOPEN(path, mode)
#define IS_ABSOLUTE_PATH(path, len)
#define DEFAULT_DIR_SEPARATOR
#define VCWD_OPEN(path, flags)
#define VCWD_GETCWD(buff, size)
struct _cwd_state cwd_state
#define VCWD_REALPATH(path, real_path)