Skip to content
34 changes: 23 additions & 11 deletions ext/standard/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ PHP_FUNCTION(tempnam)
if (p_len > 64) {
p[63] = '\0';
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theoreticaLee cleaned up stray tab

RETVAL_FALSE;

if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) {
Expand Down Expand Up @@ -1380,13 +1380,13 @@ PHP_FUNCTION(umask)
{
long arg1 = 0;
int oldumask;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theoreticaLee cleaned up stray tab

oldumask = umask(077);

if (BG(umask) == -1) {
BG(umask) = oldumask;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theoreticaLee cleaned up stray tab

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
RETURN_FALSE;
}
Expand Down Expand Up @@ -1799,22 +1799,23 @@ static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t le

#define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field))

/* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])
/* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure [, string escape_char]]])
Format line as CSV and write to file pointer */
PHP_FUNCTION(fputcsv)
{
char delimiter = ','; /* allow this to be set as parameter */
char enclosure = '"'; /* allow this to be set as parameter */
const char escape_char = '\\';
char delimiter = ','; /* allow this to be set as parameter */
char enclosure = '"'; /* allow this to be set as parameter */
char escape_char = '\\'; /* allow this to be set as parameter */
php_stream *stream;
zval *fp = NULL, *fields = NULL;
int ret;
char *delimiter_str = NULL, *enclosure_str = NULL;
int delimiter_str_len = 0, enclosure_str_len = 0;
char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL;
int delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ss",
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|sss",
&fp, &fields, &delimiter_str, &delimiter_str_len,
&enclosure_str, &enclosure_str_len) == FAILURE) {
&enclosure_str, &enclosure_str_len,
&escape_str, &escape_str_len) == FAILURE) {
return;
}

Expand Down Expand Up @@ -1842,6 +1843,17 @@ PHP_FUNCTION(fputcsv)
enclosure = *enclosure_str;
}

if (escape_str != NULL) {
if (escape_str_len < 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message should be "Escape string must be a character"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and line 1848 are fine — the messages are consistent with fgetcsv() and the other warnings in the function.

RETURN_FALSE;
} else if (escape_str_len > 1) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "escape must be a single character");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "Escape string must be a single character"

}
/* use first character from string */
escape_char = *escape_str;
}

PHP_STREAM_TO_ZVAL(stream, &fp);

ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char TSRMLS_CC);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/tests/file/fputcsv_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Warning: fputcsv() expects at least 2 parameters, 0 given in %s on line %d
NULL
-- Testing fputcsv() with more than expected number of arguments --

Warning: fputcsv() expects at most 4 parameters, 5 given in %s on line %d
Warning: fputcsv() expects parameter 5 to be string, resource given in %s on line %d
NULL
-- Testing fputcsv() with invalid arguments --
-- Iteration 1 --
Expand Down
107 changes: 107 additions & 0 deletions ext/standard/tests/file/fputcsv_variation15.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
--TEST--
various fputcsv() functionality tests
--CREDITS--
Lee Leathers <[email protected]>
--FILE--
<?php

$list = array (
0 => 'aaa,bbb',
1 => 'aaa,"bbb"',
2 => '"aaa","bbb"',
3 => 'aaa,bbb',
4 => '"aaa",bbb',
5 => '"aaa", "bbb"',
6 => ',',
7 => 'aaa,',
8 => ',"aaa"',
9 => '"",""',
10 => '"""""",',
11 => '""""",aaa',
12 => 'aaa,bbb ',
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 = dirname(__FILE__) . 'fgetcsv.csv';
@unlink($file);

$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";

@unlink($file);

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
$list = array (
0 => 'aaa,bbb',
1 => 'aaa,"""bbb"""',
2 => '"""aaa""","""bbb"""',
3 => 'aaa,bbb',
4 => '"""aaa""",bbb',
5 => '"""aaa"""," ""bbb"""',
6 => ',',
7 => 'aaa,',
8 => ',"""aaa"""',
9 => '"""""",""""""',
10 => '"""""""""""""",',
11 => '"""""""""""",aaa',
12 => 'aaa,"bbb "',
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',
1 => 'aaa,"bbb"',
2 => '"aaa","bbb"',
3 => 'aaa,bbb',
4 => '"aaa",bbb',
5 => '"aaa", "bbb"',
6 => ',',
7 => 'aaa,',
8 => ',"aaa"',
9 => '"",""',
10 => '"""""",',
11 => '""""",aaa',
12 => 'aaa,bbb ',
13 => 'aaa,"bbb "',
14 => 'aaa"aaa","bbb"bbb',
15 => 'aaa"aaa""",bbb',
16 => 'aaa,"/"bbb,ccc',
17 => 'aaa"/"a","bbb"',
18 => '"/"","aaa"',
19 => '"/""",aaa',
);
===DONE===