20
20
21
21
#include "php.h"
22
22
#include "php_ini.h"
23
- #include "ext/standard/info.h"
24
23
#include "ext/standard/file.h"
24
+ #include "ext/standard/php_filestat.h"
25
+ #include "ext/standard/flock_compat.h"
26
+ #include "ext/standard/scanf.h"
25
27
#include "ext/standard/php_string.h"
26
- #include "zend_compile.h"
27
28
#include "zend_exceptions.h"
28
29
#include "zend_interfaces.h"
29
30
35
36
#include "spl_directory_arginfo.h"
36
37
#include "spl_exceptions.h"
37
38
38
- #include "php.h"
39
- #include "fopen_wrappers.h"
40
-
41
- #include "ext/standard/basic_functions.h"
42
- #include "ext/standard/php_filestat.h"
43
-
44
39
#define SPL_HAS_FLAG (flags , test_flag ) ((flags & test_flag) ? 1 : 0)
45
40
46
41
/* declare the class handlers */
@@ -57,6 +52,13 @@ PHPAPI zend_class_entry *spl_ce_GlobIterator;
57
52
PHPAPI zend_class_entry * spl_ce_SplFileObject ;
58
53
PHPAPI zend_class_entry * spl_ce_SplTempFileObject ;
59
54
55
+ // TODO Use standard Error
56
+ #define CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (spl_filesystem_object_pointer ) \
57
+ if (!(spl_filesystem_object_pointer)->u.file.stream) { \
58
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); \
59
+ RETURN_THROWS(); \
60
+ }
61
+
60
62
static void spl_filesystem_file_free_line (spl_filesystem_object * intern ) /* {{{ */
61
63
{
62
64
if (intern -> u .file .current_line ) {
@@ -1901,64 +1903,6 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent) /
1901
1903
return SUCCESS ;
1902
1904
} /* }}} */
1903
1905
1904
- static int spl_filesystem_file_call (spl_filesystem_object * intern , zend_function * func_ptr , int pass_num_args , zval * return_value , zval * arg2 ) /* {{{ */
1905
- {
1906
- zend_fcall_info fci ;
1907
- zend_fcall_info_cache fcic ;
1908
- zval * zresource_ptr = & intern -> u .file .zresource , * params ;
1909
- int result ;
1910
- int num_args = pass_num_args + (arg2 ? 2 : 1 );
1911
-
1912
- if (Z_ISUNDEF_P (zresource_ptr )) {
1913
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
1914
- return FAILURE ;
1915
- }
1916
-
1917
- params = (zval * )safe_emalloc (num_args , sizeof (zval ), 0 );
1918
- params [0 ] = * zresource_ptr ;
1919
-
1920
- if (arg2 ) {
1921
- params [1 ] = * arg2 ;
1922
- }
1923
-
1924
- if (zend_get_parameters_array_ex (pass_num_args , params + (arg2 ? 2 : 1 )) != SUCCESS ) {
1925
- efree (params );
1926
- WRONG_PARAM_COUNT_WITH_RETVAL (FAILURE );
1927
- }
1928
-
1929
- fci .size = sizeof (fci );
1930
- fci .object = NULL ;
1931
- fci .retval = return_value ;
1932
- fci .param_count = num_args ;
1933
- fci .params = params ;
1934
- fci .named_params = NULL ;
1935
- ZVAL_STR (& fci .function_name , func_ptr -> common .function_name );
1936
-
1937
- fcic .function_handler = func_ptr ;
1938
- fcic .called_scope = NULL ;
1939
- fcic .object = NULL ;
1940
-
1941
- result = zend_call_function (& fci , & fcic );
1942
-
1943
- if (result == FAILURE || Z_ISUNDEF_P (return_value )) {
1944
- RETVAL_FALSE ;
1945
- }
1946
-
1947
- efree (params );
1948
- return result ;
1949
- } /* }}} */
1950
-
1951
- #define FileFunctionCall (func_name , pass_num_args , arg2 ) /* {{{ */ \
1952
- { \
1953
- zend_function *func_ptr; \
1954
- func_ptr = (zend_function *)zend_hash_str_find_ptr(EG(function_table), #func_name, sizeof(#func_name) - 1); \
1955
- if (func_ptr == NULL) { \
1956
- zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Internal error, function %s() not found. Please report", #func_name); \
1957
- return; \
1958
- } \
1959
- spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2); \
1960
- } /* }}} */
1961
-
1962
1906
static int spl_filesystem_file_read_csv (spl_filesystem_object * intern , char delimiter , char enclosure , int escape , zval * return_value ) /* {{{ */
1963
1907
{
1964
1908
int ret = SUCCESS ;
@@ -2075,7 +2019,7 @@ static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object
2075
2019
2076
2020
static void spl_filesystem_file_rewind (zval * this_ptr , spl_filesystem_object * intern ) /* {{{ */
2077
2021
{
2078
- if (!intern -> u .file .stream ) {
2022
+ if (!intern -> u .file .stream ) {
2079
2023
zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2080
2024
return ;
2081
2025
}
@@ -2203,10 +2147,7 @@ PHP_METHOD(SplFileObject, eof)
2203
2147
RETURN_THROWS ();
2204
2148
}
2205
2149
2206
- if (!intern -> u .file .stream ) {
2207
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2208
- RETURN_THROWS ();
2209
- }
2150
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2210
2151
2211
2152
RETURN_BOOL (php_stream_eof (intern -> u .file .stream ));
2212
2153
} /* }}} */
@@ -2239,10 +2180,7 @@ PHP_METHOD(SplFileObject, fgets)
2239
2180
RETURN_THROWS ();
2240
2181
}
2241
2182
2242
- if (!intern -> u .file .stream ) {
2243
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2244
- RETURN_THROWS ();
2245
- }
2183
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2246
2184
2247
2185
if (spl_filesystem_file_read (intern , 0 ) == FAILURE ) {
2248
2186
RETURN_FALSE ;
@@ -2259,10 +2197,7 @@ PHP_METHOD(SplFileObject, current)
2259
2197
RETURN_THROWS ();
2260
2198
}
2261
2199
2262
- if (!intern -> u .file .stream ) {
2263
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2264
- RETURN_THROWS ();
2265
- }
2200
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2266
2201
2267
2202
if (!intern -> u .file .current_line && Z_ISUNDEF (intern -> u .file .current_zval )) {
2268
2203
spl_filesystem_file_read_line (ZEND_THIS , intern , 1 );
@@ -2382,15 +2317,6 @@ PHP_METHOD(SplFileObject, getChildren)
2382
2317
/* return NULL */
2383
2318
} /* }}} */
2384
2319
2385
- /* {{{ FileFunction */
2386
- #define FileFunction (func_name ) \
2387
- PHP_METHOD(SplFileObject, func_name) \
2388
- { \
2389
- spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); \
2390
- FileFunctionCall(func_name, ZEND_NUM_ARGS(), NULL); \
2391
- }
2392
- /* }}} */
2393
-
2394
2320
/* {{{ Return current line as csv */
2395
2321
PHP_METHOD (SplFileObject , fgetcsv )
2396
2322
{
@@ -2402,10 +2328,7 @@ PHP_METHOD(SplFileObject, fgetcsv)
2402
2328
2403
2329
if (zend_parse_parameters (ZEND_NUM_ARGS (), "|sss" , & delim , & d_len , & enclo , & e_len , & esc , & esc_len ) == SUCCESS ) {
2404
2330
2405
- if (!intern -> u .file .stream ) {
2406
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2407
- RETURN_THROWS ();
2408
- }
2331
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2409
2332
2410
2333
switch (ZEND_NUM_ARGS ())
2411
2334
{
@@ -2570,19 +2493,51 @@ PHP_METHOD(SplFileObject, getCsvControl)
2570
2493
}
2571
2494
/* }}} */
2572
2495
2573
- /* {{{ Portable file locking */
2574
- FileFunction (flock )
2496
+ static int flock_values [] = { LOCK_SH , LOCK_EX , LOCK_UN };
2497
+
2498
+ /* {{{ Portable file locking, copy pasted from ext/standard/file.c flock() function.
2499
+ * This is done to prevent this to fail if flock is disabled via disable_functions */
2500
+ PHP_METHOD (SplFileObject , flock )
2501
+ {
2502
+ spl_filesystem_object * intern = Z_SPLFILESYSTEM_P (ZEND_THIS );
2503
+ zval * wouldblock = NULL ;
2504
+ int act ;
2505
+ zend_long operation = 0 ;
2506
+
2507
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "l|z" , & operation , & wouldblock ) == FAILURE ) {
2508
+ RETURN_THROWS ();
2509
+ }
2510
+
2511
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2512
+
2513
+ act = operation & PHP_LOCK_UN ;
2514
+ if (act < 1 || act > 3 ) {
2515
+ zend_argument_value_error (1 , "must be either LOCK_SH, LOCK_EX, or LOCK_UN" );
2516
+ RETURN_THROWS ();
2517
+ }
2518
+
2519
+ if (wouldblock ) {
2520
+ ZEND_TRY_ASSIGN_REF_LONG (wouldblock , 0 );
2521
+ }
2522
+
2523
+ /* flock_values contains all possible actions if (operation & PHP_LOCK_NB) we won't block on the lock */
2524
+ act = flock_values [act - 1 ] | (operation & PHP_LOCK_NB ? LOCK_NB : 0 );
2525
+ if (php_stream_lock (intern -> u .file .stream , act )) {
2526
+ if (operation && errno == EWOULDBLOCK && wouldblock ) {
2527
+ ZEND_TRY_ASSIGN_REF_LONG (wouldblock , 1 );
2528
+ }
2529
+ RETURN_FALSE ;
2530
+ }
2531
+ RETURN_TRUE ;
2532
+ }
2575
2533
/* }}} */
2576
2534
2577
2535
/* {{{ Flush the file */
2578
2536
PHP_METHOD (SplFileObject , fflush )
2579
2537
{
2580
2538
spl_filesystem_object * intern = Z_SPLFILESYSTEM_P (ZEND_THIS );
2581
2539
2582
- if (!intern -> u .file .stream ) {
2583
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2584
- RETURN_THROWS ();
2585
- }
2540
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2586
2541
2587
2542
RETURN_BOOL (!php_stream_flush (intern -> u .file .stream ));
2588
2543
} /* }}} */
@@ -2593,10 +2548,7 @@ PHP_METHOD(SplFileObject, ftell)
2593
2548
spl_filesystem_object * intern = Z_SPLFILESYSTEM_P (ZEND_THIS );
2594
2549
zend_long ret ;
2595
2550
2596
- if (!intern -> u .file .stream ) {
2597
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2598
- RETURN_THROWS ();
2599
- }
2551
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2600
2552
2601
2553
ret = php_stream_tell (intern -> u .file .stream );
2602
2554
@@ -2617,10 +2569,7 @@ PHP_METHOD(SplFileObject, fseek)
2617
2569
RETURN_THROWS ();
2618
2570
}
2619
2571
2620
- if (!intern -> u .file .stream ) {
2621
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2622
- RETURN_THROWS ();
2623
- }
2572
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2624
2573
2625
2574
spl_filesystem_file_free_line (intern );
2626
2575
RETURN_LONG (php_stream_seek (intern -> u .file .stream , pos , (int )whence ));
@@ -2633,10 +2582,7 @@ PHP_METHOD(SplFileObject, fgetc)
2633
2582
char buf [2 ];
2634
2583
int result ;
2635
2584
2636
- if (!intern -> u .file .stream ) {
2637
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2638
- RETURN_THROWS ();
2639
- }
2585
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2640
2586
2641
2587
spl_filesystem_file_free_line (intern );
2642
2588
@@ -2660,28 +2606,35 @@ PHP_METHOD(SplFileObject, fpassthru)
2660
2606
{
2661
2607
spl_filesystem_object * intern = Z_SPLFILESYSTEM_P (ZEND_THIS );
2662
2608
2663
- if (!intern -> u .file .stream ) {
2664
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2665
- RETURN_THROWS ();
2666
- }
2609
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2667
2610
2668
2611
RETURN_LONG (php_stream_passthru (intern -> u .file .stream ));
2669
2612
} /* }}} */
2670
2613
2671
2614
/* {{{ Implements a mostly ANSI compatible fscanf() */
2672
2615
PHP_METHOD (SplFileObject , fscanf )
2673
2616
{
2617
+ int result , num_varargs = 0 ;
2618
+ zend_string * format_str ;
2619
+ zval * varargs = NULL ;
2674
2620
spl_filesystem_object * intern = Z_SPLFILESYSTEM_P (ZEND_THIS );
2675
2621
2676
- if (!intern -> u .file .stream ) {
2677
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2622
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "S*" , & format_str , & varargs , & num_varargs ) == FAILURE ) {
2678
2623
RETURN_THROWS ();
2679
2624
}
2680
2625
2681
- spl_filesystem_file_free_line (intern );
2682
- intern -> u .file .current_line_num ++ ;
2626
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2683
2627
2684
- FileFunctionCall (fscanf , ZEND_NUM_ARGS (), NULL );
2628
+ /* Get next line */
2629
+ if (spl_filesystem_file_read (intern , 0 ) == FAILURE ) {
2630
+ RETURN_THROWS ();
2631
+ }
2632
+
2633
+ result = php_sscanf_internal (intern -> u .file .current_line , ZSTR_VAL (format_str ), num_varargs , varargs , 0 , return_value );
2634
+
2635
+ if (SCAN_ERROR_WRONG_PARAM_COUNT == result ) {
2636
+ WRONG_PARAM_COUNT ;
2637
+ }
2685
2638
}
2686
2639
/* }}} */
2687
2640
@@ -2698,10 +2651,7 @@ PHP_METHOD(SplFileObject, fwrite)
2698
2651
RETURN_THROWS ();
2699
2652
}
2700
2653
2701
- if (!intern -> u .file .stream ) {
2702
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2703
- RETURN_THROWS ();
2704
- }
2654
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2705
2655
2706
2656
if (ZEND_NUM_ARGS () > 1 ) {
2707
2657
if (length >= 0 ) {
@@ -2732,10 +2682,7 @@ PHP_METHOD(SplFileObject, fread)
2732
2682
RETURN_THROWS ();
2733
2683
}
2734
2684
2735
- if (!intern -> u .file .stream ) {
2736
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2737
- RETURN_THROWS ();
2738
- }
2685
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2739
2686
2740
2687
if (length <= 0 ) {
2741
2688
php_error_docref (NULL , E_WARNING , "Length parameter must be greater than 0" );
@@ -2750,7 +2697,18 @@ PHP_METHOD(SplFileObject, fread)
2750
2697
}
2751
2698
2752
2699
/* {{{ Stat() on a filehandle */
2753
- FileFunction (fstat )
2700
+ PHP_METHOD (SplFileObject , fstat )
2701
+ {
2702
+ spl_filesystem_object * intern = Z_SPLFILESYSTEM_P (ZEND_THIS );
2703
+
2704
+ if (zend_parse_parameters_none () == FAILURE ) {
2705
+ RETURN_THROWS ();
2706
+ }
2707
+
2708
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2709
+
2710
+ php_fstat (intern -> u .file .stream , return_value );
2711
+ }
2754
2712
/* }}} */
2755
2713
2756
2714
/* {{{ Truncate file to 'size' length */
@@ -2763,10 +2721,7 @@ PHP_METHOD(SplFileObject, ftruncate)
2763
2721
RETURN_THROWS ();
2764
2722
}
2765
2723
2766
- if (!intern -> u .file .stream ) {
2767
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2768
- RETURN_THROWS ();
2769
- }
2724
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2770
2725
2771
2726
if (!php_stream_truncate_supported (intern -> u .file .stream )) {
2772
2727
zend_throw_exception_ex (spl_ce_LogicException , 0 , "Can't truncate file %s" , intern -> file_name );
@@ -2785,10 +2740,8 @@ PHP_METHOD(SplFileObject, seek)
2785
2740
if (zend_parse_parameters (ZEND_NUM_ARGS (), "l" , & line_pos ) == FAILURE ) {
2786
2741
RETURN_THROWS ();
2787
2742
}
2788
- if (!intern -> u .file .stream ) {
2789
- zend_throw_exception_ex (spl_ce_RuntimeException , 0 , "Object not initialized" );
2790
- RETURN_THROWS ();
2791
- }
2743
+
2744
+ CHECK_SPL_FILE_OBJECT_IS_INITIALIZED (intern );
2792
2745
2793
2746
if (line_pos < 0 ) {
2794
2747
zend_throw_exception_ex (spl_ce_LogicException , 0 , "Can't seek file %s to negative line " ZEND_LONG_FMT , intern -> file_name , line_pos );
0 commit comments