softmagic.c (111658) | softmagic.c (133359) |
---|---|
1/* | 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: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice immediately at the beginning of the file, without modification, 11 * this list of conditions, and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Ian F. Darwin and others. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33/* |
|
2 * softmagic - interpret variable magic from MAGIC | 34 * softmagic - interpret variable magic from MAGIC |
3 * 4 * Copyright (c) Ian F. Darwin, 1987. 5 * Written by Ian F. Darwin. 6 * 7 * This software is not subject to any license of the American Telephone 8 * and Telegraph Company or of the Regents of the University of California. 9 * 10 * Permission is granted to anyone to use this software for any purpose on 11 * any computer system, and to alter it and redistribute it freely, subject 12 * to the following restrictions: 13 * 14 * 1. The author is not responsible for the consequences of use of this 15 * software, no matter how awful, even if they arise from flaws in it. 16 * 17 * 2. The origin of this software must not be misrepresented, either by 18 * explicit claim or by omission. Since few users ever read sources, 19 * credits must appear in the documentation. 20 * 21 * 3. Altered versions must be plainly marked as such, and must not be 22 * misrepresented as being the original software. Since few users 23 * ever read sources, credits must appear in the documentation. 24 * 25 * 4. This notice may not be removed or altered. | |
26 */ 27 28#include "file.h" | 35 */ 36 37#include "file.h" |
38#include "magic.h" |
|
29#include <string.h> 30#include <ctype.h> 31#include <stdlib.h> 32#include <time.h> 33#include <regex.h> 34 35 36#ifndef lint | 39#include <string.h> 40#include <ctype.h> 41#include <stdlib.h> 42#include <time.h> 43#include <regex.h> 44 45 46#ifndef lint |
37FILE_RCSID("@(#)$Id: softmagic.c,v 1.54 2003/02/25 13:04:32 christos Exp $") | 47FILE_RCSID("@(#)$Id: softmagic.c,v 1.66 2004/07/24 20:38:56 christos Exp $") |
38#endif /* lint */ 39 | 48#endif /* lint */ 49 |
40static int match(struct magic *, uint32_t, unsigned char *, int); 41static int mget(union VALUETYPE *, unsigned char *, struct magic *, int); 42static int mcheck(union VALUETYPE *, struct magic *); 43static int32_t mprint(union VALUETYPE *, struct magic *); 44static void mdebug(int32_t, char *, int); 45static int mconvert(union VALUETYPE *, struct magic *); | 50private int match(struct magic_set *, struct magic *, uint32_t, 51 const unsigned char *, size_t); 52private int mget(struct magic_set *, union VALUETYPE *, const unsigned char *, 53 struct magic *, size_t); 54private int mcheck(struct magic_set *, union VALUETYPE *, struct magic *); 55private int32_t mprint(struct magic_set *, union VALUETYPE *, struct magic *); 56private void mdebug(uint32_t, const char *, size_t); 57private int mconvert(struct magic_set *, union VALUETYPE *, struct magic *); 58private int check_mem(struct magic_set *, unsigned int); |
46 | 59 |
47extern int kflag; 48 | |
49/* 50 * softmagic - lookup one file in database 51 * (already read from MAGIC by apprentice.c). 52 * Passed the name and FILE * of one file to be typed. 53 */ 54/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ | 60/* 61 * softmagic - lookup one file in database 62 * (already read from MAGIC by apprentice.c). 63 * Passed the name and FILE * of one file to be typed. 64 */ 65/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ |
55int 56softmagic(unsigned char *buf, int nbytes) | 66protected int 67file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes) |
57{ 58 struct mlist *ml; | 68{ 69 struct mlist *ml; |
59 60 for (ml = mlist.next; ml != &mlist; ml = ml->next) 61 if (match(ml->magic, ml->nmagic, buf, nbytes)) | 70 for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next) 71 if (match(ms, ml->magic, ml->nmagic, buf, nbytes)) |
62 return 1; 63 64 return 0; 65} 66 67/* 68 * Go through the whole list, stopping if you find a match. Process all 69 * the continuations of that match before returning. --- 16 unchanged lines hidden (view full) --- 86 * level reverts to the level of the one we're seeing. 87 * 88 * Continuations at the current level are processed as, if we see 89 * one, there's no lower-level continuation that may have failed. 90 * 91 * If a continuation matches, we bump the current continuation level 92 * so that higher-level continuations are processed. 93 */ | 72 return 1; 73 74 return 0; 75} 76 77/* 78 * Go through the whole list, stopping if you find a match. Process all 79 * the continuations of that match before returning. --- 16 unchanged lines hidden (view full) --- 96 * level reverts to the level of the one we're seeing. 97 * 98 * Continuations at the current level are processed as, if we see 99 * one, there's no lower-level continuation that may have failed. 100 * 101 * If a continuation matches, we bump the current continuation level 102 * so that higher-level continuations are processed. 103 */ |
94static int 95match(struct magic *magic, uint32_t nmagic, unsigned char *s, int nbytes) | 104private int 105match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, 106 const unsigned char *s, size_t nbytes) |
96{ | 107{ |
97 int magindex = 0; 98 int cont_level = 0; | 108 uint32_t magindex = 0; 109 unsigned int cont_level = 0; |
99 int need_separator = 0; 100 union VALUETYPE p; | 110 int need_separator = 0; 111 union VALUETYPE p; |
101 static int32_t *tmpoff = NULL; 102 static size_t tmplen = 0; | |
103 int32_t oldoff = 0; 104 int returnval = 0; /* if a match is found it is set to 1*/ 105 int firstline = 1; /* a flag to print X\n X\n- X */ 106 | 112 int32_t oldoff = 0; 113 int returnval = 0; /* if a match is found it is set to 1*/ 114 int firstline = 1; /* a flag to print X\n X\n- X */ 115 |
107 if (tmpoff == NULL) 108 if ((tmpoff = (int32_t *) malloc( 109 (tmplen = 20) * sizeof(*tmpoff))) == NULL) 110 error("out of memory\n"); | 116 if (check_mem(ms, cont_level) == -1) 117 return -1; |
111 112 for (magindex = 0; magindex < nmagic; magindex++) { 113 /* if main entry matches, print it... */ | 118 119 for (magindex = 0; magindex < nmagic; magindex++) { 120 /* if main entry matches, print it... */ |
114 if (!mget(&p, s, &magic[magindex], nbytes) || 115 !mcheck(&p, &magic[magindex])) { 116 /* 117 * main entry didn't match, 118 * flush its continuations 119 */ 120 while (magindex < nmagic && 121 magic[magindex + 1].cont_level != 0) 122 magindex++; 123 continue; | 121 int flush = !mget(ms, &p, s, &magic[magindex], nbytes); 122 switch (mcheck(ms, &p, &magic[magindex])) { 123 case -1: 124 return -1; 125 case 0: 126 flush++; 127 break; 128 default: 129 break; |
124 } | 130 } |
131 if (flush) { 132 /* 133 * main entry didn't match, 134 * flush its continuations 135 */ 136 while (magindex < nmagic - 1 && 137 magic[magindex + 1].cont_level != 0) 138 magindex++; 139 continue; 140 } |
|
125 | 141 |
126 if (! firstline) { /* we found another match */ | 142 if (!firstline) { /* we found another match */ |
127 /* put a newline and '-' to do some simple formatting*/ | 143 /* put a newline and '-' to do some simple formatting*/ |
128 printf("\n- "); | 144 if (file_printf(ms, "\n- ") == -1) 145 return -1; |
129 } 130 | 146 } 147 |
131 tmpoff[cont_level] = mprint(&p, &magic[magindex]); | 148 if ((ms->c.off[cont_level] = mprint(ms, &p, &magic[magindex])) 149 == -1) 150 return -1; |
132 /* 133 * If we printed something, we'll need to print 134 * a blank before we print something else. 135 */ 136 if (magic[magindex].desc[0]) 137 need_separator = 1; 138 /* and any continuations that match */ | 151 /* 152 * If we printed something, we'll need to print 153 * a blank before we print something else. 154 */ 155 if (magic[magindex].desc[0]) 156 need_separator = 1; 157 /* and any continuations that match */ |
139 if (++cont_level >= tmplen) 140 if ((tmpoff = (int32_t *) realloc(tmpoff, 141 (tmplen += 20) * sizeof(*tmpoff))) == NULL) 142 error("out of memory\n"); | 158 if (check_mem(ms, ++cont_level) == -1) 159 return -1; 160 |
143 while (magic[magindex+1].cont_level != 0 && 144 ++magindex < nmagic) { | 161 while (magic[magindex+1].cont_level != 0 && 162 ++magindex < nmagic) { |
145 if (cont_level >= magic[magindex].cont_level) { 146 if (cont_level > magic[magindex].cont_level) { 147 /* 148 * We're at the end of the level 149 * "cont_level" continuations. 150 */ 151 cont_level = magic[magindex].cont_level; | 163 if (cont_level < magic[magindex].cont_level) 164 continue; 165 if (cont_level > magic[magindex].cont_level) { 166 /* 167 * We're at the end of the level 168 * "cont_level" continuations. 169 */ 170 cont_level = magic[magindex].cont_level; 171 } 172 if (magic[magindex].flag & OFFADD) { 173 oldoff=magic[magindex].offset; 174 magic[magindex].offset += ms->c.off[cont_level-1]; 175 } 176 if (!mget(ms, &p, s, &magic[magindex], nbytes)) 177 goto done; 178 179 switch (mcheck(ms, &p, &magic[magindex])) { 180 case -1: 181 return -1; 182 case 0: 183 break; 184 default: 185 /* 186 * This continuation matched. 187 * Print its message, with 188 * a blank before it if 189 * the previous item printed 190 * and this item isn't empty. 191 */ 192 /* space if previous printed */ 193 if (need_separator 194 && (magic[magindex].nospflag == 0) 195 && (magic[magindex].desc[0] != '\0')) { 196 if (file_printf(ms, " ") == -1) 197 return -1; 198 need_separator = 0; |
152 } | 199 } |
153 if (magic[magindex].flag & OFFADD) { 154 oldoff=magic[magindex].offset; 155 magic[magindex].offset += 156 tmpoff[cont_level-1]; 157 } 158 if (mget(&p, s, &magic[magindex], nbytes) && 159 mcheck(&p, &magic[magindex])) { 160 /* 161 * This continuation matched. 162 * Print its message, with 163 * a blank before it if 164 * the previous item printed 165 * and this item isn't empty. 166 */ 167 /* space if previous printed */ 168 if (need_separator 169 && (magic[magindex].nospflag == 0) 170 && (magic[magindex].desc[0] != '\0') 171 ) { 172 (void) putchar(' '); 173 need_separator = 0; 174 } 175 tmpoff[cont_level] = 176 mprint(&p, &magic[magindex]); 177 if (magic[magindex].desc[0]) 178 need_separator = 1; | 200 if ((ms->c.off[cont_level] = mprint(ms, &p, 201 &magic[magindex])) == -1) 202 return -1; 203 if (magic[magindex].desc[0]) 204 need_separator = 1; |
179 | 205 |
180 /* 181 * If we see any continuations 182 * at a higher level, 183 * process them. 184 */ 185 if (++cont_level >= tmplen) 186 if ((tmpoff = 187 (int32_t *) realloc(tmpoff, 188 (tmplen += 20) 189 * sizeof(*tmpoff))) == NULL) 190 error("out of memory\n"); 191 } 192 if (magic[magindex].flag & OFFADD) { 193 magic[magindex].offset = oldoff; 194 } | 206 /* 207 * If we see any continuations 208 * at a higher level, 209 * process them. 210 */ 211 if (check_mem(ms, ++cont_level) == -1) 212 return -1; |
195 } | 213 } |
214done: 215 if (magic[magindex].flag & OFFADD) { 216 magic[magindex].offset = oldoff; 217 } |
|
196 } 197 firstline = 0; 198 returnval = 1; | 218 } 219 firstline = 0; 220 returnval = 1; |
199 if (!kflag) { | 221 if ((ms->flags & MAGIC_CONTINUE) == 0) { |
200 return 1; /* don't keep searching */ 201 } 202 } 203 return returnval; /* This is hit if -k is set or there is no match */ 204} 205 | 222 return 1; /* don't keep searching */ 223 } 224 } 225 return returnval; /* This is hit if -k is set or there is no match */ 226} 227 |
206static int32_t 207mprint(union VALUETYPE *p, struct magic *m) | 228private int 229check_mem(struct magic_set *ms, unsigned int level) |
208{ | 230{ |
231 size_t len; 232 233 if (level < ms->c.len) 234 return 0; 235 236 len = (ms->c.len += 20) * sizeof(*ms->c.off); 237 ms->c.off = (ms->c.off == NULL) ? malloc(len) : realloc(ms->c.off, len); 238 if (ms->c.off != NULL) 239 return 0; 240 file_oomem(ms); 241 return -1; 242} 243 244private int32_t 245mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m) 246{ |
|
209 uint32_t v; 210 int32_t t=0 ; 211 212 213 switch (m->type) { | 247 uint32_t v; 248 int32_t t=0 ; 249 250 251 switch (m->type) { |
214 case BYTE: 215 v = signextend(m, p->b); 216 (void) printf(m->desc, (unsigned char) v); | 252 case FILE_BYTE: 253 v = file_signextend(ms, m, (size_t)p->b); 254 if (file_printf(ms, m->desc, (unsigned char) v) == -1) 255 return -1; |
217 t = m->offset + sizeof(char); 218 break; 219 | 256 t = m->offset + sizeof(char); 257 break; 258 |
220 case SHORT: 221 case BESHORT: 222 case LESHORT: 223 v = signextend(m, p->h); 224 (void) printf(m->desc, (unsigned short) v); | 259 case FILE_SHORT: 260 case FILE_BESHORT: 261 case FILE_LESHORT: 262 v = file_signextend(ms, m, (size_t)p->h); 263 if (file_printf(ms, m->desc, (unsigned short) v) == -1) 264 return -1; |
225 t = m->offset + sizeof(short); 226 break; 227 | 265 t = m->offset + sizeof(short); 266 break; 267 |
228 case LONG: 229 case BELONG: 230 case LELONG: 231 v = signextend(m, p->l); 232 (void) printf(m->desc, (uint32_t) v); | 268 case FILE_LONG: 269 case FILE_BELONG: 270 case FILE_LELONG: 271 v = file_signextend(ms, m, p->l); 272 if (file_printf(ms, m->desc, (uint32_t) v) == -1) 273 return -1; |
233 t = m->offset + sizeof(int32_t); 234 break; 235 | 274 t = m->offset + sizeof(int32_t); 275 break; 276 |
236 case STRING: 237 case PSTRING: | 277 case FILE_STRING: 278 case FILE_PSTRING: |
238 if (m->reln == '=') { | 279 if (m->reln == '=') { |
239 (void) printf(m->desc, m->value.s); | 280 if (file_printf(ms, m->desc, m->value.s) == -1) 281 return -1; |
240 t = m->offset + strlen(m->value.s); 241 } 242 else { 243 if (*m->value.s == '\0') { 244 char *cp = strchr(p->s,'\n'); 245 if (cp) 246 *cp = '\0'; 247 } | 282 t = m->offset + strlen(m->value.s); 283 } 284 else { 285 if (*m->value.s == '\0') { 286 char *cp = strchr(p->s,'\n'); 287 if (cp) 288 *cp = '\0'; 289 } |
248 (void) printf(m->desc, p->s); | 290 if (file_printf(ms, m->desc, p->s) == -1) 291 return -1; |
249 t = m->offset + strlen(p->s); 250 } 251 break; 252 | 292 t = m->offset + strlen(p->s); 293 } 294 break; 295 |
253 case DATE: 254 case BEDATE: 255 case LEDATE: 256 (void) printf(m->desc, fmttime(p->l, 1)); | 296 case FILE_DATE: 297 case FILE_BEDATE: 298 case FILE_LEDATE: 299 if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1) 300 return -1; |
257 t = m->offset + sizeof(time_t); 258 break; 259 | 301 t = m->offset + sizeof(time_t); 302 break; 303 |
260 case LDATE: 261 case BELDATE: 262 case LELDATE: 263 (void) printf(m->desc, fmttime(p->l, 0)); | 304 case FILE_LDATE: 305 case FILE_BELDATE: 306 case FILE_LELDATE: 307 if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1) 308 return -1; |
264 t = m->offset + sizeof(time_t); 265 break; | 309 t = m->offset + sizeof(time_t); 310 break; |
266 case REGEX: 267 (void) printf(m->desc, p->s); | 311 case FILE_REGEX: 312 if (file_printf(ms, m->desc, p->s) == -1) 313 return -1; |
268 t = m->offset + strlen(p->s); 269 break; 270 271 default: | 314 t = m->offset + strlen(p->s); 315 break; 316 317 default: |
272 error("invalid m->type (%d) in mprint().\n", m->type); 273 /*NOTREACHED*/ | 318 file_error(ms, 0, "invalid m->type (%d) in mprint()", m->type); 319 return -1; |
274 } 275 return(t); 276} 277 278/* 279 * Convert the byte order of the data we are looking at 280 * While we're here, let's apply the mask operation 281 * (unless you have a better idea) 282 */ | 320 } 321 return(t); 322} 323 324/* 325 * Convert the byte order of the data we are looking at 326 * While we're here, let's apply the mask operation 327 * (unless you have a better idea) 328 */ |
283static int 284mconvert(union VALUETYPE *p, struct magic *m) | 329private int 330mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m) |
285{ 286 switch (m->type) { | 331{ 332 switch (m->type) { |
287 case BYTE: | 333 case FILE_BYTE: |
288 if (m->mask) 289 switch (m->mask_op&0x7F) { | 334 if (m->mask) 335 switch (m->mask_op&0x7F) { |
290 case OPAND: | 336 case FILE_OPAND: |
291 p->b &= m->mask; 292 break; | 337 p->b &= m->mask; 338 break; |
293 case OPOR: | 339 case FILE_OPOR: |
294 p->b |= m->mask; 295 break; | 340 p->b |= m->mask; 341 break; |
296 case OPXOR: | 342 case FILE_OPXOR: |
297 p->b ^= m->mask; 298 break; | 343 p->b ^= m->mask; 344 break; |
299 case OPADD: | 345 case FILE_OPADD: |
300 p->b += m->mask; 301 break; | 346 p->b += m->mask; 347 break; |
302 case OPMINUS: | 348 case FILE_OPMINUS: |
303 p->b -= m->mask; 304 break; | 349 p->b -= m->mask; 350 break; |
305 case OPMULTIPLY: | 351 case FILE_OPMULTIPLY: |
306 p->b *= m->mask; 307 break; | 352 p->b *= m->mask; 353 break; |
308 case OPDIVIDE: | 354 case FILE_OPDIVIDE: |
309 p->b /= m->mask; 310 break; | 355 p->b /= m->mask; 356 break; |
311 case OPMODULO: | 357 case FILE_OPMODULO: |
312 p->b %= m->mask; 313 break; 314 } | 358 p->b %= m->mask; 359 break; 360 } |
315 if (m->mask_op & OPINVERSE) | 361 if (m->mask_op & FILE_OPINVERSE) |
316 p->b = ~p->b; 317 return 1; | 362 p->b = ~p->b; 363 return 1; |
318 case SHORT: | 364 case FILE_SHORT: |
319 if (m->mask) 320 switch (m->mask_op&0x7F) { | 365 if (m->mask) 366 switch (m->mask_op&0x7F) { |
321 case OPAND: | 367 case FILE_OPAND: |
322 p->h &= m->mask; 323 break; | 368 p->h &= m->mask; 369 break; |
324 case OPOR: | 370 case FILE_OPOR: |
325 p->h |= m->mask; 326 break; | 371 p->h |= m->mask; 372 break; |
327 case OPXOR: | 373 case FILE_OPXOR: |
328 p->h ^= m->mask; 329 break; | 374 p->h ^= m->mask; 375 break; |
330 case OPADD: | 376 case FILE_OPADD: |
331 p->h += m->mask; 332 break; | 377 p->h += m->mask; 378 break; |
333 case OPMINUS: | 379 case FILE_OPMINUS: |
334 p->h -= m->mask; 335 break; | 380 p->h -= m->mask; 381 break; |
336 case OPMULTIPLY: | 382 case FILE_OPMULTIPLY: |
337 p->h *= m->mask; 338 break; | 383 p->h *= m->mask; 384 break; |
339 case OPDIVIDE: | 385 case FILE_OPDIVIDE: |
340 p->h /= m->mask; 341 break; | 386 p->h /= m->mask; 387 break; |
342 case OPMODULO: | 388 case FILE_OPMODULO: |
343 p->h %= m->mask; 344 break; 345 } | 389 p->h %= m->mask; 390 break; 391 } |
346 if (m->mask_op & OPINVERSE) | 392 if (m->mask_op & FILE_OPINVERSE) |
347 p->h = ~p->h; 348 return 1; | 393 p->h = ~p->h; 394 return 1; |
349 case LONG: 350 case DATE: 351 case LDATE: | 395 case FILE_LONG: 396 case FILE_DATE: 397 case FILE_LDATE: |
352 if (m->mask) 353 switch (m->mask_op&0x7F) { | 398 if (m->mask) 399 switch (m->mask_op&0x7F) { |
354 case OPAND: | 400 case FILE_OPAND: |
355 p->l &= m->mask; 356 break; | 401 p->l &= m->mask; 402 break; |
357 case OPOR: | 403 case FILE_OPOR: |
358 p->l |= m->mask; 359 break; | 404 p->l |= m->mask; 405 break; |
360 case OPXOR: | 406 case FILE_OPXOR: |
361 p->l ^= m->mask; 362 break; | 407 p->l ^= m->mask; 408 break; |
363 case OPADD: | 409 case FILE_OPADD: |
364 p->l += m->mask; 365 break; | 410 p->l += m->mask; 411 break; |
366 case OPMINUS: | 412 case FILE_OPMINUS: |
367 p->l -= m->mask; 368 break; | 413 p->l -= m->mask; 414 break; |
369 case OPMULTIPLY: | 415 case FILE_OPMULTIPLY: |
370 p->l *= m->mask; 371 break; | 416 p->l *= m->mask; 417 break; |
372 case OPDIVIDE: | 418 case FILE_OPDIVIDE: |
373 p->l /= m->mask; 374 break; | 419 p->l /= m->mask; 420 break; |
375 case OPMODULO: | 421 case FILE_OPMODULO: |
376 p->l %= m->mask; 377 break; 378 } | 422 p->l %= m->mask; 423 break; 424 } |
379 if (m->mask_op & OPINVERSE) | 425 if (m->mask_op & FILE_OPINVERSE) |
380 p->l = ~p->l; 381 return 1; | 426 p->l = ~p->l; 427 return 1; |
382 case STRING: | 428 case FILE_STRING: |
383 { 384 int n; 385 386 /* Null terminate and eat *trailing* return */ 387 p->s[sizeof(p->s) - 1] = '\0'; 388 n = strlen(p->s) - 1; 389 if (p->s[n] == '\n') 390 p->s[n] = '\0'; 391 return 1; 392 } | 429 { 430 int n; 431 432 /* Null terminate and eat *trailing* return */ 433 p->s[sizeof(p->s) - 1] = '\0'; 434 n = strlen(p->s) - 1; 435 if (p->s[n] == '\n') 436 p->s[n] = '\0'; 437 return 1; 438 } |
393 case PSTRING: | 439 case FILE_PSTRING: |
394 { 395 char *ptr1 = p->s, *ptr2 = ptr1 + 1; | 440 { 441 char *ptr1 = p->s, *ptr2 = ptr1 + 1; |
396 int n = *p->s; | 442 unsigned int n = *p->s; |
397 if (n >= sizeof(p->s)) 398 n = sizeof(p->s) - 1; 399 while (n--) 400 *ptr1++ = *ptr2++; 401 *ptr1 = '\0'; 402 n = strlen(p->s) - 1; 403 if (p->s[n] == '\n') 404 p->s[n] = '\0'; 405 return 1; 406 } | 443 if (n >= sizeof(p->s)) 444 n = sizeof(p->s) - 1; 445 while (n--) 446 *ptr1++ = *ptr2++; 447 *ptr1 = '\0'; 448 n = strlen(p->s) - 1; 449 if (p->s[n] == '\n') 450 p->s[n] = '\0'; 451 return 1; 452 } |
407 case BESHORT: | 453 case FILE_BESHORT: |
408 p->h = (short)((p->hs[0]<<8)|(p->hs[1])); 409 if (m->mask) 410 switch (m->mask_op&0x7F) { | 454 p->h = (short)((p->hs[0]<<8)|(p->hs[1])); 455 if (m->mask) 456 switch (m->mask_op&0x7F) { |
411 case OPAND: | 457 case FILE_OPAND: |
412 p->h &= m->mask; 413 break; | 458 p->h &= m->mask; 459 break; |
414 case OPOR: | 460 case FILE_OPOR: |
415 p->h |= m->mask; 416 break; | 461 p->h |= m->mask; 462 break; |
417 case OPXOR: | 463 case FILE_OPXOR: |
418 p->h ^= m->mask; 419 break; | 464 p->h ^= m->mask; 465 break; |
420 case OPADD: | 466 case FILE_OPADD: |
421 p->h += m->mask; 422 break; | 467 p->h += m->mask; 468 break; |
423 case OPMINUS: | 469 case FILE_OPMINUS: |
424 p->h -= m->mask; 425 break; | 470 p->h -= m->mask; 471 break; |
426 case OPMULTIPLY: | 472 case FILE_OPMULTIPLY: |
427 p->h *= m->mask; 428 break; | 473 p->h *= m->mask; 474 break; |
429 case OPDIVIDE: | 475 case FILE_OPDIVIDE: |
430 p->h /= m->mask; 431 break; | 476 p->h /= m->mask; 477 break; |
432 case OPMODULO: | 478 case FILE_OPMODULO: |
433 p->h %= m->mask; 434 break; 435 } | 479 p->h %= m->mask; 480 break; 481 } |
436 if (m->mask_op & OPINVERSE) | 482 if (m->mask_op & FILE_OPINVERSE) |
437 p->h = ~p->h; 438 return 1; | 483 p->h = ~p->h; 484 return 1; |
439 case BELONG: 440 case BEDATE: 441 case BELDATE: | 485 case FILE_BELONG: 486 case FILE_BEDATE: 487 case FILE_BELDATE: |
442 p->l = (int32_t) 443 ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3])); 444 if (m->mask) 445 switch (m->mask_op&0x7F) { | 488 p->l = (int32_t) 489 ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3])); 490 if (m->mask) 491 switch (m->mask_op&0x7F) { |
446 case OPAND: | 492 case FILE_OPAND: |
447 p->l &= m->mask; 448 break; | 493 p->l &= m->mask; 494 break; |
449 case OPOR: | 495 case FILE_OPOR: |
450 p->l |= m->mask; 451 break; | 496 p->l |= m->mask; 497 break; |
452 case OPXOR: | 498 case FILE_OPXOR: |
453 p->l ^= m->mask; 454 break; | 499 p->l ^= m->mask; 500 break; |
455 case OPADD: | 501 case FILE_OPADD: |
456 p->l += m->mask; 457 break; | 502 p->l += m->mask; 503 break; |
458 case OPMINUS: | 504 case FILE_OPMINUS: |
459 p->l -= m->mask; 460 break; | 505 p->l -= m->mask; 506 break; |
461 case OPMULTIPLY: | 507 case FILE_OPMULTIPLY: |
462 p->l *= m->mask; 463 break; | 508 p->l *= m->mask; 509 break; |
464 case OPDIVIDE: | 510 case FILE_OPDIVIDE: |
465 p->l /= m->mask; 466 break; | 511 p->l /= m->mask; 512 break; |
467 case OPMODULO: | 513 case FILE_OPMODULO: |
468 p->l %= m->mask; 469 break; 470 } | 514 p->l %= m->mask; 515 break; 516 } |
471 if (m->mask_op & OPINVERSE) | 517 if (m->mask_op & FILE_OPINVERSE) |
472 p->l = ~p->l; 473 return 1; | 518 p->l = ~p->l; 519 return 1; |
474 case LESHORT: | 520 case FILE_LESHORT: |
475 p->h = (short)((p->hs[1]<<8)|(p->hs[0])); 476 if (m->mask) 477 switch (m->mask_op&0x7F) { | 521 p->h = (short)((p->hs[1]<<8)|(p->hs[0])); 522 if (m->mask) 523 switch (m->mask_op&0x7F) { |
478 case OPAND: | 524 case FILE_OPAND: |
479 p->h &= m->mask; 480 break; | 525 p->h &= m->mask; 526 break; |
481 case OPOR: | 527 case FILE_OPOR: |
482 p->h |= m->mask; 483 break; | 528 p->h |= m->mask; 529 break; |
484 case OPXOR: | 530 case FILE_OPXOR: |
485 p->h ^= m->mask; 486 break; | 531 p->h ^= m->mask; 532 break; |
487 case OPADD: | 533 case FILE_OPADD: |
488 p->h += m->mask; 489 break; | 534 p->h += m->mask; 535 break; |
490 case OPMINUS: | 536 case FILE_OPMINUS: |
491 p->h -= m->mask; 492 break; | 537 p->h -= m->mask; 538 break; |
493 case OPMULTIPLY: | 539 case FILE_OPMULTIPLY: |
494 p->h *= m->mask; 495 break; | 540 p->h *= m->mask; 541 break; |
496 case OPDIVIDE: | 542 case FILE_OPDIVIDE: |
497 p->h /= m->mask; 498 break; | 543 p->h /= m->mask; 544 break; |
499 case OPMODULO: | 545 case FILE_OPMODULO: |
500 p->h %= m->mask; 501 break; 502 } | 546 p->h %= m->mask; 547 break; 548 } |
503 if (m->mask_op & OPINVERSE) | 549 if (m->mask_op & FILE_OPINVERSE) |
504 p->h = ~p->h; 505 return 1; | 550 p->h = ~p->h; 551 return 1; |
506 case LELONG: 507 case LEDATE: 508 case LELDATE: | 552 case FILE_LELONG: 553 case FILE_LEDATE: 554 case FILE_LELDATE: |
509 p->l = (int32_t) 510 ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0])); 511 if (m->mask) 512 switch (m->mask_op&0x7F) { | 555 p->l = (int32_t) 556 ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0])); 557 if (m->mask) 558 switch (m->mask_op&0x7F) { |
513 case OPAND: | 559 case FILE_OPAND: |
514 p->l &= m->mask; 515 break; | 560 p->l &= m->mask; 561 break; |
516 case OPOR: | 562 case FILE_OPOR: |
517 p->l |= m->mask; 518 break; | 563 p->l |= m->mask; 564 break; |
519 case OPXOR: | 565 case FILE_OPXOR: |
520 p->l ^= m->mask; 521 break; | 566 p->l ^= m->mask; 567 break; |
522 case OPADD: | 568 case FILE_OPADD: |
523 p->l += m->mask; 524 break; | 569 p->l += m->mask; 570 break; |
525 case OPMINUS: | 571 case FILE_OPMINUS: |
526 p->l -= m->mask; 527 break; | 572 p->l -= m->mask; 573 break; |
528 case OPMULTIPLY: | 574 case FILE_OPMULTIPLY: |
529 p->l *= m->mask; 530 break; | 575 p->l *= m->mask; 576 break; |
531 case OPDIVIDE: | 577 case FILE_OPDIVIDE: |
532 p->l /= m->mask; 533 break; | 578 p->l /= m->mask; 579 break; |
534 case OPMODULO: | 580 case FILE_OPMODULO: |
535 p->l %= m->mask; 536 break; 537 } | 581 p->l %= m->mask; 582 break; 583 } |
538 if (m->mask_op & OPINVERSE) | 584 if (m->mask_op & FILE_OPINVERSE) |
539 p->l = ~p->l; 540 return 1; | 585 p->l = ~p->l; 586 return 1; |
541 case REGEX: | 587 case FILE_REGEX: |
542 return 1; 543 default: | 588 return 1; 589 default: |
544 error("invalid type %d in mconvert().\n", m->type); | 590 file_error(ms, 0, "invalid type %d in mconvert()", m->type); |
545 return 0; 546 } 547} 548 549 | 591 return 0; 592 } 593} 594 595 |
550static void 551mdebug(int32_t offset, char *str, int len) | 596private void 597mdebug(uint32_t offset, const char *str, size_t len) |
552{ 553 (void) fprintf(stderr, "mget @%d: ", offset); | 598{ 599 (void) fprintf(stderr, "mget @%d: ", offset); |
554 showstr(stderr, (char *) str, len); | 600 file_showstr(stderr, str, len); |
555 (void) fputc('\n', stderr); 556 (void) fputc('\n', stderr); 557} 558 | 601 (void) fputc('\n', stderr); 602 (void) fputc('\n', stderr); 603} 604 |
559static int 560mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes) | 605private int 606mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s, 607 struct magic *m, size_t nbytes) |
561{ | 608{ |
562 int32_t offset = m->offset; | 609 uint32_t offset = m->offset; |
563 | 610 |
564 if (m->type == REGEX) { 565 /* 566 * offset is interpreted as last line to search, 567 * (starting at 1), not as bytes-from start-of-file 568 */ 569 unsigned char *last = NULL; 570 p->buf = (char *)s; 571 for (; offset && (s = (unsigned char *)strchr(s, '\n')) != NULL; 572 offset--, s++) 573 last = s; 574 if (last != NULL) 575 *last = '\0'; | 611 if (m->type == FILE_REGEX) { 612 /* 613 * offset is interpreted as last line to search, 614 * (starting at 1), not as bytes-from start-of-file 615 */ 616 unsigned char *b, *last = NULL; 617 if ((p->buf = strdup((const char *)s)) == NULL) { 618 file_oomem(ms); 619 return -1; 620 } 621 for (b = (unsigned char *)p->buf; offset && 622 (b = (unsigned char *)strchr((char *)b, '\n')) != NULL; 623 offset--, s++) 624 last = b; 625 if (last != NULL) 626 *last = '\0'; |
576 } else if (offset + sizeof(union VALUETYPE) <= nbytes) 577 memcpy(p, s + offset, sizeof(union VALUETYPE)); 578 else { 579 /* 580 * the usefulness of padding with zeroes eludes me, it 581 * might even cause problems 582 */ | 627 } else if (offset + sizeof(union VALUETYPE) <= nbytes) 628 memcpy(p, s + offset, sizeof(union VALUETYPE)); 629 else { 630 /* 631 * the usefulness of padding with zeroes eludes me, it 632 * might even cause problems 633 */ |
583 int32_t have = nbytes - offset; | |
584 memset(p, 0, sizeof(union VALUETYPE)); | 634 memset(p, 0, sizeof(union VALUETYPE)); |
585 if (have > 0) 586 memcpy(p, s + offset, have); | 635 if (offset < nbytes) 636 memcpy(p, s + offset, nbytes - offset); |
587 } 588 | 637 } 638 |
589 if (debug) { 590 mdebug(offset, (char *) p, sizeof(union VALUETYPE)); 591 mdump(m); | 639 /* Verify we have enough data to match magic type */ 640 switch (m->type) { 641 case FILE_BYTE: 642 if (nbytes < (offset + 1)) /* should alway be true */ 643 return 0; 644 break; 645 646 case FILE_SHORT: 647 case FILE_BESHORT: 648 case FILE_LESHORT: 649 if (nbytes < (offset + 2)) 650 return 0; 651 break; 652 653 case FILE_LONG: 654 case FILE_BELONG: 655 case FILE_LELONG: 656 case FILE_DATE: 657 case FILE_BEDATE: 658 case FILE_LEDATE: 659 case FILE_LDATE: 660 case FILE_BELDATE: 661 case FILE_LELDATE: 662 if (nbytes < (offset + 4)) 663 return 0; 664 break; 665 666 case FILE_STRING: 667 case FILE_PSTRING: 668 if (nbytes < (offset + m->vallen)) 669 return 0; 670 break; |
592 } 593 | 671 } 672 |
673 if ((ms->flags & MAGIC_DEBUG) != 0) { 674 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); 675 file_mdump(m); 676 } 677 |
|
594 if (m->flag & INDIR) { 595 switch (m->in_type) { | 678 if (m->flag & INDIR) { 679 switch (m->in_type) { |
596 case BYTE: 597 if (m->in_offset) | 680 case FILE_BYTE: 681 if (m->in_offset) { |
598 switch (m->in_op&0x7F) { | 682 switch (m->in_op&0x7F) { |
599 case OPAND: | 683 case FILE_OPAND: |
600 offset = p->b & m->in_offset; 601 break; | 684 offset = p->b & m->in_offset; 685 break; |
602 case OPOR: | 686 case FILE_OPOR: |
603 offset = p->b | m->in_offset; 604 break; | 687 offset = p->b | m->in_offset; 688 break; |
605 case OPXOR: | 689 case FILE_OPXOR: |
606 offset = p->b ^ m->in_offset; 607 break; | 690 offset = p->b ^ m->in_offset; 691 break; |
608 case OPADD: | 692 case FILE_OPADD: |
609 offset = p->b + m->in_offset; 610 break; | 693 offset = p->b + m->in_offset; 694 break; |
611 case OPMINUS: | 695 case FILE_OPMINUS: |
612 offset = p->b - m->in_offset; 613 break; | 696 offset = p->b - m->in_offset; 697 break; |
614 case OPMULTIPLY: | 698 case FILE_OPMULTIPLY: |
615 offset = p->b * m->in_offset; 616 break; | 699 offset = p->b * m->in_offset; 700 break; |
617 case OPDIVIDE: | 701 case FILE_OPDIVIDE: |
618 offset = p->b / m->in_offset; 619 break; | 702 offset = p->b / m->in_offset; 703 break; |
620 case OPMODULO: | 704 case FILE_OPMODULO: |
621 offset = p->b % m->in_offset; 622 break; 623 } | 705 offset = p->b % m->in_offset; 706 break; 707 } |
624 if (m->in_op & OPINVERSE) | 708 } else 709 offset = p->b; 710 if (m->in_op & FILE_OPINVERSE) |
625 offset = ~offset; 626 break; | 711 offset = ~offset; 712 break; |
627 case BESHORT: 628 if (m->in_offset) 629 switch (m->in_op&0x7F) { 630 case OPAND: | 713 case FILE_BESHORT: 714 if (m->in_offset) { 715 switch (m->in_op & 0x7F) { 716 case FILE_OPAND: |
631 offset = (short)((p->hs[0]<<8)| 632 (p->hs[1])) & 633 m->in_offset; 634 break; | 717 offset = (short)((p->hs[0]<<8)| 718 (p->hs[1])) & 719 m->in_offset; 720 break; |
635 case OPOR: | 721 case FILE_OPOR: |
636 offset = (short)((p->hs[0]<<8)| 637 (p->hs[1])) | 638 m->in_offset; 639 break; | 722 offset = (short)((p->hs[0]<<8)| 723 (p->hs[1])) | 724 m->in_offset; 725 break; |
640 case OPXOR: | 726 case FILE_OPXOR: |
641 offset = (short)((p->hs[0]<<8)| 642 (p->hs[1])) ^ 643 m->in_offset; 644 break; | 727 offset = (short)((p->hs[0]<<8)| 728 (p->hs[1])) ^ 729 m->in_offset; 730 break; |
645 case OPADD: | 731 case FILE_OPADD: |
646 offset = (short)((p->hs[0]<<8)| 647 (p->hs[1])) + 648 m->in_offset; 649 break; | 732 offset = (short)((p->hs[0]<<8)| 733 (p->hs[1])) + 734 m->in_offset; 735 break; |
650 case OPMINUS: | 736 case FILE_OPMINUS: |
651 offset = (short)((p->hs[0]<<8)| 652 (p->hs[1])) - 653 m->in_offset; 654 break; | 737 offset = (short)((p->hs[0]<<8)| 738 (p->hs[1])) - 739 m->in_offset; 740 break; |
655 case OPMULTIPLY: | 741 case FILE_OPMULTIPLY: |
656 offset = (short)((p->hs[0]<<8)| 657 (p->hs[1])) * 658 m->in_offset; 659 break; | 742 offset = (short)((p->hs[0]<<8)| 743 (p->hs[1])) * 744 m->in_offset; 745 break; |
660 case OPDIVIDE: | 746 case FILE_OPDIVIDE: |
661 offset = (short)((p->hs[0]<<8)| 662 (p->hs[1])) / 663 m->in_offset; 664 break; | 747 offset = (short)((p->hs[0]<<8)| 748 (p->hs[1])) / 749 m->in_offset; 750 break; |
665 case OPMODULO: | 751 case FILE_OPMODULO: |
666 offset = (short)((p->hs[0]<<8)| 667 (p->hs[1])) % 668 m->in_offset; 669 break; 670 } | 752 offset = (short)((p->hs[0]<<8)| 753 (p->hs[1])) % 754 m->in_offset; 755 break; 756 } |
671 if (m->in_op & OPINVERSE) | 757 } else 758 offset = (short)((p->hs[0]<<8)| 759 (p->hs[1])); 760 if (m->in_op & FILE_OPINVERSE) |
672 offset = ~offset; 673 break; | 761 offset = ~offset; 762 break; |
674 case LESHORT: 675 if (m->in_offset) 676 switch (m->in_op&0x7F) { 677 case OPAND: | 763 case FILE_LESHORT: 764 if (m->in_offset) { 765 switch (m->in_op & 0x7F) { 766 case FILE_OPAND: |
678 offset = (short)((p->hs[1]<<8)| 679 (p->hs[0])) & 680 m->in_offset; 681 break; | 767 offset = (short)((p->hs[1]<<8)| 768 (p->hs[0])) & 769 m->in_offset; 770 break; |
682 case OPOR: | 771 case FILE_OPOR: |
683 offset = (short)((p->hs[1]<<8)| 684 (p->hs[0])) | 685 m->in_offset; 686 break; | 772 offset = (short)((p->hs[1]<<8)| 773 (p->hs[0])) | 774 m->in_offset; 775 break; |
687 case OPXOR: | 776 case FILE_OPXOR: |
688 offset = (short)((p->hs[1]<<8)| 689 (p->hs[0])) ^ 690 m->in_offset; 691 break; | 777 offset = (short)((p->hs[1]<<8)| 778 (p->hs[0])) ^ 779 m->in_offset; 780 break; |
692 case OPADD: | 781 case FILE_OPADD: |
693 offset = (short)((p->hs[1]<<8)| 694 (p->hs[0])) + 695 m->in_offset; 696 break; | 782 offset = (short)((p->hs[1]<<8)| 783 (p->hs[0])) + 784 m->in_offset; 785 break; |
697 case OPMINUS: | 786 case FILE_OPMINUS: |
698 offset = (short)((p->hs[1]<<8)| 699 (p->hs[0])) - 700 m->in_offset; 701 break; | 787 offset = (short)((p->hs[1]<<8)| 788 (p->hs[0])) - 789 m->in_offset; 790 break; |
702 case OPMULTIPLY: | 791 case FILE_OPMULTIPLY: |
703 offset = (short)((p->hs[1]<<8)| 704 (p->hs[0])) * 705 m->in_offset; 706 break; | 792 offset = (short)((p->hs[1]<<8)| 793 (p->hs[0])) * 794 m->in_offset; 795 break; |
707 case OPDIVIDE: | 796 case FILE_OPDIVIDE: |
708 offset = (short)((p->hs[1]<<8)| 709 (p->hs[0])) / 710 m->in_offset; 711 break; | 797 offset = (short)((p->hs[1]<<8)| 798 (p->hs[0])) / 799 m->in_offset; 800 break; |
712 case OPMODULO: | 801 case FILE_OPMODULO: |
713 offset = (short)((p->hs[1]<<8)| 714 (p->hs[0])) % 715 m->in_offset; 716 break; 717 } | 802 offset = (short)((p->hs[1]<<8)| 803 (p->hs[0])) % 804 m->in_offset; 805 break; 806 } |
718 if (m->in_op & OPINVERSE) | 807 } else 808 offset = (short)((p->hs[1]<<8)| 809 (p->hs[0])); 810 if (m->in_op & FILE_OPINVERSE) |
719 offset = ~offset; 720 break; | 811 offset = ~offset; 812 break; |
721 case SHORT: 722 if (m->in_offset) 723 switch (m->in_op&0x7F) { 724 case OPAND: | 813 case FILE_SHORT: 814 if (m->in_offset) { 815 switch (m->in_op & 0x7F) { 816 case FILE_OPAND: |
725 offset = p->h & m->in_offset; 726 break; | 817 offset = p->h & m->in_offset; 818 break; |
727 case OPOR: | 819 case FILE_OPOR: |
728 offset = p->h | m->in_offset; 729 break; | 820 offset = p->h | m->in_offset; 821 break; |
730 case OPXOR: | 822 case FILE_OPXOR: |
731 offset = p->h ^ m->in_offset; 732 break; | 823 offset = p->h ^ m->in_offset; 824 break; |
733 case OPADD: | 825 case FILE_OPADD: |
734 offset = p->h + m->in_offset; 735 break; | 826 offset = p->h + m->in_offset; 827 break; |
736 case OPMINUS: | 828 case FILE_OPMINUS: |
737 offset = p->h - m->in_offset; 738 break; | 829 offset = p->h - m->in_offset; 830 break; |
739 case OPMULTIPLY: | 831 case FILE_OPMULTIPLY: |
740 offset = p->h * m->in_offset; 741 break; | 832 offset = p->h * m->in_offset; 833 break; |
742 case OPDIVIDE: | 834 case FILE_OPDIVIDE: |
743 offset = p->h / m->in_offset; 744 break; | 835 offset = p->h / m->in_offset; 836 break; |
745 case OPMODULO: | 837 case FILE_OPMODULO: |
746 offset = p->h % m->in_offset; 747 break; 748 } | 838 offset = p->h % m->in_offset; 839 break; 840 } |
749 if (m->in_op & OPINVERSE) | 841 } 842 else 843 offset = p->h; 844 if (m->in_op & FILE_OPINVERSE) |
750 offset = ~offset; 751 break; | 845 offset = ~offset; 846 break; |
752 case BELONG: 753 if (m->in_offset) 754 switch (m->in_op&0x7F) { 755 case OPAND: | 847 case FILE_BELONG: 848 if (m->in_offset) { 849 switch (m->in_op & 0x7F) { 850 case FILE_OPAND: |
756 offset = (int32_t)((p->hl[0]<<24)| 757 (p->hl[1]<<16)| 758 (p->hl[2]<<8)| 759 (p->hl[3])) & 760 m->in_offset; 761 break; | 851 offset = (int32_t)((p->hl[0]<<24)| 852 (p->hl[1]<<16)| 853 (p->hl[2]<<8)| 854 (p->hl[3])) & 855 m->in_offset; 856 break; |
762 case OPOR: | 857 case FILE_OPOR: |
763 offset = (int32_t)((p->hl[0]<<24)| 764 (p->hl[1]<<16)| 765 (p->hl[2]<<8)| 766 (p->hl[3])) | 767 m->in_offset; 768 break; | 858 offset = (int32_t)((p->hl[0]<<24)| 859 (p->hl[1]<<16)| 860 (p->hl[2]<<8)| 861 (p->hl[3])) | 862 m->in_offset; 863 break; |
769 case OPXOR: | 864 case FILE_OPXOR: |
770 offset = (int32_t)((p->hl[0]<<24)| 771 (p->hl[1]<<16)| 772 (p->hl[2]<<8)| 773 (p->hl[3])) ^ 774 m->in_offset; 775 break; | 865 offset = (int32_t)((p->hl[0]<<24)| 866 (p->hl[1]<<16)| 867 (p->hl[2]<<8)| 868 (p->hl[3])) ^ 869 m->in_offset; 870 break; |
776 case OPADD: | 871 case FILE_OPADD: |
777 offset = (int32_t)((p->hl[0]<<24)| 778 (p->hl[1]<<16)| 779 (p->hl[2]<<8)| 780 (p->hl[3])) + 781 m->in_offset; 782 break; | 872 offset = (int32_t)((p->hl[0]<<24)| 873 (p->hl[1]<<16)| 874 (p->hl[2]<<8)| 875 (p->hl[3])) + 876 m->in_offset; 877 break; |
783 case OPMINUS: | 878 case FILE_OPMINUS: |
784 offset = (int32_t)((p->hl[0]<<24)| 785 (p->hl[1]<<16)| 786 (p->hl[2]<<8)| 787 (p->hl[3])) - 788 m->in_offset; 789 break; | 879 offset = (int32_t)((p->hl[0]<<24)| 880 (p->hl[1]<<16)| 881 (p->hl[2]<<8)| 882 (p->hl[3])) - 883 m->in_offset; 884 break; |
790 case OPMULTIPLY: | 885 case FILE_OPMULTIPLY: |
791 offset = (int32_t)((p->hl[0]<<24)| 792 (p->hl[1]<<16)| 793 (p->hl[2]<<8)| 794 (p->hl[3])) * 795 m->in_offset; 796 break; | 886 offset = (int32_t)((p->hl[0]<<24)| 887 (p->hl[1]<<16)| 888 (p->hl[2]<<8)| 889 (p->hl[3])) * 890 m->in_offset; 891 break; |
797 case OPDIVIDE: | 892 case FILE_OPDIVIDE: |
798 offset = (int32_t)((p->hl[0]<<24)| 799 (p->hl[1]<<16)| 800 (p->hl[2]<<8)| 801 (p->hl[3])) / 802 m->in_offset; 803 break; | 893 offset = (int32_t)((p->hl[0]<<24)| 894 (p->hl[1]<<16)| 895 (p->hl[2]<<8)| 896 (p->hl[3])) / 897 m->in_offset; 898 break; |
804 case OPMODULO: | 899 case FILE_OPMODULO: |
805 offset = (int32_t)((p->hl[0]<<24)| 806 (p->hl[1]<<16)| 807 (p->hl[2]<<8)| 808 (p->hl[3])) % 809 m->in_offset; 810 break; 811 } | 900 offset = (int32_t)((p->hl[0]<<24)| 901 (p->hl[1]<<16)| 902 (p->hl[2]<<8)| 903 (p->hl[3])) % 904 m->in_offset; 905 break; 906 } |
812 if (m->in_op & OPINVERSE) | 907 } else 908 offset = (int32_t)((p->hl[0]<<24)| 909 (p->hl[1]<<16)| 910 (p->hl[2]<<8)| 911 (p->hl[3])); 912 if (m->in_op & FILE_OPINVERSE) |
813 offset = ~offset; 814 break; | 913 offset = ~offset; 914 break; |
815 case LELONG: 816 if (m->in_offset) 817 switch (m->in_op&0x7F) { 818 case OPAND: | 915 case FILE_LELONG: 916 if (m->in_offset) { 917 switch (m->in_op & 0x7F) { 918 case FILE_OPAND: |
819 offset = (int32_t)((p->hl[3]<<24)| 820 (p->hl[2]<<16)| 821 (p->hl[1]<<8)| 822 (p->hl[0])) & 823 m->in_offset; 824 break; | 919 offset = (int32_t)((p->hl[3]<<24)| 920 (p->hl[2]<<16)| 921 (p->hl[1]<<8)| 922 (p->hl[0])) & 923 m->in_offset; 924 break; |
825 case OPOR: | 925 case FILE_OPOR: |
826 offset = (int32_t)((p->hl[3]<<24)| 827 (p->hl[2]<<16)| 828 (p->hl[1]<<8)| 829 (p->hl[0])) | 830 m->in_offset; 831 break; | 926 offset = (int32_t)((p->hl[3]<<24)| 927 (p->hl[2]<<16)| 928 (p->hl[1]<<8)| 929 (p->hl[0])) | 930 m->in_offset; 931 break; |
832 case OPXOR: | 932 case FILE_OPXOR: |
833 offset = (int32_t)((p->hl[3]<<24)| 834 (p->hl[2]<<16)| 835 (p->hl[1]<<8)| 836 (p->hl[0])) ^ 837 m->in_offset; 838 break; | 933 offset = (int32_t)((p->hl[3]<<24)| 934 (p->hl[2]<<16)| 935 (p->hl[1]<<8)| 936 (p->hl[0])) ^ 937 m->in_offset; 938 break; |
839 case OPADD: | 939 case FILE_OPADD: |
840 offset = (int32_t)((p->hl[3]<<24)| 841 (p->hl[2]<<16)| 842 (p->hl[1]<<8)| 843 (p->hl[0])) + 844 m->in_offset; 845 break; | 940 offset = (int32_t)((p->hl[3]<<24)| 941 (p->hl[2]<<16)| 942 (p->hl[1]<<8)| 943 (p->hl[0])) + 944 m->in_offset; 945 break; |
846 case OPMINUS: | 946 case FILE_OPMINUS: |
847 offset = (int32_t)((p->hl[3]<<24)| 848 (p->hl[2]<<16)| 849 (p->hl[1]<<8)| 850 (p->hl[0])) - 851 m->in_offset; 852 break; | 947 offset = (int32_t)((p->hl[3]<<24)| 948 (p->hl[2]<<16)| 949 (p->hl[1]<<8)| 950 (p->hl[0])) - 951 m->in_offset; 952 break; |
853 case OPMULTIPLY: | 953 case FILE_OPMULTIPLY: |
854 offset = (int32_t)((p->hl[3]<<24)| 855 (p->hl[2]<<16)| 856 (p->hl[1]<<8)| 857 (p->hl[0])) * 858 m->in_offset; 859 break; | 954 offset = (int32_t)((p->hl[3]<<24)| 955 (p->hl[2]<<16)| 956 (p->hl[1]<<8)| 957 (p->hl[0])) * 958 m->in_offset; 959 break; |
860 case OPDIVIDE: | 960 case FILE_OPDIVIDE: |
861 offset = (int32_t)((p->hl[3]<<24)| 862 (p->hl[2]<<16)| 863 (p->hl[1]<<8)| 864 (p->hl[0])) / 865 m->in_offset; 866 break; | 961 offset = (int32_t)((p->hl[3]<<24)| 962 (p->hl[2]<<16)| 963 (p->hl[1]<<8)| 964 (p->hl[0])) / 965 m->in_offset; 966 break; |
867 case OPMODULO: | 967 case FILE_OPMODULO: |
868 offset = (int32_t)((p->hl[3]<<24)| 869 (p->hl[2]<<16)| 870 (p->hl[1]<<8)| 871 (p->hl[0])) % 872 m->in_offset; 873 break; 874 } | 968 offset = (int32_t)((p->hl[3]<<24)| 969 (p->hl[2]<<16)| 970 (p->hl[1]<<8)| 971 (p->hl[0])) % 972 m->in_offset; 973 break; 974 } |
875 if (m->in_op & OPINVERSE) | 975 } else 976 offset = (int32_t)((p->hl[3]<<24)| 977 (p->hl[2]<<16)| 978 (p->hl[1]<<8)| 979 (p->hl[0])); 980 if (m->in_op & FILE_OPINVERSE) |
876 offset = ~offset; 877 break; | 981 offset = ~offset; 982 break; |
878 case LONG: 879 if (m->in_offset) 880 switch (m->in_op&0x7F) { 881 case OPAND: | 983 case FILE_LONG: 984 if (m->in_offset) { 985 switch (m->in_op & 0x7F) { 986 case FILE_OPAND: |
882 offset = p->l & m->in_offset; 883 break; | 987 offset = p->l & m->in_offset; 988 break; |
884 case OPOR: | 989 case FILE_OPOR: |
885 offset = p->l | m->in_offset; 886 break; | 990 offset = p->l | m->in_offset; 991 break; |
887 case OPXOR: | 992 case FILE_OPXOR: |
888 offset = p->l ^ m->in_offset; 889 break; | 993 offset = p->l ^ m->in_offset; 994 break; |
890 case OPADD: | 995 case FILE_OPADD: |
891 offset = p->l + m->in_offset; 892 break; | 996 offset = p->l + m->in_offset; 997 break; |
893 case OPMINUS: | 998 case FILE_OPMINUS: |
894 offset = p->l - m->in_offset; 895 break; | 999 offset = p->l - m->in_offset; 1000 break; |
896 case OPMULTIPLY: | 1001 case FILE_OPMULTIPLY: |
897 offset = p->l * m->in_offset; 898 break; | 1002 offset = p->l * m->in_offset; 1003 break; |
899 case OPDIVIDE: | 1004 case FILE_OPDIVIDE: |
900 offset = p->l / m->in_offset; 901 break; | 1005 offset = p->l / m->in_offset; 1006 break; |
902 case OPMODULO: | 1007 case FILE_OPMODULO: |
903 offset = p->l % m->in_offset; 904 break; 905 /* case TOOMANYSWITCHBLOCKS: 906 * ugh = p->eye % m->strain; 907 * rub; 908 * case BEER: 909 * off = p->tab & m->in_gest; 910 * sleep; 911 */ 912 } | 1008 offset = p->l % m->in_offset; 1009 break; 1010 /* case TOOMANYSWITCHBLOCKS: 1011 * ugh = p->eye % m->strain; 1012 * rub; 1013 * case BEER: 1014 * off = p->tab & m->in_gest; 1015 * sleep; 1016 */ 1017 } |
913 if (m->in_op & OPINVERSE) | 1018 } else 1019 offset = p->l; 1020 if (m->in_op & FILE_OPINVERSE) |
914 offset = ~offset; 915 break; 916 } 917 | 1021 offset = ~offset; 1022 break; 1023 } 1024 |
918 if (offset + sizeof(union VALUETYPE) > nbytes) | 1025 if (nbytes < sizeof(union VALUETYPE) || 1026 nbytes - sizeof(union VALUETYPE) < offset) |
919 return 0; 920 921 memcpy(p, s + offset, sizeof(union VALUETYPE)); 922 | 1027 return 0; 1028 1029 memcpy(p, s + offset, sizeof(union VALUETYPE)); 1030 |
923 if (debug) { 924 mdebug(offset, (char *) p, sizeof(union VALUETYPE)); 925 mdump(m); | 1031 if ((ms->flags & MAGIC_DEBUG) != 0) { 1032 mdebug(offset, (char *)(void *)p, 1033 sizeof(union VALUETYPE)); 1034 file_mdump(m); |
926 } 927 } | 1035 } 1036 } |
928 if (!mconvert(p, m)) | 1037 if (!mconvert(ms, p, m)) |
929 return 0; 930 return 1; 931} 932 | 1038 return 0; 1039 return 1; 1040} 1041 |
933static int 934mcheck(union VALUETYPE *p, struct magic *m) | 1042private int 1043mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m) |
935{ 936 uint32_t l = m->value.l; 937 uint32_t v; 938 int matched; 939 940 if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) { | 1044{ 1045 uint32_t l = m->value.l; 1046 uint32_t v; 1047 int matched; 1048 1049 if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) { |
941 fprintf(stderr, "BOINK"); | |
942 return 1; 943 } 944 945 946 switch (m->type) { | 1050 return 1; 1051 } 1052 1053 1054 switch (m->type) { |
947 case BYTE: | 1055 case FILE_BYTE: |
948 v = p->b; 949 break; 950 | 1056 v = p->b; 1057 break; 1058 |
951 case SHORT: 952 case BESHORT: 953 case LESHORT: | 1059 case FILE_SHORT: 1060 case FILE_BESHORT: 1061 case FILE_LESHORT: |
954 v = p->h; 955 break; 956 | 1062 v = p->h; 1063 break; 1064 |
957 case LONG: 958 case BELONG: 959 case LELONG: 960 case DATE: 961 case BEDATE: 962 case LEDATE: 963 case LDATE: 964 case BELDATE: 965 case LELDATE: | 1065 case FILE_LONG: 1066 case FILE_BELONG: 1067 case FILE_LELONG: 1068 case FILE_DATE: 1069 case FILE_BEDATE: 1070 case FILE_LEDATE: 1071 case FILE_LDATE: 1072 case FILE_BELDATE: 1073 case FILE_LELDATE: |
966 v = p->l; 967 break; 968 | 1074 v = p->l; 1075 break; 1076 |
969 case STRING: 970 case PSTRING: | 1077 case FILE_STRING: 1078 case FILE_PSTRING: |
971 { 972 /* 973 * What we want here is: 974 * v = strncmp(m->value.s, p->s, m->vallen); 975 * but ignoring any nulls. bcmp doesn't give -/+/0 976 * and isn't universally available anyway. 977 */ 978 unsigned char *a = (unsigned char*)m->value.s; --- 29 unchanged lines hidden (view full) --- 1008 } else { 1009 if ((v = *b++ - *a++) != '\0') 1010 break; 1011 } 1012 } 1013 } 1014 break; 1015 } | 1079 { 1080 /* 1081 * What we want here is: 1082 * v = strncmp(m->value.s, p->s, m->vallen); 1083 * but ignoring any nulls. bcmp doesn't give -/+/0 1084 * and isn't universally available anyway. 1085 */ 1086 unsigned char *a = (unsigned char*)m->value.s; --- 29 unchanged lines hidden (view full) --- 1116 } else { 1117 if ((v = *b++ - *a++) != '\0') 1118 break; 1119 } 1120 } 1121 } 1122 break; 1123 } |
1016 case REGEX: | 1124 case FILE_REGEX: |
1017 { 1018 int rc; 1019 regex_t rx; 1020 char errmsg[512]; 1021 1022 rc = regcomp(&rx, m->value.s, REG_EXTENDED|REG_NOSUB); 1023 if (rc) { | 1125 { 1126 int rc; 1127 regex_t rx; 1128 char errmsg[512]; 1129 1130 rc = regcomp(&rx, m->value.s, REG_EXTENDED|REG_NOSUB); 1131 if (rc) { |
1132 free(p->buf); |
|
1024 regerror(rc, &rx, errmsg, sizeof(errmsg)); | 1133 regerror(rc, &rx, errmsg, sizeof(errmsg)); |
1025 error("regex error %d, (%s)\n", rc, errmsg); | 1134 file_error(ms, 0, "regex error %d, (%s)", rc, errmsg); 1135 return -1; |
1026 } else { 1027 rc = regexec(&rx, p->buf, 0, 0, 0); | 1136 } else { 1137 rc = regexec(&rx, p->buf, 0, 0, 0); |
1138 regfree(&rx); 1139 free(p->buf); |
|
1028 return !rc; 1029 } 1030 } 1031 default: | 1140 return !rc; 1141 } 1142 } 1143 default: |
1032 error("invalid type %d in mcheck().\n", m->type); 1033 return 0;/*NOTREACHED*/ | 1144 file_error(ms, 0, "invalid type %d in mcheck()", m->type); 1145 return -1; |
1034 } 1035 | 1146 } 1147 |
1036 if(m->type != STRING && m->type != PSTRING) 1037 v = signextend(m, v); | 1148 if (m->type != FILE_STRING && m->type != FILE_PSTRING) 1149 v = file_signextend(ms, m, v); |
1038 1039 switch (m->reln) { 1040 case 'x': | 1150 1151 switch (m->reln) { 1152 case 'x': |
1041 if (debug) | 1153 if ((ms->flags & MAGIC_DEBUG) != 0) |
1042 (void) fprintf(stderr, "%u == *any* = 1\n", v); 1043 matched = 1; 1044 break; 1045 1046 case '!': 1047 matched = v != l; | 1154 (void) fprintf(stderr, "%u == *any* = 1\n", v); 1155 matched = 1; 1156 break; 1157 1158 case '!': 1159 matched = v != l; |
1048 if (debug) | 1160 if ((ms->flags & MAGIC_DEBUG) != 0) |
1049 (void) fprintf(stderr, "%u != %u = %d\n", 1050 v, l, matched); 1051 break; 1052 1053 case '=': 1054 matched = v == l; | 1161 (void) fprintf(stderr, "%u != %u = %d\n", 1162 v, l, matched); 1163 break; 1164 1165 case '=': 1166 matched = v == l; |
1055 if (debug) | 1167 if ((ms->flags & MAGIC_DEBUG) != 0) |
1056 (void) fprintf(stderr, "%u == %u = %d\n", 1057 v, l, matched); 1058 break; 1059 1060 case '>': 1061 if (m->flag & UNSIGNED) { 1062 matched = v > l; | 1168 (void) fprintf(stderr, "%u == %u = %d\n", 1169 v, l, matched); 1170 break; 1171 1172 case '>': 1173 if (m->flag & UNSIGNED) { 1174 matched = v > l; |
1063 if (debug) | 1175 if ((ms->flags & MAGIC_DEBUG) != 0) |
1064 (void) fprintf(stderr, "%u > %u = %d\n", 1065 v, l, matched); 1066 } 1067 else { 1068 matched = (int32_t) v > (int32_t) l; | 1176 (void) fprintf(stderr, "%u > %u = %d\n", 1177 v, l, matched); 1178 } 1179 else { 1180 matched = (int32_t) v > (int32_t) l; |
1069 if (debug) | 1181 if ((ms->flags & MAGIC_DEBUG) != 0) |
1070 (void) fprintf(stderr, "%d > %d = %d\n", 1071 v, l, matched); 1072 } 1073 break; 1074 1075 case '<': 1076 if (m->flag & UNSIGNED) { 1077 matched = v < l; | 1182 (void) fprintf(stderr, "%d > %d = %d\n", 1183 v, l, matched); 1184 } 1185 break; 1186 1187 case '<': 1188 if (m->flag & UNSIGNED) { 1189 matched = v < l; |
1078 if (debug) | 1190 if ((ms->flags & MAGIC_DEBUG) != 0) |
1079 (void) fprintf(stderr, "%u < %u = %d\n", 1080 v, l, matched); 1081 } 1082 else { 1083 matched = (int32_t) v < (int32_t) l; | 1191 (void) fprintf(stderr, "%u < %u = %d\n", 1192 v, l, matched); 1193 } 1194 else { 1195 matched = (int32_t) v < (int32_t) l; |
1084 if (debug) | 1196 if ((ms->flags & MAGIC_DEBUG) != 0) |
1085 (void) fprintf(stderr, "%d < %d = %d\n", 1086 v, l, matched); 1087 } 1088 break; 1089 1090 case '&': 1091 matched = (v & l) == l; | 1197 (void) fprintf(stderr, "%d < %d = %d\n", 1198 v, l, matched); 1199 } 1200 break; 1201 1202 case '&': 1203 matched = (v & l) == l; |
1092 if (debug) | 1204 if ((ms->flags & MAGIC_DEBUG) != 0) |
1093 (void) fprintf(stderr, "((%x & %x) == %x) = %d\n", 1094 v, l, l, matched); 1095 break; 1096 1097 case '^': 1098 matched = (v & l) != l; | 1205 (void) fprintf(stderr, "((%x & %x) == %x) = %d\n", 1206 v, l, l, matched); 1207 break; 1208 1209 case '^': 1210 matched = (v & l) != l; |
1099 if (debug) | 1211 if ((ms->flags & MAGIC_DEBUG) != 0) |
1100 (void) fprintf(stderr, "((%x & %x) != %x) = %d\n", 1101 v, l, l, matched); 1102 break; 1103 1104 default: 1105 matched = 0; | 1212 (void) fprintf(stderr, "((%x & %x) != %x) = %d\n", 1213 v, l, l, matched); 1214 break; 1215 1216 default: 1217 matched = 0; |
1106 error("mcheck: can't happen: invalid relation %d.\n", m->reln); 1107 break;/*NOTREACHED*/ | 1218 file_error(ms, 0, "cannot happen: invalid relation `%c'", 1219 m->reln); 1220 return -1; |
1108 } 1109 1110 return matched; 1111} | 1221 } 1222 1223 return matched; 1224} |