Skip to content

Commit 9053800

Browse files
committed
Add suffix to tempnam()
Implementation of this RFC: https://wiki.php.net/rfc/tempnam-suffix
1 parent 4904be6 commit 9053800

8 files changed

+107
-25
lines changed

ext/standard/basic_functions.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,9 +1094,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file, 0, 0, 1)
10941094
ZEND_ARG_INFO(0, context)
10951095
ZEND_END_ARG_INFO()
10961096

1097-
ZEND_BEGIN_ARG_INFO(arginfo_tempnam, 0)
1097+
ZEND_BEGIN_ARG_INFO_EX(arginfo_tempnam, 0, 0, 2)
10981098
ZEND_ARG_INFO(0, dir)
10991099
ZEND_ARG_INFO(0, prefix)
1100+
ZEND_ARG_INFO(0, suffix)
11001101
ZEND_END_ARG_INFO()
11011102

11021103
ZEND_BEGIN_ARG_INFO(arginfo_tmpfile, 0)

ext/standard/file.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -799,18 +799,18 @@ PHP_FUNCTION(file)
799799
}
800800
/* }}} */
801801

802-
/* {{{ proto string tempnam(string dir, string prefix)
802+
/* {{{ proto string tempnam(string dir, string prefix [, string suffix])
803803
Create a unique filename in a directory */
804804
PHP_FUNCTION(tempnam)
805805
{
806-
char *dir, *prefix;
807-
int dir_len, prefix_len;
806+
char *dir, *prefix, *suffix = "";
807+
int dir_len, prefix_len, suffix_len = 0;
808808
size_t p_len;
809809
char *opened_path;
810810
char *p;
811811
int fd;
812812

813-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
813+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps|s", &dir, &dir_len, &prefix, &prefix_len, &suffix, &suffix_len) == FAILURE) {
814814
return;
815815
}
816816

@@ -825,7 +825,7 @@ PHP_FUNCTION(tempnam)
825825

826826
RETVAL_FALSE;
827827

828-
if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) {
828+
if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, suffix, 1 TSRMLS_CC)) >= 0) {
829829
close(fd);
830830
RETVAL_STRING(opened_path, 0);
831831
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
--TEST--
2+
Test tempnam() function: usage variations - specify a suffix
3+
--SKIPIF--
4+
<?php
5+
if(substr(PHP_OS, 0, 3) == "WIN")
6+
die("skip Do not run on Windows");
7+
?>
8+
--FILE--
9+
<?php
10+
/* Prototype: string tempnam ( string $dir, string $prefix, string $suffix );
11+
Description: Create file with unique file name.
12+
*/
13+
14+
/* Passing args for $prefix and $suffix */
15+
16+
echo "*** Testing tempnam() with suffixes ***\n";
17+
$file_path = dirname(__FILE__)."/tempnamSuffix";
18+
mkdir($file_path);
19+
20+
/* An array of suffixes */
21+
$names_arr = array(
22+
NULL,
23+
"",
24+
".png",
25+
);
26+
27+
for( $i=0; $i<count($names_arr); $i++ ) {
28+
echo "-- Iteration $i --\n";
29+
$file_name = tempnam("$file_path", "prefix", $names_arr[$i]);
30+
31+
/* creating the files in existing dir */
32+
if( file_exists($file_name) ) {
33+
echo "File name is => ";
34+
print($file_name);
35+
echo "\n";
36+
37+
echo "File permissions are => ";
38+
printf("%o", fileperms($file_name) );
39+
echo "\n";
40+
41+
echo "File created in => ";
42+
$file_dir = dirname($file_name);
43+
44+
if ($file_dir == sys_get_temp_dir()) {
45+
echo "temp dir\n";
46+
}
47+
else if ($file_dir == $file_path) {
48+
echo "directory specified\n";
49+
}
50+
else {
51+
echo "unknown location\n";
52+
}
53+
54+
}
55+
else {
56+
echo "-- File is not created --\n";
57+
}
58+
59+
unlink($file_name);
60+
}
61+
62+
rmdir($file_path);
63+
echo "\n*** Done ***\n";
64+
?>
65+
--EXPECTF--
66+
*** Testing tempnam() with obscure suffixes ***
67+
-- Iteration 0 --
68+
File name is => %s/prefix%s
69+
File permissions are => 100600
70+
File created in => directory specified
71+
-- Iteration 1 --
72+
File name is => %s/prefix%s
73+
File permissions are => 100600
74+
File created in => directory specified
75+
-- Iteration 2 --
76+
File name is => %s/prefix%s.png
77+
File permissions are => 100600
78+
File created in => directory specified
79+
80+
*** Done ***
81+

main/php_open_temporary_file.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
* SUCH DAMAGE.
9595
*/
9696

97-
static int php_do_open_temporary_file(const char *path, const char *pfx, char **opened_path_p TSRMLS_DC)
97+
static int php_do_open_temporary_file(const char *path, const char *pfx, const char *suffix, char **opened_path_p TSRMLS_DC)
9898
{
9999
char *trailing_slash;
100100
char *opened_path;
@@ -138,7 +138,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char **
138138
trailing_slash = "/";
139139
}
140140

141-
if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) {
141+
if (spprintf(&opened_path, 0, "%s%s%sXXXXXX%s", new_state.cwd, trailing_slash, pfx, suffix) >= MAXPATHLEN) {
142142
efree(opened_path);
143143
efree(new_state.cwd);
144144
return -1;
@@ -158,7 +158,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char **
158158
}
159159

160160
#elif defined(HAVE_MKSTEMP)
161-
fd = mkstemp(opened_path);
161+
fd = mkstemps(opened_path, strlen(suffix));
162162
#else
163163
if (mktemp(opened_path)) {
164164
fd = VCWD_OPEN(opened_path, open_flags);
@@ -264,7 +264,7 @@ PHPAPI const char* php_get_temporary_directory(TSRMLS_D)
264264
* This function should do its best to return a file pointer to a newly created
265265
* unique file, on every platform.
266266
*/
267-
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC)
267+
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, const char *suffix, zend_bool open_basedir_check TSRMLS_DC)
268268
{
269269
int fd;
270270
const char *temp_dir;
@@ -281,30 +281,30 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **ope
281281
temp_dir = php_get_temporary_directory(TSRMLS_C);
282282

283283
if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || !php_check_open_basedir(temp_dir TSRMLS_CC))) {
284-
return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC);
284+
return php_do_open_temporary_file(temp_dir, pfx, suffix, opened_path_p TSRMLS_CC);
285285
} else {
286286
return -1;
287287
}
288288
}
289289

290290
/* Try the directory given as parameter. */
291-
fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC);
291+
fd = php_do_open_temporary_file(dir, pfx, suffix, opened_path_p TSRMLS_CC);
292292
if (fd == -1) {
293293
/* Use default temporary directory. */
294294
goto def_tmp;
295295
}
296296
return fd;
297297
}
298298

299-
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC)
299+
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, const char *suffix, char **opened_path_p TSRMLS_DC)
300300
{
301-
return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0 TSRMLS_CC);
301+
return php_open_temporary_fd_ex(dir, pfx, opened_path_p, suffix, 0 TSRMLS_CC);
302302
}
303303

304-
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC)
304+
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, const char *suffix, char **opened_path_p TSRMLS_DC)
305305
{
306306
FILE *fp;
307-
int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC);
307+
int fd = php_open_temporary_fd(dir, pfx, suffix, opened_path_p TSRMLS_CC);
308308

309309
if (fd == -1) {
310310
return NULL;

main/php_open_temporary_file.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
#define PHP_OPEN_TEMPORARY_FILE_H
2323

2424
BEGIN_EXTERN_C()
25-
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC);
26-
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC);
27-
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC);
25+
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, const char *suffix, char **opened_path_p TSRMLS_DC);
26+
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, const char *suffix, zend_bool open_basedir_check TSRMLS_DC);
27+
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, const char *suffix, char **opened_path_p TSRMLS_DC);
2828
PHPAPI const char *php_get_temporary_directory(TSRMLS_D);
2929
PHPAPI void php_shutdown_temporary_directory(void);
3030
END_EXTERN_C()

main/rfc1867.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
10031003
/* in non-debug mode we have no problem with 0-length files */
10041004
{
10051005
#endif
1006-
fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1 TSRMLS_CC);
1006+
fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, "", 1 TSRMLS_CC);
10071007
upload_cnt--;
10081008
if (fd == -1) {
10091009
sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");

main/streams/php_stream_plain_wrapper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE
4545
PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC);
4646
#define php_stream_fopen_tmpfile() _php_stream_fopen_tmpfile(0 STREAMS_CC TSRMLS_CC)
4747

48-
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC);
49-
#define php_stream_fopen_temporary_file(dir, pfx, opened_path) _php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_CC TSRMLS_CC)
48+
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, const char *suffix, char **opened_path STREAMS_DC TSRMLS_DC);
49+
#define php_stream_fopen_temporary_file(dir, pfx, opened_path, suffix) _php_stream_fopen_temporary_file((dir), (pfx), (suffix), (opened_path) STREAMS_CC TSRMLS_CC)
5050

5151
/* This is a utility API for extensions that are opening a stream, converting it
5252
* to a FILE* and then closing it again. Be warned that fileno() on the result

main/streams/plain_wrapper.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode
183183
return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
184184
}
185185

186-
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC)
186+
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, const char *suffix, char **opened_path STREAMS_DC TSRMLS_DC)
187187
{
188-
int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC);
188+
int fd = php_open_temporary_fd(dir, pfx, suffix, opened_path TSRMLS_CC);
189189

190190
if (fd != -1) {
191191
php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
@@ -204,7 +204,7 @@ PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char
204204
PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
205205
{
206206
char *opened_path = NULL;
207-
int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC);
207+
int fd = php_open_temporary_fd(NULL, "php", "", &opened_path TSRMLS_CC);
208208

209209
if (fd != -1) {
210210
php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);

0 commit comments

Comments
 (0)