1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Rasmus Lerdorf <rasmus@php.net> |
16 | Stig Bakken <ssb@php.net> |
17 | Andi Gutmans <andi@zend.com> |
18 | Zeev Suraski <zeev@zend.com> |
19 | PHP 4.0 patches by Thies C. Arntzen (thies@thieso.net) |
20 | PHP streams by Wez Furlong (wez@thebrainroom.com) |
21 +----------------------------------------------------------------------+
22 */
23
24 /* $Id$ */
25
26 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
27
28 /* {{{ includes */
29
30 #include "php.h"
31 #include "php_globals.h"
32 #include "ext/standard/flock_compat.h"
33 #include "ext/standard/exec.h"
34 #include "ext/standard/php_filestat.h"
35 #include "php_open_temporary_file.h"
36 #include "ext/standard/basic_functions.h"
37 #include "php_ini.h"
38 #include "php_smart_str.h"
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <errno.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46
47 #ifdef PHP_WIN32
48 # include <io.h>
49 # define O_RDONLY _O_RDONLY
50 # include "win32/param.h"
51 # include "win32/winutil.h"
52 # include "win32/fnmatch.h"
53 #else
54 # if HAVE_SYS_PARAM_H
55 # include <sys/param.h>
56 # endif
57 # if HAVE_SYS_SELECT_H
58 # include <sys/select.h>
59 # endif
60 # if defined(NETWARE) && defined(USE_WINSOCK)
61 # include <novsock2.h>
62 # else
63 # include <sys/socket.h>
64 # include <netinet/in.h>
65 # include <netdb.h>
66 # endif
67 # if HAVE_ARPA_INET_H
68 # include <arpa/inet.h>
69 # endif
70 #endif
71
72 #include "ext/standard/head.h"
73 #include "safe_mode.h"
74 #include "php_string.h"
75 #include "file.h"
76
77 #if HAVE_PWD_H
78 # ifdef PHP_WIN32
79 # include "win32/pwd.h"
80 # else
81 # include <pwd.h>
82 # endif
83 #endif
84
85 #ifdef HAVE_SYS_TIME_H
86 # include <sys/time.h>
87 #endif
88
89 #include "fsock.h"
90 #include "fopen_wrappers.h"
91 #include "streamsfuncs.h"
92 #include "php_globals.h"
93
94 #ifdef HAVE_SYS_FILE_H
95 # include <sys/file.h>
96 #endif
97
98 #if MISSING_FCLOSE_DECL
99 extern int fclose(FILE *);
100 #endif
101
102 #ifdef HAVE_SYS_MMAN_H
103 # include <sys/mman.h>
104 #endif
105
106 #include "scanf.h"
107 #include "zend_API.h"
108
109 #ifdef ZTS
110 int file_globals_id;
111 #else
112 php_file_globals file_globals;
113 #endif
114
115 #if defined(HAVE_FNMATCH) && !defined(PHP_WIN32)
116 # ifndef _GNU_SOURCE
117 # define _GNU_SOURCE
118 # endif
119 # include <fnmatch.h>
120 #endif
121
122 #ifdef HAVE_WCHAR_H
123 # include <wchar.h>
124 #endif
125
126 #ifndef S_ISDIR
127 # define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
128 #endif
129 /* }}} */
130
131 #define PHP_STREAM_TO_ZVAL(stream, arg) \
132 php_stream_from_zval_no_verify(stream, arg); \
133 if (stream == NULL) { \
134 RETURN_FALSE; \
135 }
136
137 /* {{{ ZTS-stuff / Globals / Prototypes */
138
139 /* sharing globals is *evil* */
140 static int le_stream_context = FAILURE;
141
php_le_stream_context(void)142 PHPAPI int php_le_stream_context(void)
143 {
144 return le_stream_context;
145 }
146 /* }}} */
147
148 /* {{{ Module-Stuff
149 */
ZEND_RSRC_DTOR_FUNC(file_context_dtor)150 static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
151 {
152 php_stream_context *context = (php_stream_context*)rsrc->ptr;
153 if (context->options) {
154 zval_ptr_dtor(&context->options);
155 context->options = NULL;
156 }
157 php_stream_context_free(context);
158 }
159
file_globals_ctor(php_file_globals * file_globals_p TSRMLS_DC)160 static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
161 {
162 FG(pclose_ret) = 0;
163 FG(user_stream_current_filename) = NULL;
164 FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
165 FG(wrapper_errors) = NULL;
166 }
167
file_globals_dtor(php_file_globals * file_globals_p TSRMLS_DC)168 static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
169 {
170 }
171
172 PHP_INI_BEGIN()
173 STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals)
174 PHP_INI_ENTRY("from", NULL, PHP_INI_ALL, NULL)
175 STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateLong, default_socket_timeout, php_file_globals, file_globals)
176 STD_PHP_INI_ENTRY("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateLong, auto_detect_line_endings, php_file_globals, file_globals)
PHP_INI_END()177 PHP_INI_END()
178
179 PHP_MINIT_FUNCTION(file)
180 {
181 le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
182
183 #ifdef ZTS
184 ts_allocate_id(&file_globals_id, sizeof(php_file_globals), (ts_allocate_ctor) file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
185 #else
186 file_globals_ctor(&file_globals TSRMLS_CC);
187 #endif
188
189 REGISTER_INI_ENTRIES();
190
191 REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
192 REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
193 REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
194 REGISTER_LONG_CONSTANT("LOCK_SH", PHP_LOCK_SH, CONST_CS | CONST_PERSISTENT);
195 REGISTER_LONG_CONSTANT("LOCK_EX", PHP_LOCK_EX, CONST_CS | CONST_PERSISTENT);
196 REGISTER_LONG_CONSTANT("LOCK_UN", PHP_LOCK_UN, CONST_CS | CONST_PERSISTENT);
197 REGISTER_LONG_CONSTANT("LOCK_NB", PHP_LOCK_NB, CONST_CS | CONST_PERSISTENT);
198
199 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT", PHP_STREAM_NOTIFY_CONNECT, CONST_CS | CONST_PERSISTENT);
200 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED", PHP_STREAM_NOTIFY_AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT);
201 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_RESULT", PHP_STREAM_NOTIFY_AUTH_RESULT, CONST_CS | CONST_PERSISTENT);
202 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_MIME_TYPE_IS", PHP_STREAM_NOTIFY_MIME_TYPE_IS, CONST_CS | CONST_PERSISTENT);
203 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FILE_SIZE_IS", PHP_STREAM_NOTIFY_FILE_SIZE_IS, CONST_CS | CONST_PERSISTENT);
204 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_REDIRECTED", PHP_STREAM_NOTIFY_REDIRECTED, CONST_CS | CONST_PERSISTENT);
205 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_PROGRESS", PHP_STREAM_NOTIFY_PROGRESS, CONST_CS | CONST_PERSISTENT);
206 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FAILURE", PHP_STREAM_NOTIFY_FAILURE, CONST_CS | CONST_PERSISTENT);
207 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_COMPLETED", PHP_STREAM_NOTIFY_COMPLETED, CONST_CS | CONST_PERSISTENT);
208 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_RESOLVE", PHP_STREAM_NOTIFY_RESOLVE, CONST_CS | CONST_PERSISTENT);
209
210 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_INFO", PHP_STREAM_NOTIFY_SEVERITY_INFO, CONST_CS | CONST_PERSISTENT);
211 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_WARN", PHP_STREAM_NOTIFY_SEVERITY_WARN, CONST_CS | CONST_PERSISTENT);
212 REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_ERR", PHP_STREAM_NOTIFY_SEVERITY_ERR, CONST_CS | CONST_PERSISTENT);
213
214 REGISTER_LONG_CONSTANT("STREAM_FILTER_READ", PHP_STREAM_FILTER_READ, CONST_CS | CONST_PERSISTENT);
215 REGISTER_LONG_CONSTANT("STREAM_FILTER_WRITE", PHP_STREAM_FILTER_WRITE, CONST_CS | CONST_PERSISTENT);
216 REGISTER_LONG_CONSTANT("STREAM_FILTER_ALL", PHP_STREAM_FILTER_ALL, CONST_CS | CONST_PERSISTENT);
217
218 REGISTER_LONG_CONSTANT("STREAM_CLIENT_PERSISTENT", PHP_STREAM_CLIENT_PERSISTENT, CONST_CS | CONST_PERSISTENT);
219 REGISTER_LONG_CONSTANT("STREAM_CLIENT_ASYNC_CONNECT", PHP_STREAM_CLIENT_ASYNC_CONNECT, CONST_CS | CONST_PERSISTENT);
220 REGISTER_LONG_CONSTANT("STREAM_CLIENT_CONNECT", PHP_STREAM_CLIENT_CONNECT, CONST_CS | CONST_PERSISTENT);
221
222 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_CLIENT", STREAM_CRYPTO_METHOD_SSLv2_CLIENT, CONST_CS|CONST_PERSISTENT);
223 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT);
224 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT);
225 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT);
226 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT);
227 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT);
228 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT);
229 REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT);
230
231 REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT);
232 REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT);
233 REGISTER_LONG_CONSTANT("STREAM_SHUT_RDWR", STREAM_SHUT_RDWR, CONST_CS|CONST_PERSISTENT);
234
235 #ifdef PF_INET
236 REGISTER_LONG_CONSTANT("STREAM_PF_INET", PF_INET, CONST_CS|CONST_PERSISTENT);
237 #elif defined(AF_INET)
238 REGISTER_LONG_CONSTANT("STREAM_PF_INET", AF_INET, CONST_CS|CONST_PERSISTENT);
239 #endif
240
241 #ifdef PF_INET6
242 REGISTER_LONG_CONSTANT("STREAM_PF_INET6", PF_INET6, CONST_CS|CONST_PERSISTENT);
243 #elif defined(AF_INET6)
244 REGISTER_LONG_CONSTANT("STREAM_PF_INET6", AF_INET6, CONST_CS|CONST_PERSISTENT);
245 #endif
246
247 #ifdef PF_UNIX
248 REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", PF_UNIX, CONST_CS|CONST_PERSISTENT);
249 #elif defined(AF_UNIX)
250 REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", AF_UNIX, CONST_CS|CONST_PERSISTENT);
251 #endif
252
253 #ifdef IPPROTO_IP
254 /* most people will use this one when calling socket() or socketpair() */
255 REGISTER_LONG_CONSTANT("STREAM_IPPROTO_IP", IPPROTO_IP, CONST_CS|CONST_PERSISTENT);
256 #endif
257
258 #ifdef IPPROTO_TCP
259 REGISTER_LONG_CONSTANT("STREAM_IPPROTO_TCP", IPPROTO_TCP, CONST_CS|CONST_PERSISTENT);
260 #endif
261
262 #ifdef IPPROTO_UDP
263 REGISTER_LONG_CONSTANT("STREAM_IPPROTO_UDP", IPPROTO_UDP, CONST_CS|CONST_PERSISTENT);
264 #endif
265
266 #ifdef IPPROTO_ICMP
267 REGISTER_LONG_CONSTANT("STREAM_IPPROTO_ICMP", IPPROTO_ICMP, CONST_CS|CONST_PERSISTENT);
268 #endif
269
270 #ifdef IPPROTO_RAW
271 REGISTER_LONG_CONSTANT("STREAM_IPPROTO_RAW", IPPROTO_RAW, CONST_CS|CONST_PERSISTENT);
272 #endif
273
274 REGISTER_LONG_CONSTANT("STREAM_SOCK_STREAM", SOCK_STREAM, CONST_CS|CONST_PERSISTENT);
275 REGISTER_LONG_CONSTANT("STREAM_SOCK_DGRAM", SOCK_DGRAM, CONST_CS|CONST_PERSISTENT);
276
277 #ifdef SOCK_RAW
278 REGISTER_LONG_CONSTANT("STREAM_SOCK_RAW", SOCK_RAW, CONST_CS|CONST_PERSISTENT);
279 #endif
280
281 #ifdef SOCK_SEQPACKET
282 REGISTER_LONG_CONSTANT("STREAM_SOCK_SEQPACKET", SOCK_SEQPACKET, CONST_CS|CONST_PERSISTENT);
283 #endif
284
285 #ifdef SOCK_RDM
286 REGISTER_LONG_CONSTANT("STREAM_SOCK_RDM", SOCK_RDM, CONST_CS|CONST_PERSISTENT);
287 #endif
288
289 REGISTER_LONG_CONSTANT("STREAM_PEEK", STREAM_PEEK, CONST_CS | CONST_PERSISTENT);
290 REGISTER_LONG_CONSTANT("STREAM_OOB", STREAM_OOB, CONST_CS | CONST_PERSISTENT);
291
292 REGISTER_LONG_CONSTANT("STREAM_SERVER_BIND", STREAM_XPORT_BIND, CONST_CS | CONST_PERSISTENT);
293 REGISTER_LONG_CONSTANT("STREAM_SERVER_LISTEN", STREAM_XPORT_LISTEN, CONST_CS | CONST_PERSISTENT);
294
295 REGISTER_LONG_CONSTANT("FILE_USE_INCLUDE_PATH", PHP_FILE_USE_INCLUDE_PATH, CONST_CS | CONST_PERSISTENT);
296 REGISTER_LONG_CONSTANT("FILE_IGNORE_NEW_LINES", PHP_FILE_IGNORE_NEW_LINES, CONST_CS | CONST_PERSISTENT);
297 REGISTER_LONG_CONSTANT("FILE_SKIP_EMPTY_LINES", PHP_FILE_SKIP_EMPTY_LINES, CONST_CS | CONST_PERSISTENT);
298 REGISTER_LONG_CONSTANT("FILE_APPEND", PHP_FILE_APPEND, CONST_CS | CONST_PERSISTENT);
299 REGISTER_LONG_CONSTANT("FILE_NO_DEFAULT_CONTEXT", PHP_FILE_NO_DEFAULT_CONTEXT, CONST_CS | CONST_PERSISTENT);
300
301 REGISTER_LONG_CONSTANT("FILE_TEXT", 0, CONST_CS | CONST_PERSISTENT);
302 REGISTER_LONG_CONSTANT("FILE_BINARY", 0, CONST_CS | CONST_PERSISTENT);
303
304 #ifdef HAVE_FNMATCH
305 REGISTER_LONG_CONSTANT("FNM_NOESCAPE", FNM_NOESCAPE, CONST_CS | CONST_PERSISTENT);
306 REGISTER_LONG_CONSTANT("FNM_PATHNAME", FNM_PATHNAME, CONST_CS | CONST_PERSISTENT);
307 REGISTER_LONG_CONSTANT("FNM_PERIOD", FNM_PERIOD, CONST_CS | CONST_PERSISTENT);
308 # ifdef FNM_CASEFOLD /* a GNU extension */ /* TODO emulate if not available */
309 REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_CS | CONST_PERSISTENT);
310 # endif
311 #endif
312
313 return SUCCESS;
314 }
315 /* }}} */
316
PHP_MSHUTDOWN_FUNCTION(file)317 PHP_MSHUTDOWN_FUNCTION(file) /* {{{ */
318 {
319 #ifndef ZTS
320 file_globals_dtor(&file_globals TSRMLS_CC);
321 #endif
322 return SUCCESS;
323 }
324 /* }}} */
325
326 static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
327
328 /* {{{ proto bool flock(resource fp, int operation [, int &wouldblock])
329 Portable file locking */
PHP_FUNCTION(flock)330 PHP_FUNCTION(flock)
331 {
332 zval *arg1, *arg3 = NULL;
333 int act;
334 php_stream *stream;
335 long operation = 0;
336
337 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) {
338 return;
339 }
340
341 PHP_STREAM_TO_ZVAL(stream, &arg1);
342
343 act = operation & 3;
344 if (act < 1 || act > 3) {
345 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal operation argument");
346 RETURN_FALSE;
347 }
348
349 if (arg3 && PZVAL_IS_REF(arg3)) {
350 convert_to_long_ex(&arg3);
351 Z_LVAL_P(arg3) = 0;
352 }
353
354 /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
355 act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
356 if (php_stream_lock(stream, act)) {
357 if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
358 Z_LVAL_P(arg3) = 1;
359 }
360 RETURN_FALSE;
361 }
362 RETURN_TRUE;
363 }
364 /* }}} */
365
366 #define PHP_META_UNSAFE ".\\+*?[^]$() "
367
368 /* {{{ proto array get_meta_tags(string filename [, bool use_include_path])
369 Extracts all meta tag content attributes from a file and returns an array */
PHP_FUNCTION(get_meta_tags)370 PHP_FUNCTION(get_meta_tags)
371 {
372 char *filename;
373 int filename_len;
374 zend_bool use_include_path = 0;
375 int in_tag = 0, done = 0;
376 int looking_for_val = 0, have_name = 0, have_content = 0;
377 int saw_name = 0, saw_content = 0;
378 char *name = NULL, *value = NULL, *temp = NULL;
379 php_meta_tags_token tok, tok_last;
380 php_meta_tags_data md;
381
382 /* Initiailize our structure */
383 memset(&md, 0, sizeof(md));
384
385 /* Parse arguments */
386 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &filename, &filename_len, &use_include_path) == FAILURE) {
387 return;
388 }
389
390 if (strlen(filename) != filename_len) {
391 RETURN_FALSE;
392 }
393
394 md.stream = php_stream_open_wrapper(filename, "rb",
395 (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
396 NULL);
397 if (!md.stream) {
398 RETURN_FALSE;
399 }
400
401 array_init(return_value);
402
403 tok_last = TOK_EOF;
404
405 while (!done && (tok = php_next_meta_token(&md TSRMLS_CC)) != TOK_EOF) {
406 if (tok == TOK_ID) {
407 if (tok_last == TOK_OPENTAG) {
408 md.in_meta = !strcasecmp("meta", md.token_data);
409 } else if (tok_last == TOK_SLASH && in_tag) {
410 if (strcasecmp("head", md.token_data) == 0) {
411 /* We are done here! */
412 done = 1;
413 }
414 } else if (tok_last == TOK_EQUAL && looking_for_val) {
415 if (saw_name) {
416 STR_FREE(name);
417 /* Get the NAME attr (Single word attr, non-quoted) */
418 temp = name = estrndup(md.token_data, md.token_len);
419
420 while (temp && *temp) {
421 if (strchr(PHP_META_UNSAFE, *temp)) {
422 *temp = '_';
423 }
424 temp++;
425 }
426
427 have_name = 1;
428 } else if (saw_content) {
429 STR_FREE(value);
430 /* Get the CONTENT attr (Single word attr, non-quoted) */
431 if (PG(magic_quotes_runtime)) {
432 value = php_addslashes(md.token_data, 0, &md.token_len, 0 TSRMLS_CC);
433 } else {
434 value = estrndup(md.token_data, md.token_len);
435 }
436
437 have_content = 1;
438 }
439
440 looking_for_val = 0;
441 } else {
442 if (md.in_meta) {
443 if (strcasecmp("name", md.token_data) == 0) {
444 saw_name = 1;
445 saw_content = 0;
446 looking_for_val = 1;
447 } else if (strcasecmp("content", md.token_data) == 0) {
448 saw_name = 0;
449 saw_content = 1;
450 looking_for_val = 1;
451 }
452 }
453 }
454 } else if (tok == TOK_STRING && tok_last == TOK_EQUAL && looking_for_val) {
455 if (saw_name) {
456 STR_FREE(name);
457 /* Get the NAME attr (Quoted single/double) */
458 temp = name = estrndup(md.token_data, md.token_len);
459
460 while (temp && *temp) {
461 if (strchr(PHP_META_UNSAFE, *temp)) {
462 *temp = '_';
463 }
464 temp++;
465 }
466
467 have_name = 1;
468 } else if (saw_content) {
469 STR_FREE(value);
470 /* Get the CONTENT attr (Single word attr, non-quoted) */
471 if (PG(magic_quotes_runtime)) {
472 value = php_addslashes(md.token_data, 0, &md.token_len, 0 TSRMLS_CC);
473 } else {
474 value = estrndup(md.token_data, md.token_len);
475 }
476
477 have_content = 1;
478 }
479
480 looking_for_val = 0;
481 } else if (tok == TOK_OPENTAG) {
482 if (looking_for_val) {
483 looking_for_val = 0;
484 have_name = saw_name = 0;
485 have_content = saw_content = 0;
486 }
487 in_tag = 1;
488 } else if (tok == TOK_CLOSETAG) {
489 if (have_name) {
490 /* For BC */
491 php_strtolower(name, strlen(name));
492 if (have_content) {
493 add_assoc_string(return_value, name, value, 1);
494 } else {
495 add_assoc_string(return_value, name, "", 1);
496 }
497
498 efree(name);
499 STR_FREE(value);
500 } else if (have_content) {
501 efree(value);
502 }
503
504 name = value = NULL;
505
506 /* Reset all of our flags */
507 in_tag = looking_for_val = 0;
508 have_name = saw_name = 0;
509 have_content = saw_content = 0;
510 md.in_meta = 0;
511 }
512
513 tok_last = tok;
514
515 if (md.token_data)
516 efree(md.token_data);
517
518 md.token_data = NULL;
519 }
520
521 STR_FREE(value);
522 STR_FREE(name);
523 php_stream_close(md.stream);
524 }
525 /* }}} */
526
527 /* {{{ proto string file_get_contents(string filename [, bool use_include_path [, resource context [, long offset [, long maxlen]]]])
528 Read the entire file into a string */
PHP_FUNCTION(file_get_contents)529 PHP_FUNCTION(file_get_contents)
530 {
531 char *filename;
532 int filename_len;
533 char *contents;
534 zend_bool use_include_path = 0;
535 php_stream *stream;
536 int len;
537 long offset = -1;
538 long maxlen = PHP_STREAM_COPY_ALL;
539 zval *zcontext = NULL;
540 php_stream_context *context = NULL;
541
542 /* Parse arguments */
543 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
544 return;
545 }
546
547 if (strlen(filename) != filename_len) {
548 RETURN_FALSE;
549 }
550
551 if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
552 php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
553 RETURN_FALSE;
554 }
555
556 context = php_stream_context_from_zval(zcontext, 0);
557
558 stream = php_stream_open_wrapper_ex(filename, "rb",
559 (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
560 NULL, context);
561 if (!stream) {
562 RETURN_FALSE;
563 }
564
565 if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
566 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
567 php_stream_close(stream);
568 RETURN_FALSE;
569 }
570
571 if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
572
573 if (PG(magic_quotes_runtime)) {
574 contents = php_addslashes(contents, len, &len, 1 TSRMLS_CC); /* 1 = free source string */
575 }
576
577 RETVAL_STRINGL(contents, len, 0);
578 } else if (len == 0) {
579 RETVAL_EMPTY_STRING();
580 } else {
581 RETVAL_FALSE;
582 }
583
584 php_stream_close(stream);
585 }
586 /* }}} */
587
588 /* {{{ proto int file_put_contents(string file, mixed data [, int flags [, resource context]])
589 Write/Create a file with contents data and return the number of bytes written */
PHP_FUNCTION(file_put_contents)590 PHP_FUNCTION(file_put_contents)
591 {
592 php_stream *stream;
593 char *filename;
594 int filename_len;
595 zval *data;
596 int numbytes = 0;
597 long flags = 0;
598 zval *zcontext = NULL;
599 php_stream_context *context = NULL;
600 php_stream *srcstream = NULL;
601 char mode[3] = "wb";
602
603 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|lr!", &filename, &filename_len, &data, &flags, &zcontext) == FAILURE) {
604 return;
605 }
606
607 if (strlen(filename) != filename_len) {
608 RETURN_FALSE;
609 }
610
611 if (Z_TYPE_P(data) == IS_RESOURCE) {
612 php_stream_from_zval(srcstream, &data);
613 }
614
615 context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
616
617 if (flags & PHP_FILE_APPEND) {
618 mode[0] = 'a';
619 } else if (flags & LOCK_EX) {
620 /* check to make sure we are dealing with a regular file */
621 if (php_memnstr(filename, "://", sizeof("://") - 1, filename + filename_len)) {
622 if (strncasecmp(filename, "file://", sizeof("file://") - 1)) {
623 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks may only be set for regular files");
624 RETURN_FALSE;
625 }
626 }
627 mode[0] = 'c';
628 }
629 mode[2] = '\0';
630
631 stream = php_stream_open_wrapper_ex(filename, mode, ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
632 if (stream == NULL) {
633 RETURN_FALSE;
634 }
635
636 if (flags & LOCK_EX && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) {
637 php_stream_close(stream);
638 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks are not supported for this stream");
639 RETURN_FALSE;
640 }
641
642 if (mode[0] == 'c') {
643 php_stream_truncate_set_size(stream, 0);
644 }
645
646 switch (Z_TYPE_P(data)) {
647 case IS_RESOURCE: {
648 size_t len;
649 if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
650 numbytes = -1;
651 } else {
652 numbytes = len;
653 }
654 break;
655 }
656 case IS_NULL:
657 case IS_LONG:
658 case IS_DOUBLE:
659 case IS_BOOL:
660 case IS_CONSTANT:
661 convert_to_string_ex(&data);
662
663 case IS_STRING:
664 if (Z_STRLEN_P(data)) {
665 numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
666 if (numbytes != Z_STRLEN_P(data)) {
667 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data));
668 numbytes = -1;
669 }
670 }
671 break;
672
673 case IS_ARRAY:
674 if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
675 int bytes_written;
676 zval **tmp;
677 HashPosition pos;
678
679 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
680 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &tmp, &pos) == SUCCESS) {
681 if (Z_TYPE_PP(tmp) != IS_STRING) {
682 SEPARATE_ZVAL(tmp);
683 convert_to_string(*tmp);
684 }
685 if (Z_STRLEN_PP(tmp)) {
686 numbytes += Z_STRLEN_PP(tmp);
687 bytes_written = php_stream_write(stream, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
688 if (bytes_written < 0 || bytes_written != Z_STRLEN_PP(tmp)) {
689 if (bytes_written < 0) {
690 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN_PP(tmp), filename);
691 } else {
692 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", bytes_written, Z_STRLEN_PP(tmp));
693 }
694 numbytes = -1;
695 break;
696 }
697 }
698 zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos);
699 }
700 }
701 break;
702
703 case IS_OBJECT:
704 if (Z_OBJ_HT_P(data) != NULL) {
705 zval out;
706
707 if (zend_std_cast_object_tostring(data, &out, IS_STRING TSRMLS_CC) == SUCCESS) {
708 numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out));
709 if (numbytes != Z_STRLEN(out)) {
710 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out));
711 numbytes = -1;
712 }
713 zval_dtor(&out);
714 break;
715 }
716 }
717 default:
718 numbytes = -1;
719 break;
720 }
721 php_stream_close(stream);
722
723 if (numbytes < 0) {
724 RETURN_FALSE;
725 }
726
727 RETURN_LONG(numbytes);
728 }
729 /* }}} */
730
731 #define PHP_FILE_BUF_SIZE 80
732
733 /* {{{ proto array file(string filename [, int flags[, resource context]])
734 Read entire file into an array */
PHP_FUNCTION(file)735 PHP_FUNCTION(file)
736 {
737 char *filename;
738 int filename_len;
739 char *slashed, *target_buf=NULL, *p, *s, *e;
740 register int i = 0;
741 int target_len, len;
742 char eol_marker = '\n';
743 long flags = 0;
744 zend_bool use_include_path;
745 zend_bool include_new_line;
746 zend_bool skip_blank_lines;
747 php_stream *stream;
748 zval *zcontext = NULL;
749 php_stream_context *context = NULL;
750
751 /* Parse arguments */
752 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr!", &filename, &filename_len, &flags, &zcontext) == FAILURE) {
753 return;
754 }
755
756 if (strlen(filename) != filename_len) {
757 RETURN_FALSE;
758 }
759
760 if (flags < 0 || flags > (PHP_FILE_USE_INCLUDE_PATH | PHP_FILE_IGNORE_NEW_LINES | PHP_FILE_SKIP_EMPTY_LINES | PHP_FILE_NO_DEFAULT_CONTEXT)) {
761 php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%ld' flag is not supported", flags);
762 RETURN_FALSE;
763 }
764
765 use_include_path = flags & PHP_FILE_USE_INCLUDE_PATH;
766 include_new_line = !(flags & PHP_FILE_IGNORE_NEW_LINES);
767 skip_blank_lines = flags & PHP_FILE_SKIP_EMPTY_LINES;
768
769 context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
770
771 stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
772 if (!stream) {
773 RETURN_FALSE;
774 }
775
776 /* Initialize return array */
777 array_init(return_value);
778
779 if ((target_len = php_stream_copy_to_mem(stream, &target_buf, PHP_STREAM_COPY_ALL, 0))) {
780 s = target_buf;
781 e = target_buf + target_len;
782
783 if (!(p = php_stream_locate_eol(stream, target_buf, target_len TSRMLS_CC))) {
784 p = e;
785 goto parse_eol;
786 }
787
788 if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
789 eol_marker = '\r';
790 }
791
792 /* for performance reasons the code is duplicated, so that the if (include_new_line)
793 * will not need to be done for every single line in the file. */
794 if (include_new_line) {
795 do {
796 p++;
797 parse_eol:
798 if (PG(magic_quotes_runtime)) {
799 /* s is in target_buf which is freed at the end of the function */
800 slashed = php_addslashes(s, (p-s), &len, 0 TSRMLS_CC);
801 add_index_stringl(return_value, i++, slashed, len, 0);
802 } else {
803 add_index_stringl(return_value, i++, estrndup(s, p-s), p-s, 0);
804 }
805 s = p;
806 } while ((p = memchr(p, eol_marker, (e-p))));
807 } else {
808 do {
809 int windows_eol = 0;
810 if (p != target_buf && eol_marker == '\n' && *(p - 1) == '\r') {
811 windows_eol++;
812 }
813 if (skip_blank_lines && !(p-s-windows_eol)) {
814 s = ++p;
815 continue;
816 }
817 if (PG(magic_quotes_runtime)) {
818 /* s is in target_buf which is freed at the end of the function */
819 slashed = php_addslashes(s, (p-s-windows_eol), &len, 0 TSRMLS_CC);
820 add_index_stringl(return_value, i++, slashed, len, 0);
821 } else {
822 add_index_stringl(return_value, i++, estrndup(s, p-s-windows_eol), p-s-windows_eol, 0);
823 }
824 s = ++p;
825 } while ((p = memchr(p, eol_marker, (e-p))));
826 }
827
828 /* handle any left overs of files without new lines */
829 if (s != e) {
830 p = e;
831 goto parse_eol;
832 }
833 }
834
835 if (target_buf) {
836 efree(target_buf);
837 }
838 php_stream_close(stream);
839 }
840 /* }}} */
841
842 /* {{{ proto string tempnam(string dir, string prefix)
843 Create a unique filename in a directory */
PHP_FUNCTION(tempnam)844 PHP_FUNCTION(tempnam)
845 {
846 char *dir, *prefix;
847 int dir_len, prefix_len;
848 size_t p_len;
849 char *opened_path;
850 char *p;
851 int fd;
852
853 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
854 return;
855 }
856
857 if (strlen(dir) != dir_len) {
858 RETURN_FALSE;
859 }
860
861 if (strlen(prefix) != prefix_len) {
862 RETURN_FALSE;
863 }
864
865 if (PG(safe_mode) &&(!php_checkuid(dir, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
866 RETURN_FALSE;
867 }
868
869 if (php_check_open_basedir(dir TSRMLS_CC)) {
870 RETURN_FALSE;
871 }
872
873 php_basename(prefix, prefix_len, NULL, 0, &p, &p_len TSRMLS_CC);
874 if (p_len > 64) {
875 p[63] = '\0';
876 }
877
878 RETVAL_FALSE;
879
880 if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) {
881 close(fd);
882 RETVAL_STRING(opened_path, 0);
883 }
884 efree(p);
885 }
886 /* }}} */
887
888 /* {{{ proto resource tmpfile(void)
889 Create a temporary file that will be deleted automatically after use */
PHP_NAMED_FUNCTION(php_if_tmpfile)890 PHP_NAMED_FUNCTION(php_if_tmpfile)
891 {
892 php_stream *stream;
893
894 if (zend_parse_parameters_none() == FAILURE) {
895 return;
896 }
897
898 stream = php_stream_fopen_tmpfile();
899
900 if (stream) {
901 php_stream_to_zval(stream, return_value);
902 } else {
903 RETURN_FALSE;
904 }
905 }
906 /* }}} */
907
908 /* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]])
909 Open a file or a URL and return a file pointer */
PHP_NAMED_FUNCTION(php_if_fopen)910 PHP_NAMED_FUNCTION(php_if_fopen)
911 {
912 char *filename, *mode;
913 int filename_len, mode_len;
914 zend_bool use_include_path = 0;
915 zval *zcontext = NULL;
916 php_stream *stream;
917 php_stream_context *context = NULL;
918
919 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
920 RETURN_FALSE;
921 }
922
923 if (strlen(filename) != filename_len) {
924 RETURN_FALSE;
925 }
926
927 context = php_stream_context_from_zval(zcontext, 0);
928
929 stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
930
931 if (stream == NULL) {
932 RETURN_FALSE;
933 }
934
935 php_stream_to_zval(stream, return_value);
936 }
937 /* }}} */
938
939 /* {{{ proto bool fclose(resource fp)
940 Close an open file pointer */
PHP_FUNCTION(fclose)941 PHPAPI PHP_FUNCTION(fclose)
942 {
943 zval *arg1;
944 php_stream *stream;
945
946 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
947 RETURN_FALSE;
948 }
949
950 PHP_STREAM_TO_ZVAL(stream, &arg1);
951
952 if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
953 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid stream resource", stream->rsrc_id);
954 RETURN_FALSE;
955 }
956
957 if (!stream->is_persistent) {
958 zend_list_delete(stream->rsrc_id);
959 } else {
960 php_stream_pclose(stream);
961 }
962
963 RETURN_TRUE;
964 }
965 /* }}} */
966
967 /* {{{ proto resource popen(string command, string mode)
968 Execute a command and open either a read or a write pipe to it */
PHP_FUNCTION(popen)969 PHP_FUNCTION(popen)
970 {
971 char *command, *mode;
972 int command_len, mode_len;
973 FILE *fp;
974 php_stream *stream;
975 char *posix_mode, *b, *buf = 0, *tmp;
976
977 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &command, &command_len, &mode, &mode_len) == FAILURE) {
978 return;
979 }
980
981 posix_mode = estrndup(mode, mode_len);
982 #ifndef PHP_WIN32
983 {
984 char *z = memchr(posix_mode, 'b', mode_len);
985 if (z) {
986 memmove(z, z + 1, mode_len - (z - posix_mode));
987 }
988 }
989 #endif
990 if (PG(safe_mode)){
991 b = strchr(command, ' ');
992 if (!b) {
993 b = strrchr(command, '/');
994 } else {
995 char *c;
996
997 c = command;
998 while((*b != '/') && (b != c)) {
999 b--;
1000 }
1001 if (b == c) {
1002 b = NULL;
1003 }
1004 }
1005
1006 if (b) {
1007 spprintf(&buf, 0, "%s%s", PG(safe_mode_exec_dir), b);
1008 } else {
1009 spprintf(&buf, 0, "%s/%s", PG(safe_mode_exec_dir), command);
1010 }
1011
1012 tmp = php_escape_shell_cmd(buf);
1013 fp = VCWD_POPEN(tmp, posix_mode);
1014 efree(tmp);
1015
1016 if (!fp) {
1017 php_error_docref2(NULL TSRMLS_CC, buf, posix_mode, E_WARNING, "%s", strerror(errno));
1018 efree(posix_mode);
1019 efree(buf);
1020 RETURN_FALSE;
1021 }
1022
1023 efree(buf);
1024
1025 } else {
1026 fp = VCWD_POPEN(command, posix_mode);
1027 if (!fp) {
1028 php_error_docref2(NULL TSRMLS_CC, command, posix_mode, E_WARNING, "%s", strerror(errno));
1029 efree(posix_mode);
1030 RETURN_FALSE;
1031 }
1032 }
1033 stream = php_stream_fopen_from_pipe(fp, mode);
1034
1035 if (stream == NULL) {
1036 php_error_docref2(NULL TSRMLS_CC, command, mode, E_WARNING, "%s", strerror(errno));
1037 RETVAL_FALSE;
1038 } else {
1039 php_stream_to_zval(stream, return_value);
1040 }
1041
1042 efree(posix_mode);
1043 }
1044 /* }}} */
1045
1046 /* {{{ proto int pclose(resource fp)
1047 Close a file pointer opened by popen() */
PHP_FUNCTION(pclose)1048 PHP_FUNCTION(pclose)
1049 {
1050 zval *arg1;
1051 php_stream *stream;
1052
1053 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1054 RETURN_FALSE;
1055 }
1056
1057 PHP_STREAM_TO_ZVAL(stream, &arg1);
1058
1059 zend_list_delete(stream->rsrc_id);
1060 RETURN_LONG(FG(pclose_ret));
1061 }
1062 /* }}} */
1063
1064 /* {{{ proto bool feof(resource fp)
1065 Test for end-of-file on a file pointer */
PHP_FUNCTION(feof)1066 PHPAPI PHP_FUNCTION(feof)
1067 {
1068 zval *arg1;
1069 php_stream *stream;
1070
1071 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1072 RETURN_FALSE;
1073 }
1074
1075 PHP_STREAM_TO_ZVAL(stream, &arg1);
1076
1077 if (php_stream_eof(stream)) {
1078 RETURN_TRUE;
1079 } else {
1080 RETURN_FALSE;
1081 }
1082 }
1083 /* }}} */
1084
1085 /* {{{ proto string fgets(resource fp[, int length])
1086 Get a line from file pointer */
PHP_FUNCTION(fgets)1087 PHPAPI PHP_FUNCTION(fgets)
1088 {
1089 zval *arg1;
1090 long len = 1024;
1091 char *buf = NULL;
1092 int argc = ZEND_NUM_ARGS();
1093 size_t line_len = 0;
1094 php_stream *stream;
1095
1096 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &len) == FAILURE) {
1097 RETURN_FALSE;
1098 }
1099
1100 PHP_STREAM_TO_ZVAL(stream, &arg1);
1101
1102 if (argc == 1) {
1103 /* ask streams to give us a buffer of an appropriate size */
1104 buf = php_stream_get_line(stream, NULL, 0, &line_len);
1105 if (buf == NULL) {
1106 goto exit_failed;
1107 }
1108 } else if (argc > 1) {
1109 if (len <= 0) {
1110 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
1111 RETURN_FALSE;
1112 }
1113
1114 buf = ecalloc(len + 1, sizeof(char));
1115 if (php_stream_get_line(stream, buf, len, &line_len) == NULL) {
1116 goto exit_failed;
1117 }
1118 }
1119
1120 if (PG(magic_quotes_runtime)) {
1121 Z_STRVAL_P(return_value) = php_addslashes(buf, line_len, &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
1122 Z_TYPE_P(return_value) = IS_STRING;
1123 } else {
1124 ZVAL_STRINGL(return_value, buf, line_len, 0);
1125 /* resize buffer if it's much larger than the result.
1126 * Only needed if the user requested a buffer size. */
1127 if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) {
1128 Z_STRVAL_P(return_value) = erealloc(buf, line_len + 1);
1129 }
1130 }
1131 return;
1132
1133 exit_failed:
1134 RETVAL_FALSE;
1135 if (buf) {
1136 efree(buf);
1137 }
1138 }
1139 /* }}} */
1140
1141 /* {{{ proto string fgetc(resource fp)
1142 Get a character from file pointer */
PHP_FUNCTION(fgetc)1143 PHPAPI PHP_FUNCTION(fgetc)
1144 {
1145 zval *arg1;
1146 char buf[2];
1147 int result;
1148 php_stream *stream;
1149
1150 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1151 RETURN_FALSE;
1152 }
1153
1154 PHP_STREAM_TO_ZVAL(stream, &arg1);
1155
1156 result = php_stream_getc(stream);
1157
1158 if (result == EOF) {
1159 RETVAL_FALSE;
1160 } else {
1161 buf[0] = result;
1162 buf[1] = '\0';
1163
1164 RETURN_STRINGL(buf, 1, 1);
1165 }
1166 }
1167 /* }}} */
1168
1169 /* {{{ proto string fgetss(resource fp [, int length [, string allowable_tags]])
1170 Get a line from file pointer and strip HTML tags */
PHP_FUNCTION(fgetss)1171 PHPAPI PHP_FUNCTION(fgetss)
1172 {
1173 zval *fd;
1174 long bytes = 0;
1175 size_t len = 0;
1176 size_t actual_len, retval_len;
1177 char *buf = NULL, *retval;
1178 php_stream *stream;
1179 char *allowed_tags=NULL;
1180 int allowed_tags_len=0;
1181
1182 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) {
1183 RETURN_FALSE;
1184 }
1185
1186 PHP_STREAM_TO_ZVAL(stream, &fd);
1187
1188 if (ZEND_NUM_ARGS() >= 2) {
1189 if (bytes <= 0) {
1190 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
1191 RETURN_FALSE;
1192 }
1193
1194 len = (size_t) bytes;
1195 buf = safe_emalloc(sizeof(char), (len + 1), 0);
1196 /*needed because recv doesnt set null char at end*/
1197 memset(buf, 0, len + 1);
1198 }
1199
1200 if ((retval = php_stream_get_line(stream, buf, len, &actual_len)) == NULL) {
1201 if (buf != NULL) {
1202 efree(buf);
1203 }
1204 RETURN_FALSE;
1205 }
1206
1207 retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len);
1208
1209 RETURN_STRINGL(retval, retval_len, 0);
1210 }
1211 /* }}} */
1212
1213 /* {{{ proto mixed fscanf(resource stream, string format [, string ...])
1214 Implements a mostly ANSI compatible fscanf() */
PHP_FUNCTION(fscanf)1215 PHP_FUNCTION(fscanf)
1216 {
1217 int result, format_len, type, argc = 0;
1218 zval ***args = NULL;
1219 zval *file_handle;
1220 char *buf, *format;
1221 size_t len;
1222 void *what;
1223
1224 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs*", &file_handle, &format, &format_len, &args, &argc) == FAILURE) {
1225 return;
1226 }
1227
1228 what = zend_fetch_resource(&file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, php_file_le_stream(), php_file_le_pstream());
1229
1230 /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
1231 * with a leak if we have an invalid filehandle. This needs changing
1232 * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */
1233 if (!what) {
1234 if (args) {
1235 efree(args);
1236 }
1237 RETURN_FALSE;
1238 }
1239
1240 buf = php_stream_get_line((php_stream *) what, NULL, 0, &len);
1241 if (buf == NULL) {
1242 if (args) {
1243 efree(args);
1244 }
1245 RETURN_FALSE;
1246 }
1247
1248 result = php_sscanf_internal(buf, format, argc, args, 0, &return_value TSRMLS_CC);
1249
1250 if (args) {
1251 efree(args);
1252 }
1253 efree(buf);
1254
1255 if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
1256 WRONG_PARAM_COUNT;
1257 }
1258 }
1259 /* }}} */
1260
1261 /* {{{ proto int fwrite(resource fp, string str [, int length])
1262 Binary-safe file write */
PHP_FUNCTION(fwrite)1263 PHPAPI PHP_FUNCTION(fwrite)
1264 {
1265 zval *arg1;
1266 char *arg2;
1267 int arg2len;
1268 int ret;
1269 int num_bytes;
1270 long arg3 = 0;
1271 char *buffer = NULL;
1272 php_stream *stream;
1273
1274 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &arg2, &arg2len, &arg3) == FAILURE) {
1275 RETURN_FALSE;
1276 }
1277
1278 if (ZEND_NUM_ARGS() == 2) {
1279 num_bytes = arg2len;
1280 } else {
1281 num_bytes = MAX(0, MIN((int)arg3, arg2len));
1282 }
1283
1284 if (!num_bytes) {
1285 RETURN_LONG(0);
1286 }
1287
1288 PHP_STREAM_TO_ZVAL(stream, &arg1);
1289
1290 if (PG(magic_quotes_runtime)) {
1291 buffer = estrndup(arg2, num_bytes);
1292 php_stripslashes(buffer, &num_bytes TSRMLS_CC);
1293 }
1294
1295 ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes);
1296 if (buffer) {
1297 efree(buffer);
1298 }
1299
1300 RETURN_LONG(ret);
1301 }
1302 /* }}} */
1303
1304 /* {{{ proto bool fflush(resource fp)
1305 Flushes output */
PHP_FUNCTION(fflush)1306 PHPAPI PHP_FUNCTION(fflush)
1307 {
1308 zval *arg1;
1309 int ret;
1310 php_stream *stream;
1311
1312 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1313 RETURN_FALSE;
1314 }
1315
1316 PHP_STREAM_TO_ZVAL(stream, &arg1);
1317
1318 ret = php_stream_flush(stream);
1319 if (ret) {
1320 RETURN_FALSE;
1321 }
1322 RETURN_TRUE;
1323 }
1324 /* }}} */
1325
1326 /* {{{ proto bool rewind(resource fp)
1327 Rewind the position of a file pointer */
PHP_FUNCTION(rewind)1328 PHPAPI PHP_FUNCTION(rewind)
1329 {
1330 zval *arg1;
1331 php_stream *stream;
1332
1333 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1334 RETURN_FALSE;
1335 }
1336
1337 PHP_STREAM_TO_ZVAL(stream, &arg1);
1338
1339 if (-1 == php_stream_rewind(stream)) {
1340 RETURN_FALSE;
1341 }
1342 RETURN_TRUE;
1343 }
1344 /* }}} */
1345
1346 /* {{{ proto int ftell(resource fp)
1347 Get file pointer's read/write position */
PHP_FUNCTION(ftell)1348 PHPAPI PHP_FUNCTION(ftell)
1349 {
1350 zval *arg1;
1351 long ret;
1352 php_stream *stream;
1353
1354 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1355 RETURN_FALSE;
1356 }
1357
1358 PHP_STREAM_TO_ZVAL(stream, &arg1);
1359
1360 ret = php_stream_tell(stream);
1361 if (ret == -1) {
1362 RETURN_FALSE;
1363 }
1364 RETURN_LONG(ret);
1365 }
1366 /* }}} */
1367
1368 /* {{{ proto int fseek(resource fp, int offset [, int whence])
1369 Seek on a file pointer */
PHP_FUNCTION(fseek)1370 PHPAPI PHP_FUNCTION(fseek)
1371 {
1372 zval *arg1;
1373 long arg2, whence = SEEK_SET;
1374 php_stream *stream;
1375
1376 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &arg2, &whence) == FAILURE) {
1377 RETURN_FALSE;
1378 }
1379
1380 PHP_STREAM_TO_ZVAL(stream, &arg1);
1381
1382 RETURN_LONG(php_stream_seek(stream, arg2, whence));
1383 }
1384 /* }}} */
1385
1386 /* {{{ php_mkdir
1387 */
1388
1389 /* DEPRECATED APIs: Use php_stream_mkdir() instead */
php_mkdir_ex(char * dir,long mode,int options TSRMLS_DC)1390 PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC)
1391 {
1392 int ret;
1393
1394 if (PG(safe_mode) && (!php_checkuid(dir, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
1395 return -1;
1396 }
1397
1398 if (php_check_open_basedir(dir TSRMLS_CC)) {
1399 return -1;
1400 }
1401
1402 if ((ret = VCWD_MKDIR(dir, (mode_t)mode)) < 0 && (options & REPORT_ERRORS)) {
1403 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
1404 }
1405
1406 return ret;
1407 }
1408
php_mkdir(char * dir,long mode TSRMLS_DC)1409 PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC)
1410 {
1411 return php_mkdir_ex(dir, mode, REPORT_ERRORS TSRMLS_CC);
1412 }
1413 /* }}} */
1414
1415 /* {{{ proto bool mkdir(string pathname [, int mode [, bool recursive [, resource context]]])
1416 Create a directory */
PHP_FUNCTION(mkdir)1417 PHP_FUNCTION(mkdir)
1418 {
1419 char *dir;
1420 int dir_len;
1421 zval *zcontext = NULL;
1422 long mode = 0777;
1423 zend_bool recursive = 0;
1424 php_stream_context *context;
1425
1426 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbr", &dir, &dir_len, &mode, &recursive, &zcontext) == FAILURE) {
1427 RETURN_FALSE;
1428 }
1429
1430 if (strlen(dir) != dir_len) {
1431 RETURN_FALSE;
1432 }
1433
1434 context = php_stream_context_from_zval(zcontext, 0);
1435
1436 RETURN_BOOL(php_stream_mkdir(dir, mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
1437 }
1438 /* }}} */
1439
1440 /* {{{ proto bool rmdir(string dirname[, resource context])
1441 Remove a directory */
PHP_FUNCTION(rmdir)1442 PHP_FUNCTION(rmdir)
1443 {
1444 char *dir;
1445 int dir_len;
1446 zval *zcontext = NULL;
1447 php_stream_context *context;
1448
1449 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
1450 RETURN_FALSE;
1451 }
1452
1453 if (strlen(dir) != dir_len) {
1454 RETURN_FALSE;
1455 }
1456
1457 context = php_stream_context_from_zval(zcontext, 0);
1458
1459 RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context));
1460 }
1461 /* }}} */
1462
1463 /* {{{ proto int readfile(string filename [, bool use_include_path[, resource context]])
1464 Output a file or a URL */
PHP_FUNCTION(readfile)1465 PHP_FUNCTION(readfile)
1466 {
1467 char *filename;
1468 int filename_len;
1469 int size = 0;
1470 zend_bool use_include_path = 0;
1471 zval *zcontext = NULL;
1472 php_stream *stream;
1473 php_stream_context *context = NULL;
1474
1475 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
1476 RETURN_FALSE;
1477 }
1478
1479 if (strlen(filename) != filename_len) {
1480 RETURN_FALSE;
1481 }
1482
1483 context = php_stream_context_from_zval(zcontext, 0);
1484
1485 stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
1486 if (stream) {
1487 size = php_stream_passthru(stream);
1488 php_stream_close(stream);
1489 RETURN_LONG(size);
1490 }
1491
1492 RETURN_FALSE;
1493 }
1494 /* }}} */
1495
1496 /* {{{ proto int umask([int mask])
1497 Return or change the umask */
PHP_FUNCTION(umask)1498 PHP_FUNCTION(umask)
1499 {
1500 long arg1 = 0;
1501 int oldumask;
1502
1503 oldumask = umask(077);
1504
1505 if (BG(umask) == -1) {
1506 BG(umask) = oldumask;
1507 }
1508
1509 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
1510 RETURN_FALSE;
1511 }
1512
1513 if (ZEND_NUM_ARGS() == 0) {
1514 umask(oldumask);
1515 } else {
1516 umask(arg1);
1517 }
1518
1519 RETURN_LONG(oldumask);
1520 }
1521 /* }}} */
1522
1523 /* {{{ proto int fpassthru(resource fp)
1524 Output all remaining data from a file pointer */
PHP_FUNCTION(fpassthru)1525 PHPAPI PHP_FUNCTION(fpassthru)
1526 {
1527 zval *arg1;
1528 int size;
1529 php_stream *stream;
1530
1531 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1532 RETURN_FALSE;
1533 }
1534
1535 PHP_STREAM_TO_ZVAL(stream, &arg1);
1536
1537 size = php_stream_passthru(stream);
1538 RETURN_LONG(size);
1539 }
1540 /* }}} */
1541
1542 /* {{{ proto bool rename(string old_name, string new_name[, resource context])
1543 Rename a file */
PHP_FUNCTION(rename)1544 PHP_FUNCTION(rename)
1545 {
1546 char *old_name, *new_name;
1547 int old_name_len, new_name_len;
1548 zval *zcontext = NULL;
1549 php_stream_wrapper *wrapper;
1550 php_stream_context *context;
1551
1552 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &old_name, &old_name_len, &new_name, &new_name_len, &zcontext) == FAILURE) {
1553 RETURN_FALSE;
1554 }
1555
1556 if (strlen(old_name) != old_name_len) {
1557 RETURN_FALSE;
1558 }
1559
1560 if (strlen(new_name) != new_name_len) {
1561 RETURN_FALSE;
1562 }
1563
1564 wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0 TSRMLS_CC);
1565
1566 if (!wrapper || !wrapper->wops) {
1567 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
1568 RETURN_FALSE;
1569 }
1570
1571 if (!wrapper->wops->rename) {
1572 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s wrapper does not support renaming", wrapper->wops->label ? wrapper->wops->label : "Source");
1573 RETURN_FALSE;
1574 }
1575
1576 if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0 TSRMLS_CC)) {
1577 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rename a file across wrapper types");
1578 RETURN_FALSE;
1579 }
1580
1581 context = php_stream_context_from_zval(zcontext, 0);
1582
1583 RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context TSRMLS_CC));
1584 }
1585 /* }}} */
1586
1587 /* {{{ proto bool unlink(string filename[, context context])
1588 Delete a file */
PHP_FUNCTION(unlink)1589 PHP_FUNCTION(unlink)
1590 {
1591 char *filename;
1592 int filename_len;
1593 php_stream_wrapper *wrapper;
1594 zval *zcontext = NULL;
1595 php_stream_context *context = NULL;
1596
1597 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &filename, &filename_len, &zcontext) == FAILURE) {
1598 RETURN_FALSE;
1599 }
1600
1601 if (strlen(filename) != filename_len) {
1602 RETURN_FALSE;
1603 }
1604
1605 context = php_stream_context_from_zval(zcontext, 0);
1606
1607 wrapper = php_stream_locate_url_wrapper(filename, NULL, 0 TSRMLS_CC);
1608
1609 if (!wrapper || !wrapper->wops) {
1610 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
1611 RETURN_FALSE;
1612 }
1613
1614 if (!wrapper->wops->unlink) {
1615 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
1616 RETURN_FALSE;
1617 }
1618 RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC));
1619 }
1620 /* }}} */
1621
1622 /* {{{ proto bool ftruncate(resource fp, int size)
1623 Truncate file to 'size' length */
PHP_NAMED_FUNCTION(php_if_ftruncate)1624 PHP_NAMED_FUNCTION(php_if_ftruncate)
1625 {
1626 zval *fp;
1627 long size;
1628 php_stream *stream;
1629
1630 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &fp, &size) == FAILURE) {
1631 RETURN_FALSE;
1632 }
1633
1634 PHP_STREAM_TO_ZVAL(stream, &fp);
1635
1636 if (!php_stream_truncate_supported(stream)) {
1637 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream!");
1638 RETURN_FALSE;
1639 }
1640
1641 RETURN_BOOL(0 == php_stream_truncate_set_size(stream, size));
1642 }
1643 /* }}} */
1644
1645 /* {{{ proto array fstat(resource fp)
1646 Stat() on a filehandle */
PHP_NAMED_FUNCTION(php_if_fstat)1647 PHP_NAMED_FUNCTION(php_if_fstat)
1648 {
1649 zval *fp;
1650 zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
1651 *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
1652 php_stream *stream;
1653 php_stream_statbuf stat_ssb;
1654 char *stat_sb_names[13] = {
1655 "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
1656 "size", "atime", "mtime", "ctime", "blksize", "blocks"
1657 };
1658
1659 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &fp) == FAILURE) {
1660 RETURN_FALSE;
1661 }
1662
1663 PHP_STREAM_TO_ZVAL(stream, &fp);
1664
1665 if (php_stream_stat(stream, &stat_ssb)) {
1666 RETURN_FALSE;
1667 }
1668
1669 array_init(return_value);
1670
1671 MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev);
1672 MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino);
1673 MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode);
1674 MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink);
1675 MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid);
1676 MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid);
1677 #ifdef HAVE_ST_RDEV
1678 MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev);
1679 #else
1680 MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
1681 #endif
1682 MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size);
1683 MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime);
1684 MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime);
1685 MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime);
1686 #ifdef HAVE_ST_BLKSIZE
1687 MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize);
1688 #else
1689 MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
1690 #endif
1691 #ifdef HAVE_ST_BLOCKS
1692 MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks);
1693 #else
1694 MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
1695 #endif
1696 /* Store numeric indexes in propper order */
1697 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
1698 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
1699 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
1700 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
1701 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
1702 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
1703 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
1704 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
1705 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
1706 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
1707 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
1708 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
1709 zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
1710
1711 /* Store string indexes referencing the same zval*/
1712 zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *)&stat_dev, sizeof(zval *), NULL);
1713 zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *)&stat_ino, sizeof(zval *), NULL);
1714 zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *)&stat_mode, sizeof(zval *), NULL);
1715 zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *)&stat_nlink, sizeof(zval *), NULL);
1716 zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *)&stat_uid, sizeof(zval *), NULL);
1717 zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *)&stat_gid, sizeof(zval *), NULL);
1718 zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *)&stat_rdev, sizeof(zval *), NULL);
1719 zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *)&stat_size, sizeof(zval *), NULL);
1720 zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *)&stat_atime, sizeof(zval *), NULL);
1721 zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *)&stat_mtime, sizeof(zval *), NULL);
1722 zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *)&stat_ctime, sizeof(zval *), NULL);
1723 zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *)&stat_blksize, sizeof(zval *), NULL);
1724 zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *)&stat_blocks, sizeof(zval *), NULL);
1725 }
1726 /* }}} */
1727
1728 /* {{{ proto bool copy(string source_file, string destination_file [, resource context])
1729 Copy a file */
PHP_FUNCTION(copy)1730 PHP_FUNCTION(copy)
1731 {
1732 char *source, *target;
1733 int source_len, target_len;
1734 zval *zcontext = NULL;
1735 php_stream_context *context;
1736
1737 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &source, &source_len, &target, &target_len, &zcontext) == FAILURE) {
1738 return;
1739 }
1740
1741 if (strlen(source) != source_len) {
1742 RETURN_FALSE;
1743 }
1744
1745 if (strlen(target) != target_len) {
1746 RETURN_FALSE;
1747 }
1748
1749 if (PG(safe_mode) &&(!php_checkuid(source, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
1750 RETURN_FALSE;
1751 }
1752
1753 if (php_check_open_basedir(source TSRMLS_CC)) {
1754 RETURN_FALSE;
1755 }
1756
1757 context = php_stream_context_from_zval(zcontext, 0);
1758
1759 if (php_copy_file_ctx(source, target, 0, context TSRMLS_CC) == SUCCESS) {
1760 RETURN_TRUE;
1761 } else {
1762 RETURN_FALSE;
1763 }
1764 }
1765 /* }}} */
1766
1767 /* {{{ php_copy_file
1768 */
php_copy_file(char * src,char * dest TSRMLS_DC)1769 PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC)
1770 {
1771 return php_copy_file_ctx(src, dest, ENFORCE_SAFE_MODE, NULL TSRMLS_CC);
1772 }
1773 /* }}} */
1774
1775 /* {{{ php_copy_file_ex
1776 */
php_copy_file_ex(char * src,char * dest,int src_chk TSRMLS_DC)1777 PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC)
1778 {
1779 return php_copy_file_ctx(src, dest, ENFORCE_SAFE_MODE, NULL TSRMLS_CC);
1780 }
1781 /* }}} */
1782
1783 /* {{{ php_copy_file_ctx
1784 */
php_copy_file_ctx(char * src,char * dest,int src_chk,php_stream_context * context TSRMLS_DC)1785 PHPAPI int php_copy_file_ctx(char *src, char *dest, int src_chk, php_stream_context *context TSRMLS_DC)
1786 {
1787 php_stream *srcstream = NULL, *deststream = NULL;
1788 int ret = FAILURE;
1789 php_stream_statbuf src_s, dest_s;
1790
1791 switch (php_stream_stat_path_ex(src, 0, &src_s, context)) {
1792 case -1:
1793 /* non-statable stream */
1794 goto safe_to_copy;
1795 break;
1796 case 0:
1797 break;
1798 default: /* failed to stat file, does not exist? */
1799 return ret;
1800 }
1801 if (S_ISDIR(src_s.sb.st_mode)) {
1802 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument to copy() function cannot be a directory");
1803 return FAILURE;
1804 }
1805
1806 switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, context)) {
1807 case -1:
1808 /* non-statable stream */
1809 goto safe_to_copy;
1810 break;
1811 case 0:
1812 break;
1813 default: /* failed to stat file, does not exist? */
1814 return ret;
1815 }
1816 if (S_ISDIR(dest_s.sb.st_mode)) {
1817 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument to copy() function cannot be a directory");
1818 return FAILURE;
1819 }
1820 if (!src_s.sb.st_ino || !dest_s.sb.st_ino) {
1821 goto no_stat;
1822 }
1823 if (src_s.sb.st_ino == dest_s.sb.st_ino && src_s.sb.st_dev == dest_s.sb.st_dev) {
1824 return ret;
1825 } else {
1826 goto safe_to_copy;
1827 }
1828 no_stat:
1829 {
1830 char *sp, *dp;
1831 int res;
1832
1833 if ((sp = expand_filepath(src, NULL TSRMLS_CC)) == NULL) {
1834 return ret;
1835 }
1836 if ((dp = expand_filepath(dest, NULL TSRMLS_CC)) == NULL) {
1837 efree(sp);
1838 goto safe_to_copy;
1839 }
1840
1841 res =
1842 #ifndef PHP_WIN32
1843 !strcmp(sp, dp);
1844 #else
1845 !strcasecmp(sp, dp);
1846 #endif
1847
1848 efree(sp);
1849 efree(dp);
1850 if (res) {
1851 return ret;
1852 }
1853 }
1854 safe_to_copy:
1855
1856 srcstream = php_stream_open_wrapper_ex(src, "rb", src_chk | REPORT_ERRORS, NULL, context);
1857
1858 if (!srcstream) {
1859 return ret;
1860 }
1861
1862 deststream = php_stream_open_wrapper_ex(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
1863
1864 if (srcstream && deststream) {
1865 ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL, NULL);
1866 }
1867 if (srcstream) {
1868 php_stream_close(srcstream);
1869 }
1870 if (deststream) {
1871 php_stream_close(deststream);
1872 }
1873 return ret;
1874 }
1875 /* }}} */
1876
1877 /* {{{ proto string fread(resource fp, int length)
1878 Binary-safe file read */
PHP_FUNCTION(fread)1879 PHPAPI PHP_FUNCTION(fread)
1880 {
1881 zval *arg1;
1882 long len;
1883 php_stream *stream;
1884
1885 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &len) == FAILURE) {
1886 RETURN_FALSE;
1887 }
1888
1889 PHP_STREAM_TO_ZVAL(stream, &arg1);
1890
1891 if (len <= 0) {
1892 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
1893 RETURN_FALSE;
1894 }
1895
1896 Z_STRVAL_P(return_value) = emalloc(len + 1);
1897 Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len);
1898
1899 /* needed because recv/read/gzread doesnt put a null at the end*/
1900 Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
1901
1902 if (PG(magic_quotes_runtime)) {
1903 Z_STRVAL_P(return_value) = php_addslashes(Z_STRVAL_P(return_value),
1904 Z_STRLEN_P(return_value), &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
1905 }
1906 Z_TYPE_P(return_value) = IS_STRING;
1907 }
1908 /* }}} */
1909
php_fgetcsv_lookup_trailing_spaces(const char * ptr,size_t len,const char delimiter TSRMLS_DC)1910 static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t len, const char delimiter TSRMLS_DC) /* {{{ */
1911 {
1912 int inc_len;
1913 unsigned char last_chars[2] = { 0, 0 };
1914
1915 while (len > 0) {
1916 inc_len = (*ptr == '\0' ? 1: php_mblen(ptr, len));
1917 switch (inc_len) {
1918 case -2:
1919 case -1:
1920 inc_len = 1;
1921 php_mblen(NULL, 0);
1922 break;
1923 case 0:
1924 goto quit_loop;
1925 case 1:
1926 default:
1927 last_chars[0] = last_chars[1];
1928 last_chars[1] = *ptr;
1929 break;
1930 }
1931 ptr += inc_len;
1932 len -= inc_len;
1933 }
1934 quit_loop:
1935 switch (last_chars[1]) {
1936 case '\n':
1937 if (last_chars[0] == '\r') {
1938 return ptr - 2;
1939 }
1940 /* break is omitted intentionally */
1941 case '\r':
1942 return ptr - 1;
1943 }
1944 return ptr;
1945 }
1946 /* }}} */
1947
1948 #define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field))
1949
1950 /* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])
1951 Format line as CSV and write to file pointer */
PHP_FUNCTION(fputcsv)1952 PHP_FUNCTION(fputcsv)
1953 {
1954 char delimiter = ','; /* allow this to be set as parameter */
1955 char enclosure = '"'; /* allow this to be set as parameter */
1956 const char escape_char = '\\';
1957 php_stream *stream;
1958 int ret;
1959 zval *fp = NULL, *fields = NULL, **field_tmp = NULL, field;
1960 char *delimiter_str = NULL, *enclosure_str = NULL;
1961 int delimiter_str_len = 0, enclosure_str_len = 0;
1962 HashPosition pos;
1963 int count, i = 0;
1964 smart_str csvline = {0};
1965
1966 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ss",
1967 &fp, &fields, &delimiter_str, &delimiter_str_len,
1968 &enclosure_str, &enclosure_str_len) == FAILURE) {
1969 return;
1970 }
1971
1972 if (delimiter_str != NULL) {
1973 /* Make sure that there is at least one character in string */
1974 if (delimiter_str_len < 1) {
1975 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
1976 RETURN_FALSE;
1977 } else if (delimiter_str_len > 1) {
1978 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
1979 }
1980
1981 /* use first character from string */
1982 delimiter = *delimiter_str;
1983 }
1984
1985 if (enclosure_str != NULL) {
1986 if (enclosure_str_len < 1) {
1987 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
1988 RETURN_FALSE;
1989 } else if (enclosure_str_len > 1) {
1990 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
1991 }
1992 /* use first character from string */
1993 enclosure = *enclosure_str;
1994 }
1995
1996 PHP_STREAM_TO_ZVAL(stream, &fp);
1997
1998 count = zend_hash_num_elements(Z_ARRVAL_P(fields));
1999 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
2000 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field_tmp, &pos) == SUCCESS) {
2001 field = **field_tmp;
2002
2003 if (Z_TYPE_PP(field_tmp) != IS_STRING) {
2004 zval_copy_ctor(&field);
2005 convert_to_string(&field);
2006 }
2007
2008 /* enclose a field that contains a delimiter, an enclosure character, or a newline */
2009 if (FPUTCSV_FLD_CHK(delimiter) ||
2010 FPUTCSV_FLD_CHK(enclosure) ||
2011 FPUTCSV_FLD_CHK(escape_char) ||
2012 FPUTCSV_FLD_CHK('\n') ||
2013 FPUTCSV_FLD_CHK('\r') ||
2014 FPUTCSV_FLD_CHK('\t') ||
2015 FPUTCSV_FLD_CHK(' ')
2016 ) {
2017 char *ch = Z_STRVAL(field);
2018 char *end = ch + Z_STRLEN(field);
2019 int escaped = 0;
2020
2021 smart_str_appendc(&csvline, enclosure);
2022 while (ch < end) {
2023 if (*ch == escape_char) {
2024 escaped = 1;
2025 } else if (!escaped && *ch == enclosure) {
2026 smart_str_appendc(&csvline, enclosure);
2027 } else {
2028 escaped = 0;
2029 }
2030 smart_str_appendc(&csvline, *ch);
2031 ch++;
2032 }
2033 smart_str_appendc(&csvline, enclosure);
2034 } else {
2035 smart_str_appendl(&csvline, Z_STRVAL(field), Z_STRLEN(field));
2036 }
2037
2038 if (++i != count) {
2039 smart_str_appendl(&csvline, &delimiter, 1);
2040 }
2041 zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);
2042
2043 if (Z_TYPE_PP(field_tmp) != IS_STRING) {
2044 zval_dtor(&field);
2045 }
2046 }
2047
2048 smart_str_appendc(&csvline, '\n');
2049 smart_str_0(&csvline);
2050
2051 if (!PG(magic_quotes_runtime)) {
2052 ret = php_stream_write(stream, csvline.c, csvline.len);
2053 } else {
2054 char *buffer = estrndup(csvline.c, csvline.len);
2055 int len = csvline.len;
2056 php_stripslashes(buffer, &len TSRMLS_CC);
2057 ret = php_stream_write(stream, buffer, len);
2058 efree(buffer);
2059 }
2060
2061 smart_str_free(&csvline);
2062
2063 RETURN_LONG(ret);
2064 }
2065 /* }}} */
2066
2067 /* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, string enclosure [, string escape]]]])
2068 Get line from file pointer and parse for CSV fields */
PHP_FUNCTION(fgetcsv)2069 PHP_FUNCTION(fgetcsv)
2070 {
2071 char delimiter = ','; /* allow this to be set as parameter */
2072 char enclosure = '"'; /* allow this to be set as parameter */
2073 char escape = '\\';
2074
2075 /* first section exactly as php_fgetss */
2076
2077 long len = 0;
2078 size_t buf_len;
2079 char *buf;
2080 php_stream *stream;
2081
2082 {
2083 zval *fd, **len_zv = NULL;
2084 char *delimiter_str = NULL;
2085 int delimiter_str_len = 0;
2086 char *enclosure_str = NULL;
2087 int enclosure_str_len = 0;
2088 char *escape_str = NULL;
2089 int escape_str_len = 0;
2090
2091 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|Zsss",
2092 &fd, &len_zv, &delimiter_str, &delimiter_str_len,
2093 &enclosure_str, &enclosure_str_len,
2094 &escape_str, &escape_str_len) == FAILURE
2095 ) {
2096 return;
2097 }
2098
2099 if (delimiter_str != NULL) {
2100 /* Make sure that there is at least one character in string */
2101 if (delimiter_str_len < 1) {
2102 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
2103 RETURN_FALSE;
2104 } else if (delimiter_str_len > 1) {
2105 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
2106 }
2107
2108 /* use first character from string */
2109 delimiter = delimiter_str[0];
2110 }
2111
2112 if (enclosure_str != NULL) {
2113 if (enclosure_str_len < 1) {
2114 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
2115 RETURN_FALSE;
2116 } else if (enclosure_str_len > 1) {
2117 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
2118 }
2119
2120 /* use first character from string */
2121 enclosure = enclosure_str[0];
2122 }
2123
2124 if (escape_str != NULL) {
2125 if (escape_str_len < 1) {
2126 php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be character");
2127 RETURN_FALSE;
2128 } else if (escape_str_len > 1) {
2129 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "escape must be a single character");
2130 }
2131
2132 escape = escape_str[0];
2133 }
2134
2135 if (len_zv != NULL && Z_TYPE_PP(len_zv) != IS_NULL) {
2136 convert_to_long_ex(len_zv);
2137 len = Z_LVAL_PP(len_zv);
2138 if (len < 0) {
2139 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative");
2140 RETURN_FALSE;
2141 } else if (len == 0) {
2142 len = -1;
2143 }
2144 } else {
2145 len = -1;
2146 }
2147
2148 PHP_STREAM_TO_ZVAL(stream, &fd);
2149 }
2150
2151 if (len < 0) {
2152 if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) {
2153 RETURN_FALSE;
2154 }
2155 } else {
2156 buf = emalloc(len + 1);
2157 if (php_stream_get_line(stream, buf, len + 1, &buf_len) == NULL) {
2158 efree(buf);
2159 RETURN_FALSE;
2160 }
2161 }
2162
2163 php_fgetcsv(stream, delimiter, enclosure, escape, buf_len, buf, return_value TSRMLS_CC);
2164 }
2165 /* }}} */
2166
php_fgetcsv(php_stream * stream,char delimiter,char enclosure,char escape_char,size_t buf_len,char * buf,zval * return_value TSRMLS_DC)2167 PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char escape_char, size_t buf_len, char *buf, zval *return_value TSRMLS_DC) /* {{{ */
2168 {
2169 char *temp, *tptr, *bptr, *line_end, *limit;
2170 size_t temp_len, line_end_len;
2171 int inc_len;
2172 zend_bool first_field = 1;
2173
2174 /* initialize internal state */
2175 php_mblen(NULL, 0);
2176
2177 /* Now into new section that parses buf for delimiter/enclosure fields */
2178
2179 /* Strip trailing space from buf, saving end of line in case required for enclosure field */
2180
2181 bptr = buf;
2182 tptr = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len, delimiter TSRMLS_CC);
2183 line_end_len = buf_len - (size_t)(tptr - buf);
2184 line_end = limit = tptr;
2185
2186 /* reserve workspace for building each individual field */
2187 temp_len = buf_len;
2188 temp = emalloc(temp_len + line_end_len + 1);
2189
2190 /* Initialize return array */
2191 array_init(return_value);
2192
2193 /* Main loop to read CSV fields */
2194 /* NB this routine will return a single null entry for a blank line */
2195
2196 do {
2197 char *comp_end, *hunk_begin;
2198
2199 tptr = temp;
2200 inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2201 if (inc_len == 1) {
2202 char *tmp = bptr;
2203 while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) {
2204 tmp++;
2205 }
2206 if (*tmp == enclosure) {
2207 bptr = tmp;
2208 }
2209 }
2210
2211 if (first_field && bptr == line_end) {
2212 add_next_index_null(return_value);
2213 break;
2214 }
2215 first_field = 0;
2216 /* 2. Read field, leaving bptr pointing at start of next field */
2217 if (inc_len != 0 && *bptr == enclosure) {
2218 int state = 0;
2219
2220 bptr++; /* move on to first character in field */
2221 hunk_begin = bptr;
2222
2223 /* 2A. handle enclosure delimited field */
2224 for (;;) {
2225 switch (inc_len) {
2226 case 0:
2227 switch (state) {
2228 case 2:
2229 memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2230 tptr += (bptr - hunk_begin - 1);
2231 hunk_begin = bptr;
2232 goto quit_loop_2;
2233
2234 case 1:
2235 memcpy(tptr, hunk_begin, bptr - hunk_begin);
2236 tptr += (bptr - hunk_begin);
2237 hunk_begin = bptr;
2238 /* break is omitted intentionally */
2239
2240 case 0: {
2241 char *new_buf;
2242 size_t new_len;
2243 char *new_temp;
2244
2245 if (hunk_begin != line_end) {
2246 memcpy(tptr, hunk_begin, bptr - hunk_begin);
2247 tptr += (bptr - hunk_begin);
2248 hunk_begin = bptr;
2249 }
2250
2251 /* add the embedded line end to the field */
2252 memcpy(tptr, line_end, line_end_len);
2253 tptr += line_end_len;
2254
2255 if (stream == NULL) {
2256 goto quit_loop_2;
2257 } else if ((new_buf = php_stream_get_line(stream, NULL, 0, &new_len)) == NULL) {
2258 /* we've got an unterminated enclosure,
2259 * assign all the data from the start of
2260 * the enclosure to end of data to the
2261 * last element */
2262 if ((size_t)temp_len > (size_t)(limit - buf)) {
2263 goto quit_loop_2;
2264 }
2265 zval_dtor(return_value);
2266 RETVAL_FALSE;
2267 goto out;
2268 }
2269 temp_len += new_len;
2270 new_temp = erealloc(temp, temp_len);
2271 tptr = new_temp + (size_t)(tptr - temp);
2272 temp = new_temp;
2273
2274 efree(buf);
2275 buf_len = new_len;
2276 bptr = buf = new_buf;
2277 hunk_begin = buf;
2278
2279 line_end = limit = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len, delimiter TSRMLS_CC);
2280 line_end_len = buf_len - (size_t)(limit - buf);
2281
2282 state = 0;
2283 } break;
2284 }
2285 break;
2286
2287 case -2:
2288 case -1:
2289 php_mblen(NULL, 0);
2290 /* break is omitted intentionally */
2291 case 1:
2292 /* we need to determine if the enclosure is
2293 * 'real' or is it escaped */
2294 switch (state) {
2295 case 1: /* escaped */
2296 bptr++;
2297 state = 0;
2298 break;
2299 case 2: /* embedded enclosure ? let's check it */
2300 if (*bptr != enclosure) {
2301 /* real enclosure */
2302 memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2303 tptr += (bptr - hunk_begin - 1);
2304 hunk_begin = bptr;
2305 goto quit_loop_2;
2306 }
2307 memcpy(tptr, hunk_begin, bptr - hunk_begin);
2308 tptr += (bptr - hunk_begin);
2309 bptr++;
2310 hunk_begin = bptr;
2311 state = 0;
2312 break;
2313 default:
2314 if (*bptr == enclosure) {
2315 state = 2;
2316 } else if (*bptr == escape_char) {
2317 state = 1;
2318 }
2319 bptr++;
2320 break;
2321 }
2322 break;
2323
2324 default:
2325 switch (state) {
2326 case 2:
2327 /* real enclosure */
2328 memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2329 tptr += (bptr - hunk_begin - 1);
2330 hunk_begin = bptr;
2331 goto quit_loop_2;
2332 case 1:
2333 bptr += inc_len;
2334 memcpy(tptr, hunk_begin, bptr - hunk_begin);
2335 tptr += (bptr - hunk_begin);
2336 hunk_begin = bptr;
2337 break;
2338 default:
2339 bptr += inc_len;
2340 break;
2341 }
2342 break;
2343 }
2344 inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2345 }
2346
2347 quit_loop_2:
2348 /* look up for a delimiter */
2349 for (;;) {
2350 switch (inc_len) {
2351 case 0:
2352 goto quit_loop_3;
2353
2354 case -2:
2355 case -1:
2356 inc_len = 1;
2357 php_mblen(NULL, 0);
2358 /* break is omitted intentionally */
2359 case 1:
2360 if (*bptr == delimiter) {
2361 goto quit_loop_3;
2362 }
2363 break;
2364 default:
2365 break;
2366 }
2367 bptr += inc_len;
2368 inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2369 }
2370
2371 quit_loop_3:
2372 memcpy(tptr, hunk_begin, bptr - hunk_begin);
2373 tptr += (bptr - hunk_begin);
2374 bptr += inc_len;
2375 comp_end = tptr;
2376 } else {
2377 /* 2B. Handle non-enclosure field */
2378
2379 hunk_begin = bptr;
2380
2381 for (;;) {
2382 switch (inc_len) {
2383 case 0:
2384 goto quit_loop_4;
2385 case -2:
2386 case -1:
2387 inc_len = 1;
2388 php_mblen(NULL, 0);
2389 /* break is omitted intentionally */
2390 case 1:
2391 if (*bptr == delimiter) {
2392 goto quit_loop_4;
2393 }
2394 break;
2395 default:
2396 break;
2397 }
2398 bptr += inc_len;
2399 inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2400 }
2401 quit_loop_4:
2402 memcpy(tptr, hunk_begin, bptr - hunk_begin);
2403 tptr += (bptr - hunk_begin);
2404
2405 comp_end = (char *)php_fgetcsv_lookup_trailing_spaces(temp, tptr - temp, delimiter TSRMLS_CC);
2406 if (*bptr == delimiter) {
2407 bptr++;
2408 }
2409 }
2410
2411 /* 3. Now pass our field back to php */
2412 *comp_end = '\0';
2413 add_next_index_stringl(return_value, temp, comp_end - temp, 1);
2414 } while (inc_len > 0);
2415
2416 out:
2417 efree(temp);
2418 if (stream) {
2419 efree(buf);
2420 }
2421 }
2422 /* }}} */
2423
2424 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2425 /* {{{ proto string realpath(string path)
2426 Return the resolved path */
PHP_FUNCTION(realpath)2427 PHP_FUNCTION(realpath)
2428 {
2429 char *filename;
2430 int filename_len;
2431 char resolved_path_buff[MAXPATHLEN];
2432
2433 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
2434 return;
2435 }
2436
2437 if (strlen(filename) != filename_len) {
2438 RETURN_FALSE;
2439 }
2440
2441 if (VCWD_REALPATH(filename, resolved_path_buff)) {
2442 if (PG(safe_mode) && (!php_checkuid(resolved_path_buff, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2443 RETURN_FALSE;
2444 }
2445
2446 if (php_check_open_basedir(resolved_path_buff TSRMLS_CC)) {
2447 RETURN_FALSE;
2448 }
2449
2450 #ifdef ZTS
2451 if (VCWD_ACCESS(resolved_path_buff, F_OK)) {
2452 RETURN_FALSE;
2453 }
2454 #endif
2455 RETURN_STRING(resolved_path_buff, 1);
2456 } else {
2457 RETURN_FALSE;
2458 }
2459 }
2460 /* }}} */
2461 #endif
2462
2463 /* See http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.2 */
2464 #define PHP_META_HTML401_CHARS "-_.:"
2465
2466 /* {{{ php_next_meta_token
2467 Tokenizes an HTML file for get_meta_tags */
php_next_meta_token(php_meta_tags_data * md TSRMLS_DC)2468 php_meta_tags_token php_next_meta_token(php_meta_tags_data *md TSRMLS_DC)
2469 {
2470 int ch = 0, compliment;
2471 char buff[META_DEF_BUFSIZE + 1];
2472
2473 memset((void *)buff, 0, META_DEF_BUFSIZE + 1);
2474
2475 while (md->ulc || (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)))) {
2476 if (php_stream_eof(md->stream)) {
2477 break;
2478 }
2479
2480 if (md->ulc) {
2481 ch = md->lc;
2482 md->ulc = 0;
2483 }
2484
2485 switch (ch) {
2486 case '<':
2487 return TOK_OPENTAG;
2488 break;
2489
2490 case '>':
2491 return TOK_CLOSETAG;
2492 break;
2493
2494 case '=':
2495 return TOK_EQUAL;
2496 break;
2497 case '/':
2498 return TOK_SLASH;
2499 break;
2500
2501 case '\'':
2502 case '"':
2503 compliment = ch;
2504 md->token_len = 0;
2505 while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && ch != compliment && ch != '<' && ch != '>') {
2506 buff[(md->token_len)++] = ch;
2507
2508 if (md->token_len == META_DEF_BUFSIZE) {
2509 break;
2510 }
2511 }
2512
2513 if (ch == '<' || ch == '>') {
2514 /* Was just an apostrohpe */
2515 md->ulc = 1;
2516 md->lc = ch;
2517 }
2518
2519 /* We don't need to alloc unless we are in a meta tag */
2520 if (md->in_meta) {
2521 md->token_data = (char *) emalloc(md->token_len + 1);
2522 memcpy(md->token_data, buff, md->token_len+1);
2523 }
2524
2525 return TOK_STRING;
2526 break;
2527
2528 case '\n':
2529 case '\r':
2530 case '\t':
2531 break;
2532
2533 case ' ':
2534 return TOK_SPACE;
2535 break;
2536
2537 default:
2538 if (isalnum(ch)) {
2539 md->token_len = 0;
2540 buff[(md->token_len)++] = ch;
2541 while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && (isalnum(ch) || strchr(PHP_META_HTML401_CHARS, ch))) {
2542 buff[(md->token_len)++] = ch;
2543
2544 if (md->token_len == META_DEF_BUFSIZE) {
2545 break;
2546 }
2547 }
2548
2549 /* This is ugly, but we have to replace ungetc */
2550 if (!isalpha(ch) && ch != '-') {
2551 md->ulc = 1;
2552 md->lc = ch;
2553 }
2554
2555 md->token_data = (char *) emalloc(md->token_len + 1);
2556 memcpy(md->token_data, buff, md->token_len+1);
2557
2558 return TOK_ID;
2559 } else {
2560 return TOK_OTHER;
2561 }
2562 break;
2563 }
2564 }
2565
2566 return TOK_EOF;
2567 }
2568 /* }}} */
2569
2570 #ifdef HAVE_FNMATCH
2571 /* {{{ proto bool fnmatch(string pattern, string filename [, int flags])
2572 Match filename against pattern */
PHP_FUNCTION(fnmatch)2573 PHP_FUNCTION(fnmatch)
2574 {
2575 char *pattern, *filename;
2576 int pattern_len, filename_len;
2577 long flags = 0;
2578
2579 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &pattern, &pattern_len, &filename, &filename_len, &flags) == FAILURE) {
2580 return;
2581 }
2582
2583 if (strlen(pattern) != pattern_len) {
2584 RETURN_FALSE;
2585 }
2586
2587 if (strlen(filename) != filename_len) {
2588 RETURN_FALSE;
2589 }
2590
2591 if (filename_len >= MAXPATHLEN) {
2592 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN);
2593 RETURN_FALSE;
2594 }
2595 if (pattern_len >= MAXPATHLEN) {
2596 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
2597 RETURN_FALSE;
2598 }
2599
2600 RETURN_BOOL( ! fnmatch( pattern, filename, flags ));
2601 }
2602 /* }}} */
2603 #endif
2604
2605 /* {{{ proto string sys_get_temp_dir()
2606 Returns directory path used for temporary files */
PHP_FUNCTION(sys_get_temp_dir)2607 PHP_FUNCTION(sys_get_temp_dir)
2608 {
2609 if (zend_parse_parameters_none() == FAILURE) {
2610 return;
2611 }
2612 RETURN_STRING((char *)php_get_temporary_directory(), 1);
2613 }
2614 /* }}} */
2615
2616 /*
2617 * Local variables:
2618 * tab-width: 4
2619 * c-basic-offset: 4
2620 * End:
2621 * vim600: noet sw=4 ts=4 fdm=marker
2622 * vim<600: noet sw=4 ts=4
2623 */
2624