Skip to content

Commit 5a14715

Browse files
author
Derick Rethans
committed
- Fixed Bug #42272 (var_export() incorrectly escapes char(0)).
- Also fixed var_export() in unicode mode, as the function would actually generate non-parsable strings which defeats the purpose of var_export().
1 parent 7752925 commit 5a14715

File tree

5 files changed

+73
-17
lines changed

5 files changed

+73
-17
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #42272: var_export() incorrectly escapes char(0).
3+
--FILE--
4+
<?php
5+
$foo = var_export("\0", true );
6+
echo $foo, "\n";
7+
var_export("a\0b");
8+
?>
9+
--EXPECT--
10+
'' . "\0" . ''
11+
'a' . "\0" . 'b'

ext/standard/tests/general_functions/var_export-locale.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,9 @@ string(3) "' '"
572572

573573

574574
Iteration 12
575-
'\000'
576-
'\000'
577-
string(6) "'\000'"
575+
'' . "\0" . ''
576+
'' . "\0" . ''
577+
string(14) "'' . "\0" . ''"
578578

579579

580580
Iteration 13

ext/standard/tests/general_functions/var_export.phpt

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ $valid_strings = array(
124124
"\0",
125125
'\0',
126126
'\060',
127-
"\070"
127+
"\070",
128+
"\0hello\0this is an test, to work with ' and \0 and \n and foreign chars too: blåbærøl"
128129
);
129130
$counter = 1;
130131
/* Loop to check for above strings with var_export() */
@@ -568,9 +569,9 @@ string(3) "' '"
568569

569570

570571
Iteration 12
571-
'\000'
572-
'\000'
573-
string(6) "'\000'"
572+
'' . "\0" . ''
573+
'' . "\0" . ''
574+
string(14) "'' . "\0" . ''"
574575

575576

576577
Iteration 13
@@ -590,6 +591,15 @@ Iteration 15
590591
'8'
591592
string(3) "'8'"
592593

594+
595+
Iteration 16
596+
'' . "\0" . 'hello' . "\0" . 'this is an test, to work with \' and ' . "\0" . ' and
597+
and foreign chars too: blåbærøl'
598+
'' . "\0" . 'hello' . "\0" . 'this is an test, to work with \' and ' . "\0" . ' and
599+
and foreign chars too: blåbærøl'
600+
string(121) "'' . "\0" . 'hello' . "\0" . 'this is an test, to work with \' and ' . "\0" . ' and
601+
and foreign chars too: blåbærøl'"
602+
593603
*** Testing var_export() with valid arrays ***
594604

595605
*** Output for arrays ***
@@ -1320,9 +1330,9 @@ string(3) "' '"
13201330

13211331

13221332
Iteration 12
1323-
'\000'
1324-
'\000'
1325-
string(6) "'\000'"
1333+
'' . "\0" . ''
1334+
'' . "\0" . ''
1335+
string(14) "'' . "\0" . ''"
13261336

13271337

13281338
Iteration 13
@@ -1342,6 +1352,15 @@ Iteration 15
13421352
'8'
13431353
string(3) "'8'"
13441354

1355+
1356+
Iteration 16
1357+
'' . "\0" . 'hello' . "\0" . 'this is an test, to work with \' and ' . "\0" . ' and
1358+
and foreign chars too: bl' . "\u00E5" . 'b' . "\u00E6" . 'r' . "\u00F8" . 'l'
1359+
'' . "\0" . 'hello' . "\0" . 'this is an test, to work with \' and ' . "\0" . ' and
1360+
and foreign chars too: bl' . "\u00E5" . 'b' . "\u00E6" . 'r' . "\u00F8" . 'l'
1361+
string(163) "'' . "\0" . 'hello' . "\0" . 'this is an test, to work with \' and ' . "\0" . ' and
1362+
and foreign chars too: bl' . "\u00E5" . 'b' . "\u00E6" . 'r' . "\u00F8" . 'l'"
1363+
13451364
*** Testing var_export() with valid arrays ***
13461365

13471366
*** Output for arrays ***

ext/standard/tests/strings/bug37262.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ $func = create_function('$a', 'return $a;');
66
var_export($func);
77
?>
88
--EXPECT--
9-
'\000lambda_1'
9+
'' . "\0" . 'lambda_1'

ext/standard/var.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ static void php_unicode_export(UChar *ustr, int ustr_len TSRMLS_DC) /* {{{ */
520520
int i = 0;
521521
char buf[10];
522522
int buf_len;
523+
int state = 0; /* 0 = in single quotes, 1 = in double quotes */
523524

524525
/*
525526
* We export all codepoints > 128 in escaped form to avoid encoding issues
@@ -529,10 +530,18 @@ static void php_unicode_export(UChar *ustr, int ustr_len TSRMLS_DC) /* {{{ */
529530
U16_NEXT(ustr, i, ustr_len, cp);
530531
switch (cp) {
531532
case 0x0: /* '\0' */
532-
PHPWRITE("\\000", 4);
533+
if (state == 0) {
534+
PHPWRITE("' . \"", 5);
535+
state = 1;
536+
}
537+
PHPWRITE("\\0", 2);
533538
break;
534539

535540
case 0x27: /* '\'' */
541+
if (state == 1) {
542+
PHPWRITE("\" . '", 5);
543+
state = 0;
544+
}
536545
PHPWRITE("\\'", 2);
537546
break;
538547

@@ -542,25 +551,40 @@ static void php_unicode_export(UChar *ustr, int ustr_len TSRMLS_DC) /* {{{ */
542551

543552
default:
544553
if ((uint32_t)cp < 128) {
554+
if (state == 1) {
555+
PHPWRITE("\" . '", 5);
556+
state = 0;
557+
}
545558
buf[0] = (char) (short) cp;
546559
buf_len = 1;
547560
} else if (U_IS_BMP(cp)) {
561+
if (state == 0) {
562+
PHPWRITE("' . \"", 5);
563+
state = 1;
564+
}
548565
buf_len = snprintf(buf, sizeof(buf), "\\u%04X", cp);
549566
} else {
567+
if (state == 0) {
568+
PHPWRITE("' . \"", 5);
569+
state = 1;
570+
}
550571
buf_len = snprintf(buf, sizeof(buf), "\\u%06X", cp);
551572
}
552573
PHPWRITE(buf, buf_len);
553574
break;
554575
}
555576
}
577+
if (state == 1) { // if we are in double quotes, go back to single */
578+
PHPWRITE("\" . '", 5);
579+
}
556580
}
557581
/* }}} */
558582

559583
PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) /* {{{ */
560584
{
561585
HashTable *myht;
562-
char* tmp_str;
563-
int tmp_len;
586+
char *tmp_str, *tmp_str2;
587+
int tmp_len, tmp_len2;
564588
zstr class_name;
565589
zend_uint class_name_len;
566590

@@ -578,11 +602,13 @@ PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) /* {{{ */
578602
php_printf("%.*H", (int) EG(precision), Z_DVAL_PP(struc));
579603
break;
580604
case IS_STRING:
581-
tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\\0", 3 TSRMLS_CC);
605+
tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\", 2 TSRMLS_CC);
606+
tmp_str2 = php_str_to_str_ex(tmp_str, tmp_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len2, 0, NULL);
582607
PUTS ("'");
583-
PHPWRITE(tmp_str, tmp_len);
608+
PHPWRITE(tmp_str2, tmp_len2);
584609
PUTS ("'");
585-
efree (tmp_str);
610+
efree(tmp_str2);
611+
efree(tmp_str);
586612
break;
587613
case IS_UNICODE:
588614
PUTS ("'");

0 commit comments

Comments
 (0)