36
36
#include "fopen_wrappers.h" /* needed for is_url */
37
37
#include "Zend/zend_exceptions.h"
38
38
39
- /* {{{ macros and type definitions */
40
- typedef struct _php_fileinfo {
41
- zend_long options ;
42
- struct magic_set * magic ;
43
- } php_fileinfo ;
44
-
45
39
static zend_object_handlers finfo_object_handlers ;
46
40
zend_class_entry * finfo_class_entry ;
47
41
48
42
typedef struct _finfo_object {
49
- php_fileinfo * ptr ;
43
+ struct magic_set * magic ;
50
44
zend_object zo ;
51
45
} finfo_object ;
52
46
@@ -56,26 +50,12 @@ static inline finfo_object *php_finfo_fetch_object(zend_object *obj) {
56
50
57
51
#define Z_FINFO_P (zv ) php_finfo_fetch_object(Z_OBJ_P((zv)))
58
52
59
- #define FILEINFO_FROM_OBJECT (finfo , object ) \
60
- { \
61
- finfo_object *obj = Z_FINFO_P(object); \
62
- finfo = obj->ptr; \
63
- if (!finfo) { \
64
- zend_throw_error(NULL, "Invalid finfo object"); \
65
- RETURN_THROWS(); \
66
- } \
67
- }
68
-
69
53
/* {{{ finfo_objects_free */
70
54
static void finfo_objects_free (zend_object * object )
71
55
{
72
56
finfo_object * intern = php_finfo_fetch_object (object );
73
57
74
- if (intern -> ptr ) {
75
- magic_close (intern -> ptr -> magic );
76
- efree (intern -> ptr );
77
- }
78
-
58
+ magic_close (intern -> magic );
79
59
zend_object_std_dtor (& intern -> zo );
80
60
}
81
61
/* }}} */
@@ -153,7 +133,6 @@ PHP_FUNCTION(finfo_open)
153
133
zend_long options = MAGIC_NONE ;
154
134
char * file = NULL ;
155
135
size_t file_len = 0 ;
156
- php_fileinfo * finfo ;
157
136
zval * object = getThis ();
158
137
char resolved_path [MAXPATHLEN ];
159
138
zend_error_handling zeh ;
@@ -163,15 +142,10 @@ PHP_FUNCTION(finfo_open)
163
142
}
164
143
165
144
if (object ) {
166
- finfo_object * finfo_obj = Z_FINFO_P (object );
167
-
168
145
zend_replace_error_handling (EH_THROW , NULL , & zeh );
169
146
170
- if (finfo_obj -> ptr ) {
171
- magic_close (finfo_obj -> ptr -> magic );
172
- efree (finfo_obj -> ptr );
173
- finfo_obj -> ptr = NULL ;
174
- }
147
+ magic_close (Z_FINFO_P (object )-> magic );
148
+ Z_FINFO_P (object )-> magic = NULL ;
175
149
}
176
150
177
151
if (file_len == 0 ) {
@@ -199,13 +173,9 @@ PHP_FUNCTION(finfo_open)
199
173
file = resolved_path ;
200
174
}
201
175
202
- finfo = emalloc ( sizeof ( php_fileinfo ) );
176
+ struct magic_set * magic = magic_open ( options );
203
177
204
- finfo -> options = options ;
205
- finfo -> magic = magic_open (options );
206
-
207
- if (finfo -> magic == NULL ) {
208
- efree (finfo );
178
+ if (magic == NULL ) {
209
179
php_error_docref (NULL , E_WARNING , "Invalid mode '" ZEND_LONG_FMT "'." , options );
210
180
if (object ) {
211
181
zend_restore_error_handling (& zeh );
@@ -216,10 +186,9 @@ PHP_FUNCTION(finfo_open)
216
186
RETURN_FALSE ;
217
187
}
218
188
219
- if (magic_load (finfo -> magic , file ) == -1 ) {
189
+ if (magic_load (magic , file ) == -1 ) {
220
190
php_error_docref (NULL , E_WARNING , "Failed to load magic database at \"%s\"" , file );
221
- magic_close (finfo -> magic );
222
- efree (finfo );
191
+ magic_close (magic );
223
192
if (object ) {
224
193
zend_restore_error_handling (& zeh );
225
194
if (!EG (exception )) {
@@ -230,14 +199,13 @@ PHP_FUNCTION(finfo_open)
230
199
}
231
200
232
201
if (object ) {
233
- finfo_object * obj ;
234
202
zend_restore_error_handling (& zeh );
235
- obj = Z_FINFO_P (object );
236
- obj -> ptr = finfo ;
203
+ finfo_object * obj = Z_FINFO_P (object );
204
+ obj -> magic = magic ;
237
205
} else {
238
206
zend_object * zobj = finfo_objects_new (finfo_class_entry );
239
207
finfo_object * obj = php_finfo_fetch_object (zobj );
240
- obj -> ptr = finfo ;
208
+ obj -> magic = magic ;
241
209
RETURN_OBJ (zobj );
242
210
}
243
211
}
@@ -260,18 +228,20 @@ PHP_FUNCTION(finfo_close)
260
228
PHP_FUNCTION (finfo_set_flags )
261
229
{
262
230
zend_long options ;
263
- php_fileinfo * finfo ;
264
231
zval * self ;
265
232
266
233
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Ol" , & self , finfo_class_entry , & options ) == FAILURE ) {
267
234
RETURN_THROWS ();
268
235
}
269
- FILEINFO_FROM_OBJECT (finfo , self );
236
+
237
+ if (!Z_FINFO_P (self )-> magic ) {
238
+ zend_throw_error (NULL , "Invalid finfo object" );
239
+ RETURN_THROWS ();
240
+ }
270
241
271
242
/* We do not check the return value as it can only ever fail if options contains MAGIC_PRESERVE_ATIME
272
243
* and the system neither has utime(3) nor utimes(2). Something incredibly unlikely. */
273
- magic_setflags (finfo -> magic , options );
274
- finfo -> options = options ;
244
+ magic_setflags (Z_FINFO_P (self )-> magic , options );
275
245
276
246
RETURN_TRUE ;
277
247
}
@@ -331,13 +301,17 @@ PHP_FUNCTION(finfo_file)
331
301
zend_string * path = NULL ;
332
302
zend_long options = 0 ;
333
303
zval * zcontext = NULL ;
334
- php_fileinfo * finfo = NULL ;
335
304
336
305
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "OP|lr!" , & self , finfo_class_entry , & path , & options , & zcontext ) == FAILURE ) {
337
306
RETURN_THROWS ();
338
307
}
339
- FILEINFO_FROM_OBJECT (finfo , self );
340
- struct magic_set * magic = finfo -> magic ;
308
+
309
+ if (!Z_FINFO_P (self )-> magic ) {
310
+ zend_throw_error (NULL , "Invalid finfo object" );
311
+ RETURN_THROWS ();
312
+ }
313
+
314
+ struct magic_set * magic = Z_FINFO_P (self )-> magic ;
341
315
342
316
if (UNEXPECTED (ZSTR_LEN (path ) == 0 )) {
343
317
zend_argument_must_not_be_empty_error (2 );
@@ -349,16 +323,18 @@ PHP_FUNCTION(finfo_file)
349
323
}
350
324
351
325
/* Set options for the current file/buffer. */
326
+ int old_options = magic_getflags (magic );
352
327
if (options ) {
353
328
/* We do not check the return value as it can only ever fail if options contains MAGIC_PRESERVE_ATIME
354
329
* and the system neither has utime(3) nor utimes(2). Something incredibly unlikely. */
355
330
magic_setflags (magic , options );
356
331
}
357
332
358
333
const char * ret_val = php_fileinfo_from_path (magic , path , context );
334
+
359
335
/* Restore options */
360
336
if (options ) {
361
- magic_setflags (magic , finfo -> options );
337
+ magic_setflags (magic , old_options );
362
338
}
363
339
364
340
if (UNEXPECTED (ret_val == NULL )) {
@@ -375,24 +351,31 @@ PHP_FUNCTION(finfo_buffer)
375
351
zend_string * buffer = NULL ;
376
352
zend_long options = 0 ;
377
353
zval * dummy_context = NULL ;
378
- php_fileinfo * finfo = NULL ;
379
354
380
355
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "OS|lr!" , & self , finfo_class_entry , & buffer , & options , & dummy_context ) == FAILURE ) {
381
356
RETURN_THROWS ();
382
357
}
383
- FILEINFO_FROM_OBJECT (finfo , self );
384
- struct magic_set * magic = finfo -> magic ;
358
+
359
+ if (!Z_FINFO_P (self )-> magic ) {
360
+ zend_throw_error (NULL , "Invalid finfo object" );
361
+ RETURN_THROWS ();
362
+ }
363
+
364
+ struct magic_set * magic = Z_FINFO_P (self )-> magic ;
385
365
386
366
/* Set options for the current file/buffer. */
367
+ int old_options = magic_getflags (magic );
387
368
if (options ) {
369
+ /* We do not check the return value as it can only ever fail if options contains MAGIC_PRESERVE_ATIME
370
+ * and the system neither has utime(3) nor utimes(2). Something incredibly unlikely. */
388
371
magic_setflags (magic , options );
389
372
}
390
373
391
374
const char * ret_val = magic_buffer (magic , ZSTR_VAL (buffer ), ZSTR_LEN (buffer ));
392
375
393
376
/* Restore options */
394
377
if (options ) {
395
- magic_setflags (magic , finfo -> options );
378
+ magic_setflags (magic , old_options );
396
379
}
397
380
398
381
if (UNEXPECTED (ret_val == NULL )) {
0 commit comments