softmagic.c (275666) | softmagic.c (275698) |
---|---|
1/* 2 * Copyright (c) Ian F. Darwin 1986-1995. 3 * Software written by Ian F. Darwin and others; 4 * maintained 1995-present by Christos Zoulas and others. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 */ 28/* 29 * softmagic - interpret variable magic from MAGIC 30 */ 31 32#include "file.h" 33 34#ifndef lint | 1/* 2 * Copyright (c) Ian F. Darwin 1986-1995. 3 * Software written by Ian F. Darwin and others; 4 * maintained 1995-present by Christos Zoulas and others. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 */ 28/* 29 * softmagic - interpret variable magic from MAGIC 30 */ 31 32#include "file.h" 33 34#ifndef lint |
35FILE_RCSID("@(#)$File: softmagic.c,v 1.191 2014/06/04 17:36:34 christos Exp $") | 35FILE_RCSID("@(#)$File: softmagic.c,v 1.203 2014/12/04 15:22:05 christos Exp $") |
36#endif /* lint */ 37 38#include "magic.h" 39#include <assert.h> 40#include <string.h> 41#include <ctype.h> 42#include <stdlib.h> 43#include <time.h> | 36#endif /* lint */ 37 38#include "magic.h" 39#include <assert.h> 40#include <string.h> 41#include <ctype.h> 42#include <stdlib.h> 43#include <time.h> |
44#if defined(HAVE_LOCALE_H) 45#include <locale.h> 46#endif | |
47 | 44 |
48 | |
49private int match(struct magic_set *, struct magic *, uint32_t, | 45private int match(struct magic_set *, struct magic *, uint32_t, |
50 const unsigned char *, size_t, size_t, int, int, int, int, int *, int *, 51 int *); | 46 const unsigned char *, size_t, size_t, int, int, int, uint16_t, 47 uint16_t *, int *, int *, int *); |
52private int mget(struct magic_set *, const unsigned char *, | 48private int mget(struct magic_set *, const unsigned char *, |
53 struct magic *, size_t, size_t, unsigned int, int, int, int, int, int *, 54 int *, int *); | 49 struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t, 50 uint16_t *, int *, int *, int *); |
55private int magiccheck(struct magic_set *, struct magic *); 56private int32_t mprint(struct magic_set *, struct magic *); 57private int32_t moffset(struct magic_set *, struct magic *); 58private void mdebug(uint32_t, const char *, size_t); 59private int mcopy(struct magic_set *, union VALUETYPE *, int, int, 60 const unsigned char *, uint32_t, size_t, struct magic *); 61private int mconvert(struct magic_set *, struct magic *, int); 62private int print_sep(struct magic_set *, int); 63private int handle_annotation(struct magic_set *, struct magic *); 64private void cvt_8(union VALUETYPE *, const struct magic *); 65private void cvt_16(union VALUETYPE *, const struct magic *); 66private void cvt_32(union VALUETYPE *, const struct magic *); 67private void cvt_64(union VALUETYPE *, const struct magic *); 68 69#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) 70 | 51private int magiccheck(struct magic_set *, struct magic *); 52private int32_t mprint(struct magic_set *, struct magic *); 53private int32_t moffset(struct magic_set *, struct magic *); 54private void mdebug(uint32_t, const char *, size_t); 55private int mcopy(struct magic_set *, union VALUETYPE *, int, int, 56 const unsigned char *, uint32_t, size_t, struct magic *); 57private int mconvert(struct magic_set *, struct magic *, int); 58private int print_sep(struct magic_set *, int); 59private int handle_annotation(struct magic_set *, struct magic *); 60private void cvt_8(union VALUETYPE *, const struct magic *); 61private void cvt_16(union VALUETYPE *, const struct magic *); 62private void cvt_32(union VALUETYPE *, const struct magic *); 63private void cvt_64(union VALUETYPE *, const struct magic *); 64 65#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) 66 |
71#define MAX_RECURSION_LEVEL 10 72 | |
73/* 74 * softmagic - lookup one file in parsed, in-memory copy of database 75 * Passed the name and FILE * of one file to be typed. 76 */ 77/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ 78protected int 79file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, | 67/* 68 * softmagic - lookup one file in parsed, in-memory copy of database 69 * Passed the name and FILE * of one file to be typed. 70 */ 71/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ 72protected int 73file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, |
80 size_t level, int mode, int text) | 74 uint16_t indir_level, uint16_t *name_count, int mode, int text) |
81{ 82 struct mlist *ml; 83 int rv, printed_something = 0, need_separator = 0; | 75{ 76 struct mlist *ml; 77 int rv, printed_something = 0, need_separator = 0; |
78 uint16_t nc; 79 80 if (name_count == NULL) { 81 nc = 0; 82 name_count = &nc; 83 } 84 |
|
84 for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) 85 if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, | 85 for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) 86 if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, |
86 text, 0, level, &printed_something, &need_separator, 87 NULL)) != 0) | 87 text, 0, indir_level, name_count, 88 &printed_something, &need_separator, NULL)) != 0) |
88 return rv; 89 90 return 0; 91} 92 93#define FILE_FMTDEBUG 94#ifdef FILE_FMTDEBUG 95#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__) 96 97private const char * __attribute__((__format_arg__(3))) 98file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def, 99 const char *file, size_t line) 100{ 101 const char *ptr = fmtcheck(m->desc, def); 102 if (ptr == def) 103 file_magerror(ms, | 89 return rv; 90 91 return 0; 92} 93 94#define FILE_FMTDEBUG 95#ifdef FILE_FMTDEBUG 96#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__) 97 98private const char * __attribute__((__format_arg__(3))) 99file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def, 100 const char *file, size_t line) 101{ 102 const char *ptr = fmtcheck(m->desc, def); 103 if (ptr == def) 104 file_magerror(ms, |
104 "%s, %zu: format `%s' does not match with `%s'", 105 file, line, m->desc, def); | 105 "%s, %" SIZE_T_FORMAT "u: format `%s' does not match" 106 " with `%s'", file, line, m->desc, def); |
106 return ptr; 107} 108#else 109#define F(a, b, c) fmtcheck((b)->desc, (c)) 110#endif 111 112/* 113 * Go through the whole list, stopping if you find a match. Process all --- 20 unchanged lines hidden (view full) --- 134 * one, there's no lower-level continuation that may have failed. 135 * 136 * If a continuation matches, we bump the current continuation level 137 * so that higher-level continuations are processed. 138 */ 139private int 140match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, 141 const unsigned char *s, size_t nbytes, size_t offset, int mode, int text, | 107 return ptr; 108} 109#else 110#define F(a, b, c) fmtcheck((b)->desc, (c)) 111#endif 112 113/* 114 * Go through the whole list, stopping if you find a match. Process all --- 20 unchanged lines hidden (view full) --- 135 * one, there's no lower-level continuation that may have failed. 136 * 137 * If a continuation matches, we bump the current continuation level 138 * so that higher-level continuations are processed. 139 */ 140private int 141match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, 142 const unsigned char *s, size_t nbytes, size_t offset, int mode, int text, |
142 int flip, int recursion_level, int *printed_something, int *need_separator, 143 int *returnval) | 143 int flip, uint16_t indir_level, uint16_t *name_count, 144 int *printed_something, int *need_separator, int *returnval) |
144{ 145 uint32_t magindex = 0; 146 unsigned int cont_level = 0; 147 int returnvalv = 0, e; /* if a match is found it is set to 1*/ 148 int firstline = 1; /* a flag to print X\n X\n- X */ 149 int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0; 150 151 if (returnval == NULL) --- 20 unchanged lines hidden (view full) --- 172 continue; /* Skip to next top-level test*/ 173 } 174 175 ms->offset = m->offset; 176 ms->line = m->lineno; 177 178 /* if main entry matches, print it... */ 179 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text, | 145{ 146 uint32_t magindex = 0; 147 unsigned int cont_level = 0; 148 int returnvalv = 0, e; /* if a match is found it is set to 1*/ 149 int firstline = 1; /* a flag to print X\n X\n- X */ 150 int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0; 151 152 if (returnval == NULL) --- 20 unchanged lines hidden (view full) --- 173 continue; /* Skip to next top-level test*/ 174 } 175 176 ms->offset = m->offset; 177 ms->line = m->lineno; 178 179 /* if main entry matches, print it... */ 180 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text, |
180 flip, recursion_level + 1, printed_something, 181 need_separator, returnval)) { | 181 flip, indir_level, name_count, 182 printed_something, need_separator, returnval)) { |
182 case -1: 183 return -1; 184 case 0: 185 flush = m->reln != '!'; 186 break; 187 default: 188 if (m->type == FILE_INDIRECT) 189 *returnval = 1; --- 43 unchanged lines hidden (view full) --- 233 return -1; 234 235 ms->c.li[cont_level].off = moffset(ms, m); 236 237 /* and any continuations that match */ 238 if (file_check_mem(ms, ++cont_level) == -1) 239 return -1; 240 | 183 case -1: 184 return -1; 185 case 0: 186 flush = m->reln != '!'; 187 break; 188 default: 189 if (m->type == FILE_INDIRECT) 190 *returnval = 1; --- 43 unchanged lines hidden (view full) --- 234 return -1; 235 236 ms->c.li[cont_level].off = moffset(ms, m); 237 238 /* and any continuations that match */ 239 if (file_check_mem(ms, ++cont_level) == -1) 240 return -1; 241 |
241 while (++magindex < nmagic && 242 magic[magindex].cont_level != 0) { 243 m = &magic[magindex]; | 242 while (magindex + 1 < nmagic && 243 magic[magindex + 1].cont_level != 0) { 244 m = &magic[++magindex]; |
244 ms->line = m->lineno; /* for messages */ 245 246 if (cont_level < m->cont_level) 247 continue; 248 if (cont_level > m->cont_level) { 249 /* 250 * We're at the end of the level 251 * "cont_level" continuations. --- 9 unchanged lines hidden (view full) --- 261#ifdef ENABLE_CONDITIONALS 262 if (m->cond == COND_ELSE || 263 m->cond == COND_ELIF) { 264 if (ms->c.li[cont_level].last_match == 1) 265 continue; 266 } 267#endif 268 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, | 245 ms->line = m->lineno; /* for messages */ 246 247 if (cont_level < m->cont_level) 248 continue; 249 if (cont_level > m->cont_level) { 250 /* 251 * We're at the end of the level 252 * "cont_level" continuations. --- 9 unchanged lines hidden (view full) --- 262#ifdef ENABLE_CONDITIONALS 263 if (m->cond == COND_ELSE || 264 m->cond == COND_ELIF) { 265 if (ms->c.li[cont_level].last_match == 1) 266 continue; 267 } 268#endif 269 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, |
269 text, flip, recursion_level + 1, printed_something, 270 need_separator, returnval)) { | 270 text, flip, indir_level, name_count, 271 printed_something, need_separator, returnval)) { |
271 case -1: 272 return -1; 273 case 0: 274 if (m->reln != '!') 275 continue; 276 flush = 1; 277 break; 278 default: --- 119 unchanged lines hidden (view full) --- 398 if ((copy = malloc(len + 1)) == NULL) 399 return NULL; 400 (void)memcpy(copy, str, len); 401 copy[len] = '\0'; 402 return copy; 403} 404#endif /* HAVE_STRNDUP */ 405 | 272 case -1: 273 return -1; 274 case 0: 275 if (m->reln != '!') 276 continue; 277 flush = 1; 278 break; 279 default: --- 119 unchanged lines hidden (view full) --- 399 if ((copy = malloc(len + 1)) == NULL) 400 return NULL; 401 (void)memcpy(copy, str, len); 402 copy[len] = '\0'; 403 return copy; 404} 405#endif /* HAVE_STRNDUP */ 406 |
407static char * 408printable(char *buf, size_t bufsiz, const char *str) 409{ 410 char *ptr, *eptr; 411 const unsigned char *s = (const unsigned char *)str; 412 413 for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) { 414 if (isprint(*s)) { 415 *ptr++ = *s; 416 continue; 417 } 418 if (ptr >= eptr + 4) 419 break; 420 *ptr++ = '\\'; 421 *ptr++ = ((*s >> 6) & 7) + '0'; 422 *ptr++ = ((*s >> 3) & 7) + '0'; 423 *ptr++ = ((*s >> 0) & 7) + '0'; 424 } 425 *ptr = '\0'; 426 return buf; 427} 428 |
|
406private int32_t 407mprint(struct magic_set *ms, struct magic *m) 408{ 409 uint64_t v; 410 float vf; 411 double vd; 412 int64_t t = 0; 413 char buf[128], tbuf[26]; --- 90 unchanged lines hidden (view full) --- 504 case FILE_BESTRING16: 505 case FILE_LESTRING16: 506 if (m->reln == '=' || m->reln == '!') { 507 if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1) 508 return -1; 509 t = ms->offset + m->vallen; 510 } 511 else { | 429private int32_t 430mprint(struct magic_set *ms, struct magic *m) 431{ 432 uint64_t v; 433 float vf; 434 double vd; 435 int64_t t = 0; 436 char buf[128], tbuf[26]; --- 90 unchanged lines hidden (view full) --- 527 case FILE_BESTRING16: 528 case FILE_LESTRING16: 529 if (m->reln == '=' || m->reln == '!') { 530 if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1) 531 return -1; 532 t = ms->offset + m->vallen; 533 } 534 else { |
535 char sbuf[512]; |
|
512 char *str = p->s; 513 514 /* compute t before we mangle the string? */ 515 t = ms->offset + strlen(str); 516 517 if (*m->value.s == '\0') 518 str[strcspn(str, "\n")] = '\0'; 519 --- 5 unchanged lines hidden (view full) --- 525 while (*last) 526 last++; 527 --last; 528 while (isspace((unsigned char)*last)) 529 last--; 530 *++last = '\0'; 531 } 532 | 536 char *str = p->s; 537 538 /* compute t before we mangle the string? */ 539 t = ms->offset + strlen(str); 540 541 if (*m->value.s == '\0') 542 str[strcspn(str, "\n")] = '\0'; 543 --- 5 unchanged lines hidden (view full) --- 549 while (*last) 550 last++; 551 --last; 552 while (isspace((unsigned char)*last)) 553 last--; 554 *++last = '\0'; 555 } 556 |
533 if (file_printf(ms, F(ms, m, "%s"), str) == -1) | 557 if (file_printf(ms, F(ms, m, "%s"), 558 printable(sbuf, sizeof(sbuf), str)) == -1) |
534 return -1; 535 536 if (m->type == FILE_PSTRING) 537 t += file_pstring_length_size(m); 538 } 539 break; 540 541 case FILE_DATE: --- 399 unchanged lines hidden (view full) --- 941 /* Null terminate and eat *trailing* return */ 942 p->s[sizeof(p->s) - 1] = '\0'; 943 return 1; 944 } 945 case FILE_PSTRING: { 946 size_t sz = file_pstring_length_size(m); 947 char *ptr1 = p->s, *ptr2 = ptr1 + sz; 948 size_t len = file_pstring_get_length(m, ptr1); | 559 return -1; 560 561 if (m->type == FILE_PSTRING) 562 t += file_pstring_length_size(m); 563 } 564 break; 565 566 case FILE_DATE: --- 399 unchanged lines hidden (view full) --- 966 /* Null terminate and eat *trailing* return */ 967 p->s[sizeof(p->s) - 1] = '\0'; 968 return 1; 969 } 970 case FILE_PSTRING: { 971 size_t sz = file_pstring_length_size(m); 972 char *ptr1 = p->s, *ptr2 = ptr1 + sz; 973 size_t len = file_pstring_get_length(m, ptr1); |
949 if (len >= sizeof(p->s)) { | 974 sz = sizeof(p->s) - sz; /* maximum length of string */ 975 if (len >= sz) { |
950 /* 951 * The size of the pascal string length (sz) 952 * is 1, 2, or 4. We need at least 1 byte for NUL 953 * termination, but we've already truncated the 954 * string by p->s, so we need to deduct sz. | 976 /* 977 * The size of the pascal string length (sz) 978 * is 1, 2, or 4. We need at least 1 byte for NUL 979 * termination, but we've already truncated the 980 * string by p->s, so we need to deduct sz. |
981 * Because we can use one of the bytes of the length 982 * after we shifted as NUL termination. |
|
955 */ | 983 */ |
956 len = sizeof(p->s) - sz; | 984 len = sz; |
957 } 958 while (len--) 959 *ptr1++ = *ptr2++; 960 *ptr1 = '\0'; 961 return 1; 962 } 963 case FILE_BESHORT: 964 p->h = (short)((p->hs[0]<<8)|(p->hs[1])); --- 93 unchanged lines hidden (view full) --- 1058 return 0; 1059 } 1060} 1061 1062 1063private void 1064mdebug(uint32_t offset, const char *str, size_t len) 1065{ | 985 } 986 while (len--) 987 *ptr1++ = *ptr2++; 988 *ptr1 = '\0'; 989 return 1; 990 } 991 case FILE_BESHORT: 992 p->h = (short)((p->hs[0]<<8)|(p->hs[1])); --- 93 unchanged lines hidden (view full) --- 1086 return 0; 1087 } 1088} 1089 1090 1091private void 1092mdebug(uint32_t offset, const char *str, size_t len) 1093{ |
1066 (void) fprintf(stderr, "mget/%zu @%d: ", len, offset); | 1094 (void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset); |
1067 file_showstr(stderr, str, len); 1068 (void) fputc('\n', stderr); 1069 (void) fputc('\n', stderr); 1070} 1071 1072private int 1073mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, 1074 const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m) --- 113 unchanged lines hidden (view full) --- 1188 (void)memset(((char *)(void *)p) + nbytes, '\0', 1189 sizeof(*p) - nbytes); 1190 return 0; 1191} 1192 1193private int 1194mget(struct magic_set *ms, const unsigned char *s, struct magic *m, 1195 size_t nbytes, size_t o, unsigned int cont_level, int mode, int text, | 1095 file_showstr(stderr, str, len); 1096 (void) fputc('\n', stderr); 1097 (void) fputc('\n', stderr); 1098} 1099 1100private int 1101mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, 1102 const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m) --- 113 unchanged lines hidden (view full) --- 1216 (void)memset(((char *)(void *)p) + nbytes, '\0', 1217 sizeof(*p) - nbytes); 1218 return 0; 1219} 1220 1221private int 1222mget(struct magic_set *ms, const unsigned char *s, struct magic *m, 1223 size_t nbytes, size_t o, unsigned int cont_level, int mode, int text, |
1196 int flip, int recursion_level, int *printed_something, 1197 int *need_separator, int *returnval) | 1224 int flip, uint16_t indir_level, uint16_t *name_count, 1225 int *printed_something, int *need_separator, int *returnval) |
1198{ 1199 uint32_t offset = ms->offset; 1200 uint32_t lhs; 1201 file_pushbuf_t *pb; 1202 int rv, oneed_separator, in_type; 1203 char *rbuf; 1204 union VALUETYPE *p = &ms->ms_value; 1205 struct mlist ml; 1206 | 1226{ 1227 uint32_t offset = ms->offset; 1228 uint32_t lhs; 1229 file_pushbuf_t *pb; 1230 int rv, oneed_separator, in_type; 1231 char *rbuf; 1232 union VALUETYPE *p = &ms->ms_value; 1233 struct mlist ml; 1234 |
1207 if (recursion_level >= MAX_RECURSION_LEVEL) { 1208 file_error(ms, 0, "recursion nesting exceeded"); | 1235 if (indir_level >= ms->indir_max) { 1236 file_error(ms, 0, "indirect recursion nesting (%hu) exceeded", 1237 indir_level); |
1209 return -1; 1210 } 1211 | 1238 return -1; 1239 } 1240 |
1241 if (*name_count >= ms->name_max) { 1242 file_error(ms, 0, "name use count (%hu) exceeded", 1243 *name_count); 1244 return -1; 1245 } 1246 |
|
1212 if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o), 1213 (uint32_t)nbytes, m) == -1) 1214 return -1; 1215 1216 if ((ms->flags & MAGIC_DEBUG) != 0) { | 1247 if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o), 1248 (uint32_t)nbytes, m) == -1) 1249 return -1; 1250 1251 if ((ms->flags & MAGIC_DEBUG) != 0) { |
1217 fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, " 1218 "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes); | 1252 fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%" 1253 SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT 1254 "u, il=%hu, nc=%hu)\n", 1255 m->type, m->flag, offset, o, nbytes, 1256 indir_level, *name_count); |
1219 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); 1220#ifndef COMPILE_ONLY 1221 file_mdump(m); 1222#endif 1223 } 1224 1225 if (m->flag & INDIR) { 1226 int off = m->in_offset; --- 424 unchanged lines hidden (view full) --- 1651 1652 if (nbytes < offset) 1653 return 0; 1654 1655 if ((pb = file_push_buffer(ms)) == NULL) 1656 return -1; 1657 1658 rv = file_softmagic(ms, s + offset, nbytes - offset, | 1257 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); 1258#ifndef COMPILE_ONLY 1259 file_mdump(m); 1260#endif 1261 } 1262 1263 if (m->flag & INDIR) { 1264 int off = m->in_offset; --- 424 unchanged lines hidden (view full) --- 1689 1690 if (nbytes < offset) 1691 return 0; 1692 1693 if ((pb = file_push_buffer(ms)) == NULL) 1694 return -1; 1695 1696 rv = file_softmagic(ms, s + offset, nbytes - offset, |
1659 recursion_level, BINTEST, text); | 1697 indir_level + 1, name_count, BINTEST, text); |
1660 1661 if ((ms->flags & MAGIC_DEBUG) != 0) 1662 fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); 1663 1664 rbuf = file_pop_buffer(ms, pb); 1665 if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR) 1666 return -1; 1667 --- 18 unchanged lines hidden (view full) --- 1686 if (*rbuf == '^') { 1687 rbuf++; 1688 flip = !flip; 1689 } 1690 if (file_magicfind(ms, rbuf, &ml) == -1) { 1691 file_error(ms, 0, "cannot find entry `%s'", rbuf); 1692 return -1; 1693 } | 1698 1699 if ((ms->flags & MAGIC_DEBUG) != 0) 1700 fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); 1701 1702 rbuf = file_pop_buffer(ms, pb); 1703 if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR) 1704 return -1; 1705 --- 18 unchanged lines hidden (view full) --- 1724 if (*rbuf == '^') { 1725 rbuf++; 1726 flip = !flip; 1727 } 1728 if (file_magicfind(ms, rbuf, &ml) == -1) { 1729 file_error(ms, 0, "cannot find entry `%s'", rbuf); 1730 return -1; 1731 } |
1694 | 1732 (*name_count)++; |
1695 oneed_separator = *need_separator; 1696 if (m->flag & NOSPACE) 1697 *need_separator = 0; 1698 rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o, | 1733 oneed_separator = *need_separator; 1734 if (m->flag & NOSPACE) 1735 *need_separator = 0; 1736 rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o, |
1699 mode, text, flip, recursion_level, printed_something, 1700 need_separator, returnval); | 1737 mode, text, flip, indir_level, name_count, 1738 printed_something, need_separator, returnval); |
1701 if (rv != 1) 1702 *need_separator = oneed_separator; 1703 return rv; 1704 1705 case FILE_NAME: 1706 if (file_printf(ms, "%s", m->desc) == -1) 1707 return -1; 1708 return 1; --- 238 unchanged lines hidden (view full) --- 1947 break; 1948 } 1949 } 1950 break; 1951 } 1952 case FILE_REGEX: { 1953 int rc; 1954 file_regex_t rx; | 1739 if (rv != 1) 1740 *need_separator = oneed_separator; 1741 return rv; 1742 1743 case FILE_NAME: 1744 if (file_printf(ms, "%s", m->desc) == -1) 1745 return -1; 1746 return 1; --- 238 unchanged lines hidden (view full) --- 1985 break; 1986 } 1987 } 1988 break; 1989 } 1990 case FILE_REGEX: { 1991 int rc; 1992 file_regex_t rx; |
1993 const char *search; |
|
1955 1956 if (ms->search.s == NULL) 1957 return 0; 1958 1959 l = 0; 1960 rc = file_regcomp(&rx, m->value.s, 1961 REG_EXTENDED|REG_NEWLINE| 1962 ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0)); 1963 if (rc) { 1964 file_regerror(&rx, rc, ms); 1965 v = (uint64_t)-1; 1966 } else { 1967 regmatch_t pmatch[1]; 1968 size_t slen = ms->search.s_len; 1969#ifndef REG_STARTEND 1970#define REG_STARTEND 0 | 1994 1995 if (ms->search.s == NULL) 1996 return 0; 1997 1998 l = 0; 1999 rc = file_regcomp(&rx, m->value.s, 2000 REG_EXTENDED|REG_NEWLINE| 2001 ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0)); 2002 if (rc) { 2003 file_regerror(&rx, rc, ms); 2004 v = (uint64_t)-1; 2005 } else { 2006 regmatch_t pmatch[1]; 2007 size_t slen = ms->search.s_len; 2008#ifndef REG_STARTEND 2009#define REG_STARTEND 0 |
1971 char c; 1972 if (slen != 0) 1973 slen--; 1974 c = ms->search.s[slen]; 1975 ((char *)(intptr_t)ms->search.s)[slen] = '\0'; | 2010 char *copy; 2011 if (slen != 0) { 2012 copy = malloc(slen); 2013 if (copy == NULL) { 2014 file_error(ms, errno, 2015 "can't allocate %" SIZE_T_FORMAT "u bytes", 2016 slen); 2017 return -1; 2018 } 2019 memcpy(copy, ms->search.s, slen); 2020 copy[--slen] = '\0'; 2021 search = copy; 2022 } else { 2023 search = ms->search.s; 2024 copy = NULL; 2025 } |
1976#else | 2026#else |
2027 search = ms->search.s; |
|
1977 pmatch[0].rm_so = 0; 1978 pmatch[0].rm_eo = slen; 1979#endif | 2028 pmatch[0].rm_so = 0; 2029 pmatch[0].rm_eo = slen; 2030#endif |
1980 rc = file_regexec(&rx, (const char *)ms->search.s, | 2031 rc = file_regexec(&rx, (const char *)search, |
1981 1, pmatch, REG_STARTEND); 1982#if REG_STARTEND == 0 | 2032 1, pmatch, REG_STARTEND); 2033#if REG_STARTEND == 0 |
1983 ((char *)(intptr_t)ms->search.s)[l] = c; | 2034 free(copy); |
1984#endif 1985 switch (rc) { 1986 case 0: 1987 ms->search.s += (int)pmatch[0].rm_so; 1988 ms->search.offset += (size_t)pmatch[0].rm_so; 1989 ms->search.rm_len = 1990 (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so); 1991 v = 0; --- 146 unchanged lines hidden --- | 2035#endif 2036 switch (rc) { 2037 case 0: 2038 ms->search.s += (int)pmatch[0].rm_so; 2039 ms->search.offset += (size_t)pmatch[0].rm_so; 2040 ms->search.rm_len = 2041 (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so); 2042 v = 0; --- 146 unchanged lines hidden --- |