fileinfo.c 16 KB

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