1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #ifndef __file_h__
34 #define __file_h__
35
36 #include "config.h"
37
38 #ifdef PHP_WIN32
39 #ifdef _WIN64
40 #define SIZE_T_FORMAT "I64"
41 #else
42 #define SIZE_T_FORMAT ""
43 #endif
44 #define INT64_T_FORMAT "I64"
45 #else
46 #define SIZE_T_FORMAT "z"
47 #define INT64_T_FORMAT "ll"
48 #endif
49
50 #include <stdio.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #ifdef HAVE_STDINT_H
54 #ifndef __STDC_LIMIT_MACROS
55 #define __STDC_LIMIT_MACROS
56 #endif
57 #include <stdint.h>
58 #endif
59 #ifdef HAVE_INTTYPES_H
60 #include <inttypes.h>
61 #endif
62 #ifdef PHP_WIN32
63 #include "win32/php_stdint.h"
64 #endif
65
66 #include "php.h"
67 #include "ext/standard/php_string.h"
68 #include "ext/pcre/php_pcre.h"
69
70 #include <sys/types.h>
71 #ifdef PHP_WIN32
72 #include "win32/param.h"
73 #else
74 #include <sys/param.h>
75 #endif
76
77 #include <sys/stat.h>
78 #include <stdarg.h>
79
80 #define ENABLE_CONDITIONALS
81
82 #ifndef MAGIC
83 #define MAGIC "/etc/magic"
84 #endif
85
86 #if defined(__EMX__) || defined(PHP_WIN32)
87 #define PATHSEP ';'
88 #else
89 #define PATHSEP ':'
90 #endif
91
92 #define private static
93
94 #if HAVE_VISIBILITY
95 #define public __attribute__ ((__visibility__("default")))
96 #ifndef protected
97 #define protected __attribute__ ((__visibility__("hidden")))
98 #endif
99 #else
100 #define public
101 #ifndef protected
102 #define protected
103 #endif
104 #endif
105
106 #ifndef __arraycount
107 #define __arraycount(a) (sizeof(a) / sizeof(a[0]))
108 #endif
109
110 #ifndef __GNUC_PREREQ__
111 #ifdef __GNUC__
112 #define __GNUC_PREREQ__(x, y) \
113 ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
114 (__GNUC__ > (x)))
115 #else
116 #define __GNUC_PREREQ__(x, y) 0
117 #endif
118 #endif
119
120 #ifndef MIN
121 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
122 #endif
123
124 #ifndef MAX
125 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
126 #endif
127
128 #ifndef HOWMANY
129 # define HOWMANY (256 * 1024)
130 #endif
131 #define MAXMAGIS 8192
132
133 #define MAXDESC 64
134 #define MAXMIME 80
135 #define MAXstring 64
136
137 #define MAGICNO 0xF11E041C
138 #define VERSIONNO 11
139 #define FILE_MAGICSIZE 248
140
141 #define FILE_LOAD 0
142 #define FILE_CHECK 1
143 #define FILE_COMPILE 2
144 #define FILE_LIST 3
145
146 union VALUETYPE {
147 uint8_t b;
148 uint16_t h;
149 uint32_t l;
150 uint64_t q;
151 uint8_t hs[2];
152 uint8_t hl[4];
153 uint8_t hq[8];
154 char s[MAXstring];
155 unsigned char us[MAXstring];
156 float f;
157 double d;
158 };
159
160 struct magic {
161
162 uint16_t cont_level;
163 uint8_t flag;
164 #define INDIR 0x01
165 #define OFFADD 0x02
166 #define INDIROFFADD 0x04
167 #define UNSIGNED 0x08
168 #define NOSPACE 0x10
169 #define BINTEST 0x20
170
171 #define TEXTTEST 0x40
172
173 uint8_t factor;
174
175
176 uint8_t reln;
177 uint8_t vallen;
178 uint8_t type;
179 uint8_t in_type;
180 #define FILE_INVALID 0
181 #define FILE_BYTE 1
182 #define FILE_SHORT 2
183 #define FILE_DEFAULT 3
184 #define FILE_LONG 4
185 #define FILE_STRING 5
186 #define FILE_DATE 6
187 #define FILE_BESHORT 7
188 #define FILE_BELONG 8
189 #define FILE_BEDATE 9
190 #define FILE_LESHORT 10
191 #define FILE_LELONG 11
192 #define FILE_LEDATE 12
193 #define FILE_PSTRING 13
194 #define FILE_LDATE 14
195 #define FILE_BELDATE 15
196 #define FILE_LELDATE 16
197 #define FILE_REGEX 17
198 #define FILE_BESTRING16 18
199 #define FILE_LESTRING16 19
200 #define FILE_SEARCH 20
201 #define FILE_MEDATE 21
202 #define FILE_MELDATE 22
203 #define FILE_MELONG 23
204 #define FILE_QUAD 24
205 #define FILE_LEQUAD 25
206 #define FILE_BEQUAD 26
207 #define FILE_QDATE 27
208 #define FILE_LEQDATE 28
209 #define FILE_BEQDATE 29
210 #define FILE_QLDATE 30
211 #define FILE_LEQLDATE 31
212 #define FILE_BEQLDATE 32
213 #define FILE_FLOAT 33
214 #define FILE_BEFLOAT 34
215 #define FILE_LEFLOAT 35
216 #define FILE_DOUBLE 36
217 #define FILE_BEDOUBLE 37
218 #define FILE_LEDOUBLE 38
219 #define FILE_BEID3 39
220 #define FILE_LEID3 40
221 #define FILE_INDIRECT 41
222 #define FILE_QWDATE 42
223 #define FILE_LEQWDATE 43
224 #define FILE_BEQWDATE 44
225 #define FILE_NAME 45
226 #define FILE_USE 46
227 #define FILE_CLEAR 47
228 #define FILE_NAMES_SIZE 48
229
230 #define IS_LIBMAGIC_STRING(t) \
231 ((t) == FILE_STRING || \
232 (t) == FILE_PSTRING || \
233 (t) == FILE_BESTRING16 || \
234 (t) == FILE_LESTRING16 || \
235 (t) == FILE_REGEX || \
236 (t) == FILE_SEARCH || \
237 (t) == FILE_NAME || \
238 (t) == FILE_USE)
239
240 #define FILE_FMT_NONE 0
241 #define FILE_FMT_NUM 1
242 #define FILE_FMT_STR 2
243 #define FILE_FMT_QUAD 3
244 #define FILE_FMT_FLOAT 4
245 #define FILE_FMT_DOUBLE 5
246
247
248 uint8_t in_op;
249 uint8_t mask_op;
250 #ifdef ENABLE_CONDITIONALS
251 uint8_t cond;
252 #else
253 uint8_t dummy;
254 #endif
255 uint8_t factor_op;
256 #define FILE_FACTOR_OP_PLUS '+'
257 #define FILE_FACTOR_OP_MINUS '-'
258 #define FILE_FACTOR_OP_TIMES '*'
259 #define FILE_FACTOR_OP_DIV '/'
260 #define FILE_FACTOR_OP_NONE '\0'
261
262 #define FILE_OPS "&|^+-*/%"
263 #define FILE_OPAND 0
264 #define FILE_OPOR 1
265 #define FILE_OPXOR 2
266 #define FILE_OPADD 3
267 #define FILE_OPMINUS 4
268 #define FILE_OPMULTIPLY 5
269 #define FILE_OPDIVIDE 6
270 #define FILE_OPMODULO 7
271 #define FILE_OPS_MASK 0x07
272 #define FILE_UNUSED_1 0x08
273 #define FILE_UNUSED_2 0x10
274 #define FILE_UNUSED_3 0x20
275 #define FILE_OPINVERSE 0x40
276 #define FILE_OPINDIRECT 0x80
277
278 #ifdef ENABLE_CONDITIONALS
279 #define COND_NONE 0
280 #define COND_IF 1
281 #define COND_ELIF 2
282 #define COND_ELSE 3
283 #endif
284
285
286 uint32_t offset;
287
288 int32_t in_offset;
289
290 uint32_t lineno;
291
292 union {
293 uint64_t _mask;
294 struct {
295 uint32_t _count;
296 uint32_t _flags;
297 } _s;
298 } _u;
299 #define num_mask _u._mask
300 #define str_range _u._s._count
301 #define str_flags _u._s._flags
302
303 union VALUETYPE value;
304
305 char desc[MAXDESC];
306
307 char mimetype[MAXMIME];
308
309 char apple[8];
310 };
311
312 #define BIT(A) (1 << (A))
313 #define STRING_COMPACT_WHITESPACE BIT(0)
314 #define STRING_COMPACT_OPTIONAL_WHITESPACE BIT(1)
315 #define STRING_IGNORE_LOWERCASE BIT(2)
316 #define STRING_IGNORE_UPPERCASE BIT(3)
317 #define REGEX_OFFSET_START BIT(4)
318 #define STRING_TEXTTEST BIT(5)
319 #define STRING_BINTEST BIT(6)
320 #define PSTRING_1_BE BIT(7)
321 #define PSTRING_1_LE BIT(7)
322 #define PSTRING_2_BE BIT(8)
323 #define PSTRING_2_LE BIT(9)
324 #define PSTRING_4_BE BIT(10)
325 #define PSTRING_4_LE BIT(11)
326 #define PSTRING_LEN \
327 (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE)
328 #define PSTRING_LENGTH_INCLUDES_ITSELF BIT(12)
329 #define STRING_TRIM BIT(13)
330 #define CHAR_COMPACT_WHITESPACE 'W'
331 #define CHAR_COMPACT_OPTIONAL_WHITESPACE 'w'
332 #define CHAR_IGNORE_LOWERCASE 'c'
333 #define CHAR_IGNORE_UPPERCASE 'C'
334 #define CHAR_REGEX_OFFSET_START 's'
335 #define CHAR_TEXTTEST 't'
336 #define CHAR_TRIM 'T'
337 #define CHAR_BINTEST 'b'
338 #define CHAR_PSTRING_1_BE 'B'
339 #define CHAR_PSTRING_1_LE 'B'
340 #define CHAR_PSTRING_2_BE 'H'
341 #define CHAR_PSTRING_2_LE 'h'
342 #define CHAR_PSTRING_4_BE 'L'
343 #define CHAR_PSTRING_4_LE 'l'
344 #define CHAR_PSTRING_LENGTH_INCLUDES_ITSELF 'J'
345 #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
346 #define STRING_DEFAULT_RANGE 100
347
348
349
350 struct mlist {
351 struct magic *magic;
352 uint32_t nmagic;
353 void *map;
354 struct mlist *next, *prev;
355 };
356
357 #ifdef __cplusplus
358 #define CAST(T, b) static_cast<T>(b)
359 #define RCAST(T, b) reinterpret_cast<T>(b)
360 #else
361 #define CAST(T, b) (T)(b)
362 #define RCAST(T, b) (T)(b)
363 #endif
364
365 struct level_info {
366 int32_t off;
367 int got_match;
368 #ifdef ENABLE_CONDITIONALS
369 int last_match;
370 int last_cond;
371 #endif
372 };
373
374 #define MAGIC_SETS 2
375
376 struct magic_set {
377 struct mlist *mlist[MAGIC_SETS];
378 struct cont {
379 size_t len;
380 struct level_info *li;
381 } c;
382 struct out {
383 char *buf;
384 char *pbuf;
385 } o;
386 uint32_t offset;
387 int error;
388 int flags;
389 int event_flags;
390 #define EVENT_HAD_ERR 0x01
391 const char *file;
392 size_t line;
393
394
395 struct {
396 const char *s;
397 size_t s_len;
398 size_t offset;
399 size_t rm_len;
400 } search;
401
402
403
404 union VALUETYPE ms_value;
405 };
406
407
408 typedef unsigned long unichar;
409
410 struct stat;
411 #define FILE_T_LOCAL 1
412 #define FILE_T_WINDOWS 2
413 protected const char *file_fmttime(uint64_t, int, char *);
414 protected struct magic_set *file_ms_alloc(int);
415 protected void file_ms_free(struct magic_set *);
416 protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *,
417 size_t);
418 protected int file_fsmagic(struct magic_set *, const char *, struct stat *, php_stream *);
419 protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
420 protected int file_replace(struct magic_set *, const char *, const char *);
421 protected int file_printf(struct magic_set *, const char *, ...);
422 protected int file_reset(struct magic_set *);
423 protected int file_trycdf(struct magic_set *, int, const unsigned char *,
424 size_t);
425 #ifdef PHP_FILEINFO_UNCOMPRESS
426 protected int file_zmagic(struct magic_set *, int, const char *,
427 const unsigned char *, size_t);
428 #endif
429 protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t,
430 int);
431 protected int file_ascmagic_with_encoding(struct magic_set *,
432 const unsigned char *, size_t, unichar *, size_t, const char *,
433 const char *, int);
434 protected int file_encoding(struct magic_set *, const unsigned char *, size_t,
435 unichar **, size_t *, const char **, const char **, const char **);
436 protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
437 protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
438 size_t, int, int);
439 protected int file_apprentice(struct magic_set *, const char *, int);
440 protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
441 protected uint64_t file_signextend(struct magic_set *, struct magic *,
442 uint64_t);
443 protected void file_delmagic(struct magic *, int type, size_t entries);
444 protected void file_badread(struct magic_set *);
445 protected void file_badseek(struct magic_set *);
446 protected void file_oomem(struct magic_set *, size_t);
447 protected void file_error(struct magic_set *, int, const char *, ...);
448 protected void file_magerror(struct magic_set *, const char *, ...);
449 protected void file_magwarn(struct magic_set *, const char *, ...);
450 protected void file_showstr(FILE *, const char *, size_t);
451 protected size_t file_mbswidth(const char *);
452 protected const char *file_getbuffer(struct magic_set *);
453 protected ssize_t sread(int, void *, size_t, int);
454 protected int file_check_mem(struct magic_set *, unsigned int);
455 protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
456 size_t *);
457 protected size_t file_pstring_length_size(const struct magic *);
458 protected size_t file_pstring_get_length(const struct magic *, const char *);
459 protected size_t file_printedlen(const struct magic_set *ms);
460 #ifdef __EMX__
461 protected int file_os2_apptype(struct magic_set *, const char *, const void *,
462 size_t);
463 #endif
464
465 extern const char *file_names[];
466 extern const size_t file_nnames;
467
468 #ifndef HAVE_STRERROR
469 extern int sys_nerr;
470 extern char *sys_errlist[];
471 #define strerror(e) \
472 (((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
473 #endif
474
475 #ifndef HAVE_STRTOUL
476 #define strtoul(a, b, c) strtol(a, b, c)
477 #endif
478
479 #ifndef strlcpy
480 size_t strlcpy(char *, const char *, size_t);
481 #endif
482 #ifndef strlcat
483 size_t strlcat(char *, const char *, size_t);
484 #endif
485 #ifndef HAVE_STRCASESTR
486 char *strcasestr(const char *, const char *);
487 #endif
488 #ifndef HAVE_GETLINE
489 ssize_t getline(char **, size_t *, FILE *);
490 ssize_t getdelim(char **, size_t *, int, FILE *);
491 #endif
492 #ifndef HAVE_CTIME_R
493 char *ctime_r(const time_t *, char *);
494 #endif
495 #ifndef HAVE_ASCTIME_R
496 char *asctime_r(const struct tm *, char *);
497 #endif
498
499 #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
500 #define QUICK
501 #endif
502
503 #ifndef O_BINARY
504 #define O_BINARY 0
505 #endif
506
507 #ifndef __cplusplus
508 #if defined(__GNUC__) && (__GNUC__ >= 3)
509 #define FILE_RCSID(id) \
510 static const char rcsid[] __attribute__((__used__)) = id;
511 #else
512 #define FILE_RCSID(id) \
513 static const char *rcsid(const char *p) { \
514 return rcsid(p = id); \
515 }
516 #endif
517 #else
518 #define FILE_RCSID(id)
519 #endif
520
521 #ifdef PHP_WIN32
522 #define FINFO_LSEEK_FUNC _lseek
523 #define FINFO_READ_FUNC _read
524 #else
525 #define FINFO_LSEEK_FUNC lseek
526 #define FINFO_READ_FUNC read
527 #endif
528
529 #endif