xref: /PHP-7.4/ext/fileinfo/fileinfo.c (revision 7817fc07)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) The PHP Group                                          |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.0 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_0.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   | Author: Ilia Alshanetsky <ilia@php.net>                              |
16   +----------------------------------------------------------------------+
17 */
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 #include "php.h"
23 
24 #include <magic.h>
25 /*
26  * HOWMANY specifies the maximum offset libmagic will look at
27  * this is currently hardcoded in the libmagic source but not exported
28  */
29 #ifndef HOWMANY
30 #define HOWMANY 65536
31 #endif
32 
33 #include "php_ini.h"
34 #include "ext/standard/info.h"
35 #include "ext/standard/file.h" /* needed for context stuff */
36 #include "php_fileinfo.h"
37 #include "fopen_wrappers.h" /* needed for is_url */
38 #include "Zend/zend_exceptions.h"
39 
40 /* {{{ macros and type definitions */
41 typedef struct _php_fileinfo {
42 	zend_long options;
43 	struct magic_set *magic;
44 } php_fileinfo;
45 
46 static zend_object_handlers finfo_object_handlers;
47 zend_class_entry *finfo_class_entry;
48 
49 typedef struct _finfo_object {
50 	php_fileinfo *ptr;
51 	zend_object zo;
52 } finfo_object;
53 
54 #define FILEINFO_DECLARE_INIT_OBJECT(object) \
55 	zval *object = getThis();
56 
php_finfo_fetch_object(zend_object * obj)57 static inline finfo_object *php_finfo_fetch_object(zend_object *obj) {
58 	return (finfo_object *)((char*)(obj) - XtOffsetOf(finfo_object, zo));
59 }
60 
61 #define Z_FINFO_P(zv) php_finfo_fetch_object(Z_OBJ_P((zv)))
62 
63 #define FILEINFO_REGISTER_OBJECT(_object, _ptr) \
64 { \
65 	finfo_object *obj; \
66     obj = Z_FINFO_P(_object); \
67     obj->ptr = _ptr; \
68 }
69 
70 #define FILEINFO_FROM_OBJECT(finfo, object) \
71 { \
72 	finfo_object *obj = Z_FINFO_P(object); \
73 	finfo = obj->ptr; \
74 	if (!finfo) { \
75         	php_error_docref(NULL, E_WARNING, "The invalid fileinfo object."); \
76 		RETURN_FALSE; \
77 	} \
78 }
79 
80 /* {{{ finfo_objects_free
81  */
finfo_objects_free(zend_object * object)82 static void finfo_objects_free(zend_object *object)
83 {
84 	finfo_object *intern = php_finfo_fetch_object(object);
85 
86 	if (intern->ptr) {
87 		magic_close(intern->ptr->magic);
88 		efree(intern->ptr);
89 	}
90 
91 	zend_object_std_dtor(&intern->zo);
92 }
93 /* }}} */
94 
95 /* {{{ finfo_objects_new
96  */
finfo_objects_new(zend_class_entry * class_type)97 PHP_FILEINFO_API zend_object *finfo_objects_new(zend_class_entry *class_type)
98 {
99 	finfo_object *intern;
100 
101 	intern = zend_object_alloc(sizeof(finfo_object), class_type);
102 
103 	zend_object_std_init(&intern->zo, class_type);
104 	object_properties_init(&intern->zo, class_type);
105 	intern->zo.handlers = &finfo_object_handlers;
106 
107 	return &intern->zo;
108 }
109 /* }}} */
110 
111 /* {{{ arginfo */
112 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_open, 0, 0, 0)
113 	ZEND_ARG_INFO(0, options)
114 	ZEND_ARG_INFO(0, arg)
115 ZEND_END_ARG_INFO()
116 
117 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_close, 0, 0, 1)
118 	ZEND_ARG_INFO(0, finfo)
119 ZEND_END_ARG_INFO()
120 
121 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_set_flags, 0, 0, 2)
122 	ZEND_ARG_INFO(0, finfo)
123 	ZEND_ARG_INFO(0, options)
124 ZEND_END_ARG_INFO()
125 
126 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_set_flags, 0, 0, 1)
127 	ZEND_ARG_INFO(0, options)
128 ZEND_END_ARG_INFO()
129 
130 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_file, 0, 0, 2)
131 	ZEND_ARG_INFO(0, finfo)
132 	ZEND_ARG_INFO(0, filename)
133 	ZEND_ARG_INFO(0, options)
134 	ZEND_ARG_INFO(0, context)
135 ZEND_END_ARG_INFO()
136 
137 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_file, 0, 0, 1)
138 	ZEND_ARG_INFO(0, filename)
139 	ZEND_ARG_INFO(0, options)
140 	ZEND_ARG_INFO(0, context)
141 ZEND_END_ARG_INFO()
142 
143 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_buffer, 0, 0, 2)
144 	ZEND_ARG_INFO(0, finfo)
145 	ZEND_ARG_INFO(0, string)
146 	ZEND_ARG_INFO(0, options)
147 	ZEND_ARG_INFO(0, context)
148 ZEND_END_ARG_INFO()
149 
150 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_buffer, 0, 0, 1)
151 	ZEND_ARG_INFO(0, string)
152 	ZEND_ARG_INFO(0, options)
153 	ZEND_ARG_INFO(0, context)
154 ZEND_END_ARG_INFO()
155 
156 ZEND_BEGIN_ARG_INFO_EX(arginfo_mime_content_type, 0, 0, 1)
157 	ZEND_ARG_INFO(0, string)
158 ZEND_END_ARG_INFO()
159 /* }}} */
160 
161 /* {{{ finfo_class_functions
162  */
163 static const zend_function_entry finfo_class_functions[] = {
164 	ZEND_ME_MAPPING(finfo,          finfo_open,     arginfo_finfo_open, ZEND_ACC_PUBLIC)
165 	ZEND_ME_MAPPING(set_flags,      finfo_set_flags,arginfo_finfo_method_set_flags, ZEND_ACC_PUBLIC)
166 	ZEND_ME_MAPPING(file,           finfo_file,     arginfo_finfo_method_file, ZEND_ACC_PUBLIC)
167 	ZEND_ME_MAPPING(buffer,         finfo_buffer,   arginfo_finfo_method_buffer, ZEND_ACC_PUBLIC)
168 	PHP_FE_END
169 };
170 /* }}} */
171 
172 #define FINFO_SET_OPTION(magic, options) \
173 	if (magic_setflags(magic, options) == -1) { \
174 		php_error_docref(NULL, E_WARNING, "Failed to set option '" ZEND_LONG_FMT "' %d:%s", \
175 				options, magic_errno(magic), magic_error(magic)); \
176 		RETURN_FALSE; \
177 	}
178 
179 /* True global resources - no need for thread safety here */
180 static int le_fileinfo;
181 /* }}} */
182 
finfo_resource_destructor(zend_resource * rsrc)183 void finfo_resource_destructor(zend_resource *rsrc) /* {{{ */
184 {
185 	if (rsrc->ptr) {
186 		php_fileinfo *finfo = (php_fileinfo *) rsrc->ptr;
187 		magic_close(finfo->magic);
188 		efree(rsrc->ptr);
189 		rsrc->ptr = NULL;
190 	}
191 }
192 /* }}} */
193 
194 
195 /* {{{ fileinfo_functions[]
196  */
197 static const zend_function_entry fileinfo_functions[] = {
198 	PHP_FE(finfo_open,		arginfo_finfo_open)
199 	PHP_FE(finfo_close,		arginfo_finfo_close)
200 	PHP_FE(finfo_set_flags,	arginfo_finfo_set_flags)
201 	PHP_FE(finfo_file,		arginfo_finfo_file)
202 	PHP_FE(finfo_buffer,	arginfo_finfo_buffer)
203 	PHP_FE(mime_content_type, arginfo_mime_content_type)
204 	PHP_FE_END
205 };
206 /* }}} */
207 
208 /* {{{ PHP_MINIT_FUNCTION
209  */
PHP_MINIT_FUNCTION(finfo)210 PHP_MINIT_FUNCTION(finfo)
211 {
212 	zend_class_entry _finfo_class_entry;
213 	INIT_CLASS_ENTRY(_finfo_class_entry, "finfo", finfo_class_functions);
214 	_finfo_class_entry.create_object = finfo_objects_new;
215 	finfo_class_entry = zend_register_internal_class(&_finfo_class_entry);
216 
217 	/* copy the standard object handlers to you handler table */
218 	memcpy(&finfo_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
219 	finfo_object_handlers.offset = XtOffsetOf(finfo_object, zo);
220 	finfo_object_handlers.free_obj = finfo_objects_free;
221 	finfo_object_handlers.clone_obj = NULL;
222 
223 	le_fileinfo = zend_register_list_destructors_ex(finfo_resource_destructor, NULL, "file_info", module_number);
224 
225 	REGISTER_LONG_CONSTANT("FILEINFO_NONE",			MAGIC_NONE, CONST_CS|CONST_PERSISTENT);
226 	REGISTER_LONG_CONSTANT("FILEINFO_SYMLINK",		MAGIC_SYMLINK, CONST_CS|CONST_PERSISTENT);
227 	REGISTER_LONG_CONSTANT("FILEINFO_MIME",			MAGIC_MIME, CONST_CS|CONST_PERSISTENT);
228 	REGISTER_LONG_CONSTANT("FILEINFO_MIME_TYPE",	MAGIC_MIME_TYPE, CONST_CS|CONST_PERSISTENT);
229 	REGISTER_LONG_CONSTANT("FILEINFO_MIME_ENCODING",MAGIC_MIME_ENCODING, CONST_CS|CONST_PERSISTENT);
230 /*	REGISTER_LONG_CONSTANT("FILEINFO_COMPRESS",		MAGIC_COMPRESS, CONST_CS|CONST_PERSISTENT); disabled, as it does fork now */
231 	REGISTER_LONG_CONSTANT("FILEINFO_DEVICES",		MAGIC_DEVICES, CONST_CS|CONST_PERSISTENT);
232 	REGISTER_LONG_CONSTANT("FILEINFO_CONTINUE",		MAGIC_CONTINUE, CONST_CS|CONST_PERSISTENT);
233 #ifdef MAGIC_PRESERVE_ATIME
234 	REGISTER_LONG_CONSTANT("FILEINFO_PRESERVE_ATIME",	MAGIC_PRESERVE_ATIME, CONST_CS|CONST_PERSISTENT);
235 #endif
236 #ifdef MAGIC_RAW
237 	REGISTER_LONG_CONSTANT("FILEINFO_RAW",			MAGIC_RAW, CONST_CS|CONST_PERSISTENT);
238 #endif
239 #if 0
240 	/* seems not usable yet. */
241 	REGISTER_LONG_CONSTANT("FILEINFO_APPLE",		MAGIC_APPLE, CONST_CS|CONST_PERSISTENT);
242 #endif
243 	REGISTER_LONG_CONSTANT("FILEINFO_EXTENSION",	MAGIC_EXTENSION, CONST_CS|CONST_PERSISTENT);
244 
245 	return SUCCESS;
246 }
247 /* }}} */
248 
249 /* {{{ fileinfo_module_entry
250  */
251 zend_module_entry fileinfo_module_entry = {
252 	STANDARD_MODULE_HEADER,
253 	"fileinfo",
254 	fileinfo_functions,
255 	PHP_MINIT(finfo),
256 	NULL,
257 	NULL,
258 	NULL,
259 	PHP_MINFO(fileinfo),
260 	PHP_FILEINFO_VERSION,
261 	STANDARD_MODULE_PROPERTIES
262 };
263 /* }}} */
264 
265 #ifdef COMPILE_DL_FILEINFO
266 ZEND_GET_MODULE(fileinfo)
267 #endif
268 
269 /* {{{ PHP_MINFO_FUNCTION
270  */
PHP_MINFO_FUNCTION(fileinfo)271 PHP_MINFO_FUNCTION(fileinfo)
272 {
273 	char magic_ver[5];
274 
275 	(void)snprintf(magic_ver, 4, "%d", magic_version());
276 	magic_ver[4] = '\0';
277 
278 	php_info_print_table_start();
279 	php_info_print_table_row(2, "fileinfo support", "enabled");
280 	php_info_print_table_row(2, "libmagic", magic_ver);
281 	php_info_print_table_end();
282 }
283 /* }}} */
284 
285 /* {{{ proto resource finfo_open([int options [, string arg]])
286    Create a new fileinfo resource. */
PHP_FUNCTION(finfo_open)287 PHP_FUNCTION(finfo_open)
288 {
289 	zend_long options = MAGIC_NONE;
290 	char *file = NULL;
291 	size_t file_len = 0;
292 	php_fileinfo *finfo;
293 	FILEINFO_DECLARE_INIT_OBJECT(object)
294 	char resolved_path[MAXPATHLEN];
295 	zend_error_handling zeh;
296 	int flags = object ? ZEND_PARSE_PARAMS_THROW : 0;
297 
298 	if (zend_parse_parameters_ex(flags, ZEND_NUM_ARGS(), "|lp", &options, &file, &file_len) == FAILURE) {
299 		RETURN_FALSE;
300 	}
301 
302 	if (object) {
303 		finfo_object *finfo_obj = Z_FINFO_P(object);
304 
305 		zend_replace_error_handling(EH_THROW, NULL, &zeh);
306 
307 		if (finfo_obj->ptr) {
308 			magic_close(finfo_obj->ptr->magic);
309 			efree(finfo_obj->ptr);
310 			finfo_obj->ptr = NULL;
311 		}
312 	}
313 
314 	if (file_len == 0) {
315 		file = NULL;
316 	} else if (file && *file) { /* user specified file, perform open_basedir checks */
317 
318 		if (php_check_open_basedir(file)) {
319 			if (object) {
320 				zend_restore_error_handling(&zeh);
321 				if (!EG(exception)) {
322 					zend_throw_exception(NULL, "Constructor failed", 0);
323 				}
324 			}
325 			RETURN_FALSE;
326 		}
327 		if (!expand_filepath_with_mode(file, resolved_path, NULL, 0, CWD_EXPAND)) {
328 			if (object) {
329 				zend_restore_error_handling(&zeh);
330 				if (!EG(exception)) {
331 					zend_throw_exception(NULL, "Constructor failed", 0);
332 				}
333 			}
334 			RETURN_FALSE;
335 		}
336 		file = resolved_path;
337 	}
338 
339 	finfo = emalloc(sizeof(php_fileinfo));
340 
341 	finfo->options = options;
342 	finfo->magic = magic_open(options);
343 
344 	if (finfo->magic == NULL) {
345 		efree(finfo);
346 		php_error_docref(NULL, E_WARNING, "Invalid mode '" ZEND_LONG_FMT "'.", options);
347 		if (object) {
348 			zend_restore_error_handling(&zeh);
349 			if (!EG(exception)) {
350 				zend_throw_exception(NULL, "Constructor failed", 0);
351 			}
352 		}
353 		RETURN_FALSE;
354 	}
355 
356 	if (magic_load(finfo->magic, file) == -1) {
357 		php_error_docref(NULL, E_WARNING, "Failed to load magic database at '%s'.", file);
358 		magic_close(finfo->magic);
359 		efree(finfo);
360 		if (object) {
361 			zend_restore_error_handling(&zeh);
362 			if (!EG(exception)) {
363 				zend_throw_exception(NULL, "Constructor failed", 0);
364 			}
365 		}
366 		RETURN_FALSE;
367 	}
368 
369 	if (object) {
370 		zend_restore_error_handling(&zeh);
371 		FILEINFO_REGISTER_OBJECT(object, finfo);
372 	} else {
373 		RETURN_RES(zend_register_resource(finfo, le_fileinfo));
374 	}
375 }
376 /* }}} */
377 
378 /* {{{ proto resource finfo_close(resource finfo)
379    Close fileinfo resource. */
PHP_FUNCTION(finfo_close)380 PHP_FUNCTION(finfo_close)
381 {
382 	php_fileinfo *finfo;
383 	zval *zfinfo;
384 
385 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zfinfo) == FAILURE) {
386 		RETURN_FALSE;
387 	}
388 
389 	if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
390 		RETURN_FALSE;
391 	}
392 
393 	zend_list_close(Z_RES_P(zfinfo));
394 
395 	RETURN_TRUE;
396 }
397 /* }}} */
398 
399 /* {{{ proto bool finfo_set_flags(resource finfo, int options)
400    Set libmagic configuration options. */
PHP_FUNCTION(finfo_set_flags)401 PHP_FUNCTION(finfo_set_flags)
402 {
403 	zend_long options;
404 	php_fileinfo *finfo;
405 	zval *zfinfo;
406 	FILEINFO_DECLARE_INIT_OBJECT(object)
407 
408 	if (object) {
409 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &options) == FAILURE) {
410 			RETURN_FALSE;
411 		}
412 		FILEINFO_FROM_OBJECT(finfo, object);
413 	} else {
414 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &zfinfo, &options) == FAILURE) {
415 			RETURN_FALSE;
416 		}
417 		if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
418 			RETURN_FALSE;
419 		}
420 	}
421 
422 	FINFO_SET_OPTION(finfo->magic, options)
423 	finfo->options = options;
424 
425 	RETURN_TRUE;
426 }
427 /* }}} */
428 
429 #define FILEINFO_MODE_BUFFER 0
430 #define FILEINFO_MODE_STREAM 1
431 #define FILEINFO_MODE_FILE 2
432 
_php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS,int mode,int mimetype_emu)433 static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu) /* {{{ */
434 {
435 	zend_long options = 0;
436 	char *ret_val = NULL, *buffer = NULL;
437 	size_t buffer_len;
438 	php_fileinfo *finfo = NULL;
439 	zval *zfinfo, *zcontext = NULL;
440 	zval *what;
441 	char mime_directory[] = "directory";
442 
443 	struct magic_set *magic = NULL;
444 	FILEINFO_DECLARE_INIT_OBJECT(object)
445 
446 	if (mimetype_emu) {
447 
448 		/* mime_content_type(..) emulation */
449 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &what) == FAILURE) {
450 			return;
451 		}
452 
453 		switch (Z_TYPE_P(what)) {
454 			case IS_STRING:
455 				buffer = Z_STRVAL_P(what);
456 				buffer_len = Z_STRLEN_P(what);
457 				mode = FILEINFO_MODE_FILE;
458 				break;
459 
460 			case IS_RESOURCE:
461 				mode = FILEINFO_MODE_STREAM;
462 				break;
463 
464 			default:
465 				php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments");
466 				RETURN_FALSE;
467 		}
468 
469 		magic = magic_open(MAGIC_MIME_TYPE);
470 		if (magic_load(magic, NULL) == -1) {
471 			php_error_docref(NULL, E_WARNING, "Failed to load magic database.");
472 			goto common;
473 		}
474 	} else if (object) {
475 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
476 			RETURN_FALSE;
477 		}
478 		FILEINFO_FROM_OBJECT(finfo, object);
479 		magic = finfo->magic;
480 	} else {
481 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
482 			RETURN_FALSE;
483 		}
484 		if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
485 			RETURN_FALSE;
486 		}
487 		magic = finfo->magic;
488 	}
489 
490 	/* Set options for the current file/buffer. */
491 	if (options) {
492 		FINFO_SET_OPTION(magic, options)
493 	}
494 
495 	switch (mode) {
496 		case FILEINFO_MODE_BUFFER:
497 		{
498 			ret_val = (char *) magic_buffer(magic, buffer, buffer_len);
499 			break;
500 		}
501 
502 		case FILEINFO_MODE_STREAM:
503 		{
504 				php_stream *stream;
505 				zend_off_t streampos;
506 
507 				php_stream_from_zval_no_verify(stream, what);
508 				if (!stream) {
509 					goto common;
510 				}
511 
512 				streampos = php_stream_tell(stream); /* remember stream position for restoration */
513 				php_stream_seek(stream, 0, SEEK_SET);
514 
515 				ret_val = (char *) magic_stream(magic, stream);
516 
517 				php_stream_seek(stream, streampos, SEEK_SET);
518 				break;
519 		}
520 
521 		case FILEINFO_MODE_FILE:
522 		{
523 			/* determine if the file is a local file or remote URL */
524 			const char *tmp2;
525 			php_stream_wrapper *wrap;
526 			php_stream_statbuf ssb;
527 
528 			if (buffer == NULL || !*buffer) {
529 				php_error_docref(NULL, E_WARNING, "Empty filename or path");
530 				RETVAL_FALSE;
531 				goto clean;
532 			}
533 			if (CHECK_NULL_PATH(buffer, buffer_len)) {
534 				php_error_docref(NULL, E_WARNING, "Invalid path");
535 				RETVAL_FALSE;
536 				goto clean;
537 			}
538 
539 			wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0);
540 
541 			if (wrap) {
542 				php_stream *stream;
543 				php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
544 
545 #ifdef PHP_WIN32
546 				if (php_stream_stat_path_ex(buffer, 0, &ssb, context) == SUCCESS) {
547 					if (ssb.sb.st_mode & S_IFDIR) {
548 						ret_val = mime_directory;
549 						goto common;
550 					}
551 				}
552 #endif
553 
554 				stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
555 
556 				if (!stream) {
557 					RETVAL_FALSE;
558 					goto clean;
559 				}
560 
561 				if (php_stream_stat(stream, &ssb) == SUCCESS) {
562 					if (ssb.sb.st_mode & S_IFDIR) {
563 						ret_val = mime_directory;
564 					} else {
565 						ret_val = (char *)magic_stream(magic, stream);
566 					}
567 				}
568 
569 				php_stream_close(stream);
570 			}
571 			break;
572 		}
573 
574 		default:
575 			php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments");
576 	}
577 
578 common:
579 	if (ret_val) {
580 		RETVAL_STRING(ret_val);
581 	} else {
582 		php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
583 		RETVAL_FALSE;
584 	}
585 
586 clean:
587 	if (mimetype_emu) {
588 		magic_close(magic);
589 	}
590 
591 	/* Restore options */
592 	if (options) {
593 		FINFO_SET_OPTION(magic, finfo->options)
594 	}
595 	return;
596 }
597 /* }}} */
598 
599 /* {{{ proto string finfo_file(resource finfo, char *file_name [, int options [, resource context]])
600    Return information about a file. */
PHP_FUNCTION(finfo_file)601 PHP_FUNCTION(finfo_file)
602 {
603 	_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_FILE, 0);
604 }
605 /* }}} */
606 
607 /* {{{ proto string finfo_buffer(resource finfo, char *string [, int options [, resource context]])
608    Return information about a string buffer. */
PHP_FUNCTION(finfo_buffer)609 PHP_FUNCTION(finfo_buffer)
610 {
611 	_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_BUFFER, 0);
612 }
613 /* }}} */
614 
615 /* {{{ proto string mime_content_type(string filename|resource stream)
616    Return content-type for file */
PHP_FUNCTION(mime_content_type)617 PHP_FUNCTION(mime_content_type)
618 {
619 	_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1, 1);
620 }
621 /* }}} */
622