From: Greg Beaver Date: Mon, 24 Mar 2008 01:33:30 +0000 (+0000) Subject: check for invalid aliases, add tests for this and direct setting of stub/alias X-Git-Tag: RELEASE_2_0_0a1~19 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4b890cb8f74ccb1728712b675fc2099a789da82;p=php check for invalid aliases, add tests for this and direct setting of stub/alias --- diff --git a/ext/phar/TODO b/ext/phar/TODO index 92fdffef3a..9f38b059c9 100644 --- a/ext/phar/TODO +++ b/ext/phar/TODO @@ -67,7 +67,7 @@ Version 2.0.0 access, or a string representing a file within the archive to access. If unknown, the callback should return the original request uri [Greg] * rework filename detection so that alias is always checked first - * make aliases containing '/' or '\' invalid + X make aliases containing '/' or '\' invalid [Greg] X implement manual mounting of external phar archives to locations inside a phar path, $phar->mount('/path/to/external.phar', 'internal/path'); this would traverse external.phar's manifest, and add each entry as a diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 369fab3d87..384b5b2b0b 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -361,6 +361,16 @@ static inline void phar_unixify_path_separators(char *path, int path_len) } } #endif +/** + * validate an alias, returns 1 for success, 0 for failure + */ +static inline int phar_validate_alias(const char *alias, int alias_len) /* {{{ */ +{ + return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) || + memchr(alias, ';', alias_len)); +} +/* }}} */ + void phar_request_initialize(TSRMLS_D); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 3c99e699b8..a6ae41af4e 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2177,13 +2177,13 @@ PHP_METHOD(Phar, setAlias) if (PHAR_G(readonly)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Cannot write out phar archive, phar is read-only"); - return; + RETURN_FALSE; } if (phar_obj->arc.archive->is_data) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "A Phar alias cannot be set in a plain %s archive", phar_obj->arc.archive->is_tar ? "tar" : "zip"); - return; + RETURN_FALSE; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &alias, &alias_len) == SUCCESS) { @@ -2196,6 +2196,11 @@ PHP_METHOD(Phar, setAlias) efree(error); RETURN_FALSE; } + if (!phar_validate_alias(alias, alias_len)) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, + "Invalid alias \"%s\" specified for phar \"%s\"", alias, phar_obj->arc.archive->fname); + RETURN_FALSE; + } if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) { zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len); readd = 1; @@ -2222,7 +2227,7 @@ PHP_METHOD(Phar, setAlias) zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL); } efree(error); - return; + RETURN_FALSE; } zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL); if (oldalias) { diff --git a/ext/phar/tests/invalid_alias.phpt b/ext/phar/tests/invalid_alias.phpt new file mode 100644 index 0000000000..dc0c71ed11 --- /dev/null +++ b/ext/phar/tests/invalid_alias.phpt @@ -0,0 +1,45 @@ +--TEST-- +Phar: set alias with invalid alias containing / \ : or ; +--SKIPIF-- + +--INI-- +phar.readonly=0 +--FILE-- +setAlias('hi/'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + $p->setAlias('hi\\l'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + $p->setAlias('hil;'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + $p->setAlias(':hil'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Invalid alias "hi/" specified for phar "%sinvalid_alias.phar" +Invalid alias "hi\l" specified for phar "%sinvalid_alias.phar" +Invalid alias "hil;" specified for phar "%sinvalid_alias.phar" +Invalid alias ":hil" specified for phar "%sinvalid_alias.phar" +===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/invalid_setstubalias.phpt b/ext/phar/tests/invalid_setstubalias.phpt new file mode 100644 index 0000000000..04cb779ddb --- /dev/null +++ b/ext/phar/tests/invalid_setstubalias.phpt @@ -0,0 +1,47 @@ +--TEST-- +Phar: invalid set alias or stub via array access +--SKIPIF-- + +--INI-- +phar.readonly=0 +--FILE-- +getMessage() . "\n"; +} +try { + $p['.phar/alias.txt'] = 'hi'; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +$p = new Phar($fname2); +try { + $p['.phar/stub.php'] = 'hi'; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + $p['.phar/alias.txt'] = 'hi'; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Cannot set stub ".phar/stub.php" directly in phar "%sinvalid_setstubalias.phar.tar", use setStub +Cannot set alias ".phar/alias.txt" directly in phar "%sinvalid_setstubalias.phar.tar", use setAlias +Cannot set stub ".phar/stub.php" directly in phar "%sinvalid_setstubalias.phar.zip", use setStub +Cannot set alias ".phar/alias.txt" directly in phar "%sinvalid_setstubalias.phar.zip", use setAlias +===DONE=== \ No newline at end of file