ext/(standard|spl): Deprecate passing a non-empty string as the $enclosure parameter (#15362)

This commit is contained in:
Gina Peter Banyard 2024-08-12 16:09:56 +01:00 committed by GitHub
parent 37c22c4c7e
commit c818d944cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 184 additions and 45 deletions

10
NEWS
View File

@ -77,10 +77,20 @@ PHP NEWS
. The SplFixedArray::__wakeup() method has been deprecated as it implements
__serialize() and __unserialize() which need to be overwritten instead.
(TysonAndre)
. Passing a non-empty string for the $enclosure parameter of:
- SplFileObject::setCsvControl()
- SplFileObject::fputcsv()
- SplFileObject::fgetcsv()
is now deprecated. (Girgias)
- Standard:
. Unserializing the uppercase 'S' tag is now deprecated. (timwolla)
. Enables crc32 auxiliary detection on OpenBSD. (David Carlier)
. Passing a non-empty string for the $enclosure parameter of:
- fputcsv()
- fgetcsv()
- str_getcsv()
is now deprecated. (Girgias)
- Streams:
. Implemented GH-15155 (Stream context is lost when custom stream wrapper is

View File

@ -506,6 +506,12 @@ PHP 8.4 UPGRADE NOTES
- SPL:
. The SplFixedArray::__wakeup() method has been deprecated as it implements
__serialize() and __unserialize() which need to be overwritten instead.
. Passing a non-empty string for the $enclosure parameter of:
- SplFileObject::setCsvControl()
- SplFileObject::fputcsv()
- SplFileObject::fgetcsv()
is now deprecated.
RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_proprietary_csv_escaping_mechanism
- Standard:
. Calling stream_context_set_option() with 2 arguments is deprecated.
@ -514,6 +520,12 @@ PHP 8.4 UPGRADE NOTES
RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number
. Unserializing strings using the uppercase 'S' tag is deprecated.
RFC: https://wiki.php.net/rfc/deprecations_php_8_4
. Passing a non-empty string for the $enclosure parameter of:
- fputcsv()
- fgetcsv()
- str_getcsv()
is now deprecated.
RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_proprietary_csv_escaping_mechanism
- XML:
. The xml_set_object() function has been deprecated.

View File

@ -2310,6 +2310,10 @@ PHP_METHOD(SplFileObject, fgetcsv)
if (esc_len == 0) {
escape = PHP_CSV_NO_ESCAPE;
} else {
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
escape = (unsigned char) esc[0];
}
}
@ -2358,6 +2362,10 @@ PHP_METHOD(SplFileObject, fputcsv)
if (esc_len == 0) {
escape = PHP_CSV_NO_ESCAPE;
} else {
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
escape = (unsigned char) esc[0];
}
}
@ -2405,6 +2413,10 @@ PHP_METHOD(SplFileObject, setCsvControl)
if (esc_len == 0) {
escape = PHP_CSV_NO_ESCAPE;
} else {
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
escape = (unsigned char) esc[0];
}
}

View File

@ -13,7 +13,8 @@ var_dump($fo->fgetcsv(',', '"', '"'));
<?php
unlink('SplFileObject__fgetcsv6.csv');
?>
--EXPECT--
--EXPECTF--
Deprecated: SplFileObject::fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array(3) {
[0]=>
string(3) "aaa"

View File

@ -4,16 +4,17 @@ SPL: SplFileObject::setCsvControl basic
Erwin Poeze <erwin.poeze at gmail.com>
--FILE--
<?php
file_put_contents('csv_control_data_basic.csv',
<<<CDATA
'groene appelen'|10
'gele bananen'|20
'rode kersen'|30
CDATA
file_put_contents(
'csv_control_data_basic.csv',
<<<CDATA
'groene appelen'|10
'gele bananen'|20
'rode kersen'|30
CDATA
);
$s = new SplFileObject('csv_control_data_basic.csv');
$s->setFlags(SplFileObject::READ_CSV);
$s->setCsvControl('|', '\'', '/');
$s->setCsvControl('|', '\'', '');
foreach ($s as $row) {
list($fruit, $quantity) = $row;
echo "$fruit : $quantity\n";

View File

@ -1734,6 +1734,10 @@ PHP_FUNCTION(fputcsv)
if (escape_str_len < 1) {
escape_char = PHP_CSV_NO_ESCAPE;
} else {
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
/* use first character from string */
escape_char = (unsigned char) *escape_str;
}
@ -1875,6 +1879,10 @@ PHP_FUNCTION(fgetcsv)
if (escape_str_len < 1) {
escape = PHP_CSV_NO_ESCAPE;
} else {
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
escape = (unsigned char) escape_str[0];
}
}

View File

@ -5447,25 +5447,40 @@ PHP_FUNCTION(str_getcsv)
{
zend_string *str;
char delim = ',', enc = '"';
int esc = (unsigned char) '\\';
char *delim_str = NULL, *enc_str = NULL, *esc_str = NULL;
size_t delim_len = 0, enc_len = 0, esc_len = 0;
int escape = (unsigned char) '\\';
char *delim_str = NULL, *enc_str = NULL, *escape_str = NULL;
size_t delim_len = 0, enc_len = 0, escape_str_len = 0;
ZEND_PARSE_PARAMETERS_START(1, 4)
Z_PARAM_STR(str)
Z_PARAM_OPTIONAL
Z_PARAM_STRING(delim_str, delim_len)
Z_PARAM_STRING(enc_str, enc_len)
Z_PARAM_STRING(esc_str, esc_len)
Z_PARAM_STRING(escape_str, escape_str_len)
ZEND_PARSE_PARAMETERS_END();
delim = delim_len ? delim_str[0] : delim;
enc = enc_len ? enc_str[0] : enc;
if (esc_str != NULL) {
esc = esc_len ? (unsigned char) esc_str[0] : PHP_CSV_NO_ESCAPE;
// TODO ValueError for delimiter and enclosure string being longer than 1 byte
if (escape_str != NULL) {
if (escape_str_len > 1) {
zend_argument_value_error(4, "must be empty or a single character");
RETURN_THROWS();
}
if (escape_str_len < 1) {
escape = PHP_CSV_NO_ESCAPE;
} else {
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
escape = (unsigned char) escape_str[0];
}
}
HashTable *values = php_fgetcsv(NULL, delim, enc, esc, ZSTR_LEN(str), ZSTR_VAL(str));
HashTable *values = php_fgetcsv(NULL, delim, enc, escape, ZSTR_LEN(str), ZSTR_VAL(str));
if (values == NULL) {
values = php_bc_fgetcsv_empty_line();
}

View File

@ -11,6 +11,7 @@ fclose($h);
var_dump($data);
?>
--EXPECTF--
Deprecated: fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array(2) {
[0]=>
string(%d) "this element contains the delimiter, and ends with an odd number of

View File

@ -17,7 +17,8 @@ $string = '"first #' . $utf_1 . $utf_2 . '";"second"';
$fields = str_getcsv($string, ';', '"', "#");
var_dump($fields);
?>
--EXPECT--
--EXPECTF--
Deprecated: str_getcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array(2) {
[0]=>
string(11) "first #с؀"

View File

@ -22,18 +22,13 @@ $list = array (
13 => 'aaa,"bbb "',
14 => 'aaa"aaa","bbb"bbb',
15 => 'aaa"aaa""",bbb',
16 => 'aaa,"/"bbb,ccc',
17 => 'aaa"/"a","bbb"',
18 => '"/"","aaa"',
19 => '"/""",aaa',
);
$file = __DIR__ . '/fputcsv_variation15.csv';
@unlink($file);
$fp = fopen($file, "w");
foreach ($list as $v) {
fputcsv($fp, explode(',', $v), ',', '"', '/');
fputcsv($fp, explode(',', $v), ',', '"', '');
}
fclose($fp);
@ -46,7 +41,7 @@ echo '$list = ';var_export($res);echo ";\n";
$fp = fopen($file, "r");
$res = array();
while($l=fgetcsv($fp, 0, ',', '"', '/'))
while($l=fgetcsv($fp, 0, ',', '"', ''))
{
$res[] = join(',',$l);
}
@ -54,8 +49,11 @@ fclose($fp);
echo '$list = ';var_export($res);echo ";\n";
?>
--CLEAN--
<?php
$file = __DIR__ . '/fputcsv_variation15.csv';
@unlink($file);
?>
--EXPECT--
$list = array (
@ -75,10 +73,6 @@ $list = array (
13 => 'aaa,"""bbb """',
14 => '"aaa""aaa""","""bbb""bbb"',
15 => '"aaa""aaa""""""",bbb',
16 => 'aaa,"""/"bbb",ccc',
17 => '"aaa""/"a""","""bbb"""',
18 => '"""/"""","""aaa"""',
19 => '"""/"""""",aaa',
);
$list = array (
0 => 'aaa,bbb',
@ -97,8 +91,4 @@ $list = array (
13 => 'aaa,"bbb "',
14 => 'aaa"aaa","bbb"bbb',
15 => 'aaa"aaa""",bbb',
16 => 'aaa,"/"bbb,ccc',
17 => 'aaa"/"a","bbb"',
18 => '"/"","aaa"',
19 => '"/""",aaa',
);

View File

@ -12,7 +12,7 @@ $eol_chars = ['||', '|', '\n', "\n", "\0"];
foreach ($eol_chars as $eol_char) {
$stream = fopen('php://memory', 'w+');
foreach ($data as $record) {
fputcsv($stream, $record, ',', '"', '\\', $eol_char);
fputcsv($stream, $record, ',', '"', '', $eol_char);
}
rewind($stream);
echo stream_get_contents($stream), "\n";

View File

@ -0,0 +1,73 @@
--TEST--
fputcsv() variant where escape parameter matters
--FILE--
<?php
$list = [
1 => 'aaa,"/"bbb,ccc',
2 => 'aaa"/"a","bbb"',
3 => '"/"","aaa"',
4 => '"/""",aaa',
];
$file = __DIR__ . '/fputcsv_variation18.csv';
$fp = fopen($file, "w");
foreach ($list as $v) {
fputcsv($fp, explode(',', $v), ',', '"', '/');
}
fclose($fp);
$res = file($file);
foreach($res as &$val)
{
$val = substr($val, 0, -1);
}
echo '$list = ';var_export($res);echo ";\n";
$fp = fopen($file, "r");
$res = array();
while($l=fgetcsv($fp, 0, ',', '"', '/'))
{
$res[] = join(',',$l);
}
fclose($fp);
echo '$list = ';var_export($res);echo ";\n";
?>
--CLEAN--
<?php
$file = __DIR__ . '/fputcsv_variation18.csv';
@unlink($file);
?>
--EXPECTF--
Deprecated: fputcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fputcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fputcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fputcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
$list = array (
0 => 'aaa,"""/"bbb",ccc',
1 => '"aaa""/"a""","""bbb"""',
2 => '"""/"""","""aaa"""',
3 => '"""/"""""",aaa',
);
Deprecated: fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
Deprecated: fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
$list = array (
0 => 'aaa,"/"bbb,ccc',
1 => 'aaa"/"a","bbb"',
2 => '"/"","aaa"',
3 => '"/""",aaa',
);

View File

@ -5,10 +5,13 @@ GH-12151 (str_getcsv ending with escape zero segfualt)
var_export(str_getcsv("y","","y","\000"));
var_export(str_getcsv("\0yy","y","y","\0"));
?>
--EXPECT--
--EXPECTF--
Deprecated: str_getcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array (
0 => '' . "\0" . '',
)array (
)
Deprecated: str_getcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array (
0 => '' . "\0" . '',
1 => '' . "\0" . '',
)

View File

@ -18,8 +18,6 @@ var_dump(str_getcsv('.foo..bar.', '.', '.', '.'));
print "-----\n";
var_dump(str_getcsv('.foo. .bar.', ' ', '.', '.'));
print "-----\n";
var_dump(str_getcsv('1foo1 1bar111', ' ', '1 ', '\ '));
print "-----\n";
var_dump(str_getcsv('.foo . . bar .', ' ', '.', ''));
print "-----\n";
var_dump(str_getcsv('" "" "', ' '));
@ -28,7 +26,7 @@ var_dump(str_getcsv(''));
print "-----\n";
?>
--EXPECT--
--EXPECTF--
array(3) {
[0]=>
string(1) "f"
@ -61,6 +59,8 @@ array(2) {
string(3) "bar"
}
-----
Deprecated: str_getcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array(3) {
[0]=>
string(2) "f."
@ -70,11 +70,15 @@ array(3) {
string(4) "-|-."
}
-----
Deprecated: str_getcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array(1) {
[0]=>
string(7) "foo.bar"
}
-----
Deprecated: str_getcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
array(2) {
[0]=>
string(3) "foo"
@ -82,13 +86,6 @@ array(2) {
string(3) "bar"
}
-----
array(2) {
[0]=>
string(3) "foo"
[1]=>
string(4) "bar1"
}
-----
array(2) {
[0]=>
string(5) "foo "

View File

@ -0,0 +1,15 @@
--TEST--
str_getcsv(): Invalid arguments
--FILE--
<?php
// string input[, string delimiter[, string enclosure[, string escape]]]
try {
var_dump(str_getcsv('csv_string', ',', '"', 'enclosure'));
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
ValueError: str_getcsv(): Argument #4 ($escape) must be empty or a single character