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