diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 82c7c376edd..cba0ded88ed 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1405,6 +1405,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ zend_class_entry *ce = p_obj->c; phar_archive_object *phar_obj = p_obj->p; php_stream_statbuf ssb; + char ch; value = iter->funcs->get_current_data(iter); @@ -1528,7 +1529,7 @@ phar_spl_fileinfo: base = temp; base_len = strlen(base); - if (strstr(fname, base)) { + if (fname_len >= base_len && strncmp(fname, base, base_len) == 0 && ((ch = fname[base_len - IS_SLASH(base[base_len - 1])]) == '\0' || IS_SLASH(ch))) { str_key_len = fname_len - base_len; if (str_key_len <= 0) { diff --git a/ext/phar/tests/bug81211.phpt b/ext/phar/tests/bug81211.phpt new file mode 100644 index 00000000000..43d82143f2b --- /dev/null +++ b/ext/phar/tests/bug81211.phpt @@ -0,0 +1,45 @@ +--TEST-- +Bug #81211 (Symlinks are followed when creating PHAR archive) +--SKIPIF-- + +--FILE-- +buildFromDirectory(__DIR__ . '/bug81211/foo'); +} catch (UnexpectedValueException $ex) { + echo $ex->getMessage(), PHP_EOL; +} +try { + $archive->buildFromIterator(new RecursiveDirectoryIterator(__DIR__ . '/bug81211/foo', FilesystemIterator::SKIP_DOTS), __DIR__ . '/bug81211/foo'); +} catch (UnexpectedValueException $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--CLEAN-- + +--EXPECTF-- +Iterator RecursiveIteratorIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo" +Iterator RecursiveDirectoryIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo" diff --git a/ext/standard/tests/file/windows_links/common.inc b/ext/standard/tests/file/windows_links/common.inc index 505368b8b02..caa3758d442 100644 --- a/ext/standard/tests/file/windows_links/common.inc +++ b/ext/standard/tests/file/windows_links/common.inc @@ -20,4 +20,11 @@ function get_mountvol() { return "$sysroot\\System32\\mountvol.exe"; } -?> +function skipIfSeCreateSymbolicLinkPrivilegeIsDisabled(string $filename) { + $ln = "$filename.lnk"; + $ret = exec("mklink $ln " . __FILE__ .' 2>&1', $out); + @unlink($ln); + if (strpos($ret, 'privilege') !== false) { + die('skip SeCreateSymbolicLinkPrivilege not enabled'); + } +}