Skip to content

Allow utf-8 filename in phar - fixes 64498 #588

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
168 changes: 115 additions & 53 deletions ext/phar/phar_path_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,60 +46,69 @@ phar_path_check_result phar_path_check(char **s, int *len, const char **error)
#line 47 "ext/phar/phar_path_check.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;

if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
yych = *YYCURSOR;
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= 0x00) goto yy13;
if (yych <= '\t') goto yy10;
goto yy12;
if (yych <= '>') {
if (yych <= 0x19) {
if (yych <= 0x00) goto yy16;
if (yych == '\n') goto yy15;
goto yy14;
} else {
if (yych <= 0x19) goto yy10;
if (yych == '*') goto yy6;
goto yy15;
if (yych <= '*') {
if (yych <= ')') goto yy18;
goto yy6;
} else {
if (yych != '/') goto yy18;
}
}
} else {
if (yych <= '?') {
if (yych <= '/') goto yy2;
if (yych <= '>') goto yy15;
goto yy8;
} else {
if (yych <= 0x7F) {
if (yych <= '?') goto yy8;
if (yych == '\\') goto yy4;
if (yych <= 0x7F) goto yy15;
goto yy10;
goto yy18;
} else {
if (yych <= 0xDF) {
if (yych <= 0xBF) goto yy14;
goto yy10;
} else {
if (yych <= 0xEF) goto yy12;
if (yych <= 0xF7) goto yy13;
goto yy14;
}
}
}
yy2:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '-') goto yy3;
if (yych <= '.') goto yy16;
if (yych <= '/') goto yy18;
if (yych <= '.') goto yy29;
if (yych <= '/') goto yy30;
yy3:
#line 93 "ext/phar/phar_path_check.re"
#line 105 "ext/phar/phar_path_check.re"
{
goto loop;
}
#line 84 "ext/phar/phar_path_check.c"
#line 93 "ext/phar/phar_path_check.c"
yy4:
++YYCURSOR;
#line 60 "ext/phar/phar_path_check.re"
#line 63 "ext/phar/phar_path_check.re"
{
*error = "back-slash";
return pcr_err_back_slash;
}
#line 92 "ext/phar/phar_path_check.c"
#line 101 "ext/phar/phar_path_check.c"
yy6:
++YYCURSOR;
#line 64 "ext/phar/phar_path_check.re"
#line 67 "ext/phar/phar_path_check.re"
{
*error = "star";
return pcr_err_star;
}
#line 100 "ext/phar/phar_path_check.c"
#line 109 "ext/phar/phar_path_check.c"
yy8:
++YYCURSOR;
#line 68 "ext/phar/phar_path_check.re"
#line 71 "ext/phar/phar_path_check.re"
{
if (**s == '/') {
(*s)++;
Expand All @@ -108,22 +117,39 @@ phar_path_check_result phar_path_check(char **s, int *len, const char **error)
*error = NULL;
return pcr_use_query;
}
#line 112 "ext/phar/phar_path_check.c"
#line 121 "ext/phar/phar_path_check.c"
yy10:
++YYCURSOR;
if ((yych = *YYCURSOR) <= 0x7F) goto yy11;
if (yych <= 0xBF) goto yy27;
yy11:
#line 76 "ext/phar/phar_path_check.re"
#line 88 "ext/phar/phar_path_check.re"
{
*error ="illegal character";
return pcr_err_illegal_char;
}
#line 121 "ext/phar/phar_path_check.c"
#line 132 "ext/phar/phar_path_check.c"
yy12:
yych = *++YYCURSOR;
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= 0x7F) goto yy11;
if (yych <= 0xBF) goto yy24;
goto yy11;
yy13:
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= 0x7F) goto yy11;
if (yych <= 0xBF) goto yy19;
goto yy11;
yy14:
yych = *++YYCURSOR;
goto yy11;
yy15:
yych = *++YYCURSOR;
goto yy11;
yy16:
++YYCURSOR;
#line 80 "ext/phar/phar_path_check.re"
#line 92 "ext/phar/phar_path_check.re"
{
if (**s == '/') {
(*s)++;
Expand All @@ -137,49 +163,85 @@ phar_path_check_result phar_path_check(char **s, int *len, const char **error)
*error = NULL;
return pcr_is_ok;
}
#line 141 "ext/phar/phar_path_check.c"
yy15:
#line 167 "ext/phar/phar_path_check.c"
yy18:
yych = *++YYCURSOR;
goto yy3;
yy16:
yy19:
yych = *++YYCURSOR;
if (yych <= 0x00) goto yy21;
if (yych <= '-') goto yy17;
if (yych <= '.') goto yy20;
if (yych <= '/') goto yy21;
yy17:
if (yych <= 0x7F) goto yy20;
if (yych <= 0xBF) goto yy21;
yy20:
YYCURSOR = YYMARKER;
goto yy3;
yy18:
if (yyaccept <= 0) {
goto yy3;
} else {
goto yy11;
}
yy21:
yych = *++YYCURSOR;
if (yych <= 0x7F) goto yy20;
if (yych >= 0xC0) goto yy20;
++YYCURSOR;
#line 48 "ext/phar/phar_path_check.re"
#line 85 "ext/phar/phar_path_check.re"
{
goto loop;
}
#line 191 "ext/phar/phar_path_check.c"
yy24:
yych = *++YYCURSOR;
if (yych <= 0x7F) goto yy20;
if (yych >= 0xC0) goto yy20;
++YYCURSOR;
#line 82 "ext/phar/phar_path_check.re"
{
goto loop;
}
#line 201 "ext/phar/phar_path_check.c"
yy27:
++YYCURSOR;
#line 79 "ext/phar/phar_path_check.re"
{
goto loop;
}
#line 208 "ext/phar/phar_path_check.c"
yy29:
yych = *++YYCURSOR;
if (yych <= 0x00) goto yy33;
if (yych <= '-') goto yy20;
if (yych <= '.') goto yy32;
if (yych <= '/') goto yy33;
goto yy20;
yy30:
++YYCURSOR;
#line 51 "ext/phar/phar_path_check.re"
{
*error = "double slash";
return pcr_err_double_slash;
}
#line 161 "ext/phar/phar_path_check.c"
yy20:
#line 223 "ext/phar/phar_path_check.c"
yy32:
yych = *++YYCURSOR;
if (yych <= 0x00) goto yy23;
if (yych == '/') goto yy23;
goto yy17;
yy21:
if (yych <= 0x00) goto yy35;
if (yych == '/') goto yy35;
goto yy20;
yy33:
++YYCURSOR;
#line 56 "ext/phar/phar_path_check.re"
#line 59 "ext/phar/phar_path_check.re"
{
*error = "current directory reference";
return pcr_err_curr_dir;
}
#line 174 "ext/phar/phar_path_check.c"
yy23:
#line 236 "ext/phar/phar_path_check.c"
yy35:
++YYCURSOR;
#line 52 "ext/phar/phar_path_check.re"
#line 55 "ext/phar/phar_path_check.re"
{
*error = "upper directory reference";
return pcr_err_up_dir;
}
#line 182 "ext/phar/phar_path_check.c"
#line 244 "ext/phar/phar_path_check.c"
}
#line 96 "ext/phar/phar_path_check.re"
#line 108 "ext/phar/phar_path_check.re"

}
14 changes: 13 additions & 1 deletion ext/phar/phar_path_check.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| phar php single-file executable PHP extension |
+----------------------------------------------------------------------+
| Copyright (c) 2007-2013 The PHP Group |
| Copyright (c) 2007-2014 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 |
Expand Down Expand Up @@ -42,6 +42,9 @@ phar_path_check_result phar_path_check(char **s, int *len, const char **error)
loop:
/*!re2c
END = "\x00";
MB2 = ([\xC0-\xDF][\x80-\xBF]);
MB3 = ([\xE0-\xEF][\x80-\xBF]{2});
MB4 = ([\xF0-\xF7][\x80-\xBF]{3});
ILL = [\x01-\x19\x80-\xFF];
EOS = "/" | END;
ANY = .;
Expand Down Expand Up @@ -73,6 +76,15 @@ ANY = .;
*error = NULL;
return pcr_use_query;
}
MB2 {
goto loop;
}
MB3 {
goto loop;
}
MB4 {
goto loop;
}
ILL {
*error ="illegal character";
return pcr_err_illegal_char;
Expand Down
8 changes: 7 additions & 1 deletion ext/phar/tests/create_new_phar.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ phar.require_hash=1
<?php

file_put_contents('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/a.php',
'brand new!');
"brand new!\n");
include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/a.php';

$fileName = "ChineseFile\xE5\x84\xB7\xE9\xBB\x91.php";
file_put_contents('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/$fileName.php',
'Text in utf8 file.');
include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/$fileName.php';
?>

===DONE===
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
--EXPECT--
brand new!
Text in utf8 file.
===DONE===
31 changes: 25 additions & 6 deletions ext/phar/tests/create_path_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,26 @@ var_dump(file_get_contents($pname . '/b.php'));

function error_handler($errno, $errmsg)
{
echo "Error: $errmsg\n";
echo "Error: $errmsg";
}

set_error_handler('error_handler');

$checks = array('/', '.', '../', 'a/..', 'a/', 'b//a.php');
$count = 0;
$checks = array(
'/', '.', '../', 'a/..', 'a/', 'b//a.php',
"Font\xE5\x84\xB7\xE9\xBB\x91pro.ttf", //two valid multi-byte characters
"\xF0\x9F\x98\x8D.ttf", // valid 4 byte char - smiling face with heart-shaped eyes
"Font\xE9\xBBpro.ttf", //Invalid multi-byte character - missing last byte
"Font\xBB\x91pro.ttf", //Invalid multi-byte character - missing first byte
"\xFC\x81\x81\x81\x81pro.ttf", //RFC 3629 limited char points to 0000-10FFFF aka 5 byte utf-8 not valid
);
foreach($checks as $check)
{
$count++;
echo "$count:";
file_put_contents($pname . '/' . $check, "error");
echo "\n";
}

$phar = new Phar($fname);
Expand All @@ -54,9 +65,17 @@ foreach($checks as $check)
--EXPECTF--
string(5) "query"
string(5) "query"
Error: file_put_contents(phar://%s//): failed to open stream: phar error: file "" in phar "%s" cannot be empty
Error: file_put_contents(phar://%s/.): failed to open stream: phar error: file "" in phar "%s" cannot be empty
Error: file_put_contents(phar://%s/../): failed to open stream: phar error: file "" in phar "%s" cannot be empty
Error: file_put_contents(phar://%s/a/..): failed to open stream: phar error: file "" in phar "%s" cannot be empty
1:Error: file_put_contents(phar://%s//): failed to open stream: phar error: file "" in phar "%s" cannot be empty
2:Error: file_put_contents(phar://%s/.): failed to open stream: phar error: file "" in phar "%s" cannot be empty
3:Error: file_put_contents(phar://%s/../): failed to open stream: phar error: file "" in phar "%s" cannot be empty
4:Error: file_put_contents(phar://%s/a/..): failed to open stream: phar error: file "" in phar "%s" cannot be empty
5:
6:
7:
8:
9:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character
10:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character
11:Error: file_put_contents(phar:///%s): failed to open stream: phar error: invalid path "%s" contains illegal character
Exception: Entry a does not exist and cannot be created: phar error: invalid path "a" contains illegal character
===DONE===