📄 mime_magic.c
字号:
while (*l == '>') { ++l; /* step over */ m->cont_level++; } if (m->cont_level != 0 && *l == '(') { ++l; /* step over */ m->flag |= INDIR; } /* get offset, then skip over it */ m->offset = (int) strtol(l, &t, 0); if (l == t) { php_error(E_WARNING, MODNAME ": (line %d) offset `%s' invalid", lineno, l); } l = t; if (m->flag & INDIR) { m->in.type = LONG; m->in.offset = 0; /* * read [.lbs][+-]nnnnn) */ if (*l == '.') { switch (*++l) { case 'l': m->in.type = LONG; break; case 's': m->in.type = SHORT; break; case 'b': m->in.type = BYTE; break; default: php_error(E_WARNING, MODNAME ": indirect offset type %c invalid", *l); break; } l++; } s = l; if (*l == '+' || *l == '-') l++; if (isdigit((unsigned char) *l)) { m->in.offset = strtol(l, &t, 0); if (*s == '-') m->in.offset = -m->in.offset; } else t = l; if (*t++ != ')') { php_error(E_WARNING, MODNAME ": missing ')' in indirect offset"); } l = t; } while (isdigit((unsigned char) *l)) ++l; EATAB;#define NBYTE 4#define NSHORT 5#define NLONG 4#define NSTRING 6#define NDATE 4#define NBESHORT 7#define NBELONG 6#define NBEDATE 6#define NLESHORT 7#define NLELONG 6#define NLEDATE 6 if (*l == 'u') { ++l; m->flag |= UNSIGNED; } /* get type, skip it */ if (strncmp(l, "byte", NBYTE) == 0) { m->type = BYTE; l += NBYTE; } else if (strncmp(l, "short", NSHORT) == 0) { m->type = SHORT; l += NSHORT; } else if (strncmp(l, "long", NLONG) == 0) { m->type = LONG; l += NLONG; } else if (strncmp(l, "string", NSTRING) == 0) { m->type = STRING; l += NSTRING; } else if (strncmp(l, "date", NDATE) == 0) { m->type = DATE; l += NDATE; } else if (strncmp(l, "beshort", NBESHORT) == 0) { m->type = BESHORT; l += NBESHORT; } else if (strncmp(l, "belong", NBELONG) == 0) { m->type = BELONG; l += NBELONG; } else if (strncmp(l, "bedate", NBEDATE) == 0) { m->type = BEDATE; l += NBEDATE; } else if (strncmp(l, "leshort", NLESHORT) == 0) { m->type = LESHORT; l += NLESHORT; } else if (strncmp(l, "lelong", NLELONG) == 0) { m->type = LELONG; l += NLELONG; } else if (strncmp(l, "ledate", NLEDATE) == 0) { m->type = LEDATE; l += NLEDATE; } else { php_error(E_WARNING, MODNAME ": type %s invalid", l); return -1; } /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ if (*l == '&') { ++l; m->mask = signextend(m, strtol(l, &l, 0)); } else m->mask = ~0L; EATAB; switch (*l) { case '>': case '<': /* Old-style anding: "0 byte &0x80 dynamically linked" */ case '&': case '^': case '=': m->reln = *l; ++l; break; case '!': if (m->type != STRING) { m->reln = *l; ++l; break; } /* FALL THROUGH */ default: if (*l == 'x' && isspace((unsigned char) l[1])) { m->reln = *l; ++l; goto GetDesc; /* Bill The Cat */ } m->reln = '='; break; } EATAB; if (getvalue(m, &l)) return -1; /* * now get last part - the description */ GetDesc: EATAB; if (l[0] == '\b') { ++l; m->nospflag = 1; } else if ((l[0] == '\\') && (l[1] == 'b')) { ++l; ++l; m->nospflag = 1; } else m->nospflag = 0; strlcpy(m->desc, l, sizeof(m->desc)); return 0;}/* * Read a numeric value from a pointer, into the value union of a magic * pointer, according to the magic type. Update the string pointer to point * just after the number read. Return 0 for success, non-zero for failure. */static int getvalue(struct magic *m, char **p){ int slen; if (m->type == STRING) { *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen); m->vallen = slen; } else if (m->reln != 'x') m->value.l = signextend(m, strtol(*p, p, 0)); return 0;}/* * Convert a string containing C character escapes. Stop at an unescaped * space or tab. Copy the converted version to "p", returning its length in * *slen. Return updated scan pointer as function result. */static char *getstr(register char *s, register char *p, int plen, int *slen){ char *origs = s, *origp = p; char *pmax = p + plen - 1; register int c; register int val; while ((c = *s++) != '\0') { if (isspace((unsigned char) c)) break; if (p >= pmax) { php_error(E_WARNING, MODNAME ": string too long: %s", origs); break; } if (c == '\\') { switch (c = *s++) { case '\0': goto out; default: *p++ = (char) c; break; case 'n': *p++ = '\n'; break; case 'r': *p++ = '\r'; break; case 'b': *p++ = '\b'; break; case 't': *p++ = '\t'; break; case 'f': *p++ = '\f'; break; case 'v': *p++ = '\v'; break; /* \ and up to 3 octal digits */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': val = c - '0'; c = *s++; /* try for 2 */ if (c >= '0' && c <= '7') { val = (val << 3) | (c - '0'); c = *s++; /* try for 3 */ if (c >= '0' && c <= '7') val = (val << 3) | (c - '0'); else --s; } else --s; *p++ = (char) val; break; /* \x and up to 3 hex digits */ case 'x': val = 'x'; /* Default if no digits */ c = hextoint(*s++); /* Get next char */ if (c >= 0) { val = c; c = hextoint(*s++); if (c >= 0) { val = (val << 4) + c; c = hextoint(*s++); if (c >= 0) { val = (val << 4) + c; } else --s; } else --s; } else --s; *p++ = (char) val; break; } } else *p++ = (char) c; } out: *p = '\0'; *slen = p - origp; return s;}/* Single hex char to int; -1 if not a hex char. */static int hextoint(int c){ if (isdigit((unsigned char) c)) return c - '0'; if ((c >= 'a') && (c <= 'f')) return c + 10 - 'a'; if ((c >= 'A') && (c <= 'F')) return c + 10 - 'A'; return -1;}/* * RSL (result string list) processing routines * * These collect strings that would have been printed in fragments by file(1) * into a list of magic_rsl structures with the strings. When complete, * they're concatenated together to become the MIME content and encoding * types. * * return value conventions for these functions: functions which return int: * failure = -1, other = result functions which return pointers: failure = 0, * other = result *//* allocate a per-request structure and put it in the request record */static magic_req_rec *magic_set_config(void){ magic_req_rec *req_dat = (magic_req_rec *) emalloc(sizeof(magic_req_rec)); req_dat->head = req_dat->tail = (magic_rsl *) NULL; return req_dat;}static void magic_free_config(magic_req_rec *req_dat) { magic_rsl *curr, *next; if(!req_dat) return; curr = req_dat->head; while(curr) { next = curr->next; efree(curr->str); efree(curr); curr = next; } efree(req_dat);}/* add a string to the result string list for this request *//* it is the responsibility of the caller to allocate "str" */static int magic_rsl_add(char *str){ magic_req_rec *req_dat; magic_rsl *rsl; TSRMLS_FETCH(); req_dat = MIME_MAGIC_G(req_dat); /* make sure we have a list to put it in */ if (!req_dat) { php_error(E_WARNING, MODNAME ": request config should not be NULL"); if (!(req_dat = magic_set_config())) { /* failure */ return -1; } } /* allocate the list entry */ rsl = (magic_rsl *) emalloc(sizeof(magic_rsl)); /* fill it */ rsl->str = estrdup(str); rsl->next = (magic_rsl *) NULL; /* append to the list */ if (req_dat->head && req_dat->tail) { req_dat->tail->next = rsl; req_dat->tail = rsl; } else { req_dat->head = req_dat->tail = rsl; } /* success */ return 0;}/* RSL hook for puts-type functions */static int magic_rsl_puts(char *str){ return magic_rsl_add(str);}/* RSL hook for printf-type functions */static int magic_rsl_printf(char *str,...){ va_list ap; char buf[MAXMIMESTRING]; /* assemble the string into the buffer */ va_start(ap, str); vsnprintf(buf, sizeof(buf), str, ap); va_end(ap); /* add the buffer to the list */ return magic_rsl_add(buf);}/* RSL hook for putchar-type functions */static int magic_rsl_putchar(char c){ char str[2]; /* high overhead for 1 char - just hope they don't do this much */ str[0] = c; str[1] = '\0'; return magic_rsl_add(str);}/* allocate and copy a contiguous string from a result string list */static char *rsl_strdup(int start_frag, int start_pos, int len){ char *result; /* return value */ int cur_frag, /* current fragment number/counter */ cur_pos, /* current position within fragment */ res_pos; /* position in result string */ magic_rsl *frag; /* list-traversal pointer */ magic_req_rec *req_dat; TSRMLS_FETCH(); req_dat = MIME_MAGIC_G(req_dat); /* allocate the result string */ result = (char *) emalloc(len + 2); /* loop through and collect the string */ res_pos = 0; for (frag = req_dat->head, cur_frag = 0; frag->next; frag = frag->next, cur_frag++) { /* loop to the first fragment */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -