=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/file/Attic/softmagic.c,v retrieving revision 1.13 retrieving revision 1.14 diff -c -r1.13 -r1.14 *** src/usr.bin/file/Attic/softmagic.c 2008/05/08 01:40:56 1.13 --- src/usr.bin/file/Attic/softmagic.c 2009/04/24 18:54:34 1.14 *************** *** 1,4 **** ! /* $OpenBSD: softmagic.c,v 1.13 2008/05/08 01:40:56 chl Exp $ */ /* * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; --- 1,4 ---- ! /* $OpenBSD: softmagic.c,v 1.14 2009/04/24 18:54:34 chl Exp $ */ /* * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; *************** *** 39,49 **** #ifndef lint ! FILE_RCSID("@(#)$Id: softmagic.c,v 1.13 2008/05/08 01:40:56 chl Exp $") #endif /* lint */ private int match(struct magic_set *, struct magic *, uint32_t, ! const unsigned char *, size_t); private int mget(struct magic_set *, const unsigned char *, struct magic *, size_t, unsigned int); private int magiccheck(struct magic_set *, struct magic *); --- 39,49 ---- #ifndef lint ! FILE_RCSID("@(#)$Id: softmagic.c,v 1.14 2009/04/24 18:54:34 chl Exp $") #endif /* lint */ private int match(struct magic_set *, struct magic *, uint32_t, ! const unsigned char *, size_t, int); private int mget(struct magic_set *, const unsigned char *, struct magic *, size_t, unsigned int); private int magiccheck(struct magic_set *, struct magic *); *************** *** 59,75 **** private void cvt_64(union VALUETYPE *, const struct magic *); /* * softmagic - lookup one file in parsed, in-memory copy of database * Passed the name and FILE * of one file to be typed. */ /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ protected int ! file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes) { struct mlist *ml; int rv; for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next) ! if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes)) != 0) return rv; return 0; --- 59,81 ---- private void cvt_64(union VALUETYPE *, const struct magic *); /* + * Macro to give description string according to whether we want plain + * text or MIME type + */ + #define MAGIC_DESC ((ms->flags & MAGIC_MIME) ? m->mimetype : m->desc) + + /* * softmagic - lookup one file in parsed, in-memory copy of database * Passed the name and FILE * of one file to be typed. */ /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ protected int ! file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, int mode) { struct mlist *ml; int rv; for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next) ! if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode)) != 0) return rv; return 0; *************** *** 104,110 **** */ private int match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, ! const unsigned char *s, size_t nbytes) { uint32_t magindex = 0; unsigned int cont_level = 0; --- 110,116 ---- */ private int match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, ! const unsigned char *s, size_t nbytes, int mode) { uint32_t magindex = 0; unsigned int cont_level = 0; *************** *** 118,134 **** for (magindex = 0; magindex < nmagic; magindex++) { int flush; ! ms->offset = magic[magindex].offset; ! ms->line = magic[magindex].lineno; /* if main entry matches, print it... */ ! flush = !mget(ms, s, &magic[magindex], nbytes, cont_level); if (flush) { ! if (magic[magindex].reln == '!') flush = 0; } else { ! switch (magiccheck(ms, &magic[magindex])) { case -1: return -1; case 0: --- 124,149 ---- for (magindex = 0; magindex < nmagic; magindex++) { int flush; + struct magic *m = &magic[magindex]; ! if ((m->flag & BINTEST) != mode) { ! /* Skip sub-tests */ ! while (magic[magindex + 1].cont_level != 0 && ! ++magindex < nmagic) ! continue; ! continue; /* Skip to next top-level test*/ ! } + ms->offset = m->offset; + ms->line = m->lineno; + /* if main entry matches, print it... */ ! flush = !mget(ms, s, m, nbytes, cont_level); if (flush) { ! if (m->reln == '!') flush = 0; } else { ! switch (magiccheck(ms, m)) { case -1: return -1; case 0: *************** *** 153,167 **** * If we are going to print something, we'll need to print * a blank before we print something else. */ ! if (magic[magindex].desc[0]) { need_separator = 1; printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; } ! if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) ! == -1) return -1; /* and any continuations that match */ --- 168,181 ---- * If we are going to print something, we'll need to print * a blank before we print something else. */ ! if (*MAGIC_DESC) { need_separator = 1; printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; } ! if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1) return -1; /* and any continuations that match */ *************** *** 170,205 **** while (magic[magindex+1].cont_level != 0 && ++magindex < nmagic) { ! ms->line = magic[magindex].lineno; /* for messages */ ! if (cont_level < magic[magindex].cont_level) continue; ! if (cont_level > magic[magindex].cont_level) { /* * We're at the end of the level * "cont_level" continuations. */ ! cont_level = magic[magindex].cont_level; } ! ms->offset = magic[magindex].offset; ! if (magic[magindex].flag & OFFADD) { ms->offset += ms->c.li[cont_level - 1].off; } #ifdef ENABLE_CONDITIONALS ! if (magic[magindex].cond == COND_ELSE || ! magic[magindex].cond == COND_ELIF) { if (ms->c.li[cont_level].last_match == 1) continue; } #endif ! flush = !mget(ms, s, &magic[magindex], nbytes, ! cont_level); ! if (flush && magic[magindex].reln != '!') continue; ! switch (flush ? 1 : magiccheck(ms, &magic[magindex])) { case -1: return -1; case 0: --- 184,219 ---- while (magic[magindex+1].cont_level != 0 && ++magindex < nmagic) { ! m = &magic[magindex]; ! ms->line = m->lineno; /* for messages */ ! if (cont_level < m->cont_level) continue; ! if (cont_level > m->cont_level) { /* * We're at the end of the level * "cont_level" continuations. */ ! cont_level = m->cont_level; } ! ms->offset = m->offset; ! if (m->flag & OFFADD) { ms->offset += ms->c.li[cont_level - 1].off; } #ifdef ENABLE_CONDITIONALS ! if (m->cond == COND_ELSE || ! m->cond == COND_ELIF) { if (ms->c.li[cont_level].last_match == 1) continue; } #endif ! flush = !mget(ms, s, m, nbytes, cont_level); ! if (flush && m->reln != '!') continue; ! switch (flush ? 1 : magiccheck(ms, m)) { case -1: return -1; case 0: *************** *** 211,217 **** #ifdef ENABLE_CONDITIONALS ms->c.li[cont_level].last_match = 1; #endif ! if (magic[magindex].type != FILE_DEFAULT) ms->c.li[cont_level].got_match = 1; else if (ms->c.li[cont_level].got_match) { ms->c.li[cont_level].got_match = 0; --- 225,231 ---- #ifdef ENABLE_CONDITIONALS ms->c.li[cont_level].last_match = 1; #endif ! if (m->type != FILE_DEFAULT) ms->c.li[cont_level].got_match = 1; else if (ms->c.li[cont_level].got_match) { ms->c.li[cont_level].got_match = 0; *************** *** 221,227 **** * If we are going to print something, * make sure that we have a separator first. */ ! if (magic[magindex].desc[0]) { printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; --- 235,241 ---- * If we are going to print something, * make sure that we have a separator first. */ ! if (*MAGIC_DESC) { printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; *************** *** 234,248 **** */ /* space if previous printed */ if (need_separator ! && (magic[magindex].nospflag == 0) ! && (magic[magindex].desc[0] != '\0')) { if (file_printf(ms, " ") == -1) return -1; need_separator = 0; } ! if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) == -1) return -1; ! if (magic[magindex].desc[0]) need_separator = 1; /* --- 248,262 ---- */ /* space if previous printed */ if (need_separator ! && ((m->flag & NOSPACE) == 0) ! && *MAGIC_DESC) { if (file_printf(ms, " ") == -1) return -1; need_separator = 0; } ! if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1) return -1; ! if (*MAGIC_DESC) need_separator = 1; /* *************** *** 255,263 **** break; } } ! firstline = 0; ! if (printed_something) returnval = 1; if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) { return 1; /* don't keep searching */ } --- 269,278 ---- break; } } ! if (printed_something) { ! firstline = 0; returnval = 1; + } if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) { return 1; /* don't keep searching */ } *************** *** 271,277 **** regex_t rx; int rc; ! if (strchr(m->desc, '%') == NULL) return 0; rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB); --- 286,292 ---- regex_t rx; int rc; ! if (strchr(MAGIC_DESC, '%') == NULL) return 0; rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB); *************** *** 281,287 **** file_magerror(ms, "regex error %d, (%s)", rc, errmsg); return -1; } else { ! rc = regexec(&rx, m->desc, 0, 0, 0); regfree(&rx); return !rc; } --- 296,302 ---- file_magerror(ms, "regex error %d, (%s)", rc, errmsg); return -1; } else { ! rc = regexec(&rx, MAGIC_DESC, 0, 0, 0); regfree(&rx); return !rc; } *************** *** 311,318 **** mprint(struct magic_set *ms, struct magic *m) { uint64_t v; int64_t t = 0; ! char buf[512]; union VALUETYPE *p = &ms->ms_value; switch (m->type) { --- 326,335 ---- mprint(struct magic_set *ms, struct magic *m) { uint64_t v; + float vf; + double vd; int64_t t = 0; ! char *buf; union VALUETYPE *p = &ms->ms_value; switch (m->type) { *************** *** 322,335 **** case -1: return -1; case 1: ! if (snprintf(buf, sizeof(buf), "%c", ! (unsigned char)v) < 0) return -1; ! if (file_printf(ms, m->desc, buf) == -1) return -1; break; default: ! if (file_printf(ms, m->desc, (unsigned char) v) == -1) return -1; break; } --- 339,351 ---- case -1: return -1; case 1: ! if (asprintf(&buf, "%c", (unsigned char)v) < 0) return -1; ! if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: ! if (file_printf(ms, MAGIC_DESC, (unsigned char) v) == -1) return -1; break; } *************** *** 344,357 **** case -1: return -1; case 1: ! if (snprintf(buf, sizeof(buf), "%hu", ! (unsigned short)v) < 0) return -1; ! if (file_printf(ms, m->desc, buf) == -1) return -1; break; default: ! if (file_printf(ms, m->desc, (unsigned short) v) == -1) return -1; break; } --- 360,372 ---- case -1: return -1; case 1: ! if (asprintf(&buf, "%hu", (unsigned short)v) < 0) return -1; ! if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: ! if (file_printf(ms, MAGIC_DESC, (unsigned short) v) == -1) return -1; break; } *************** *** 367,379 **** case -1: return -1; case 1: ! if (snprintf(buf, sizeof(buf), "%u", (uint32_t)v) < 0) return -1; ! if (file_printf(ms, m->desc, buf) == -1) return -1; break; default: ! if (file_printf(ms, m->desc, (uint32_t) v) == -1) return -1; break; } --- 382,394 ---- case -1: return -1; case 1: ! if (asprintf(&buf, "%u", (uint32_t)v) < 0) return -1; ! if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: ! if (file_printf(ms, MAGIC_DESC, (uint32_t) v) == -1) return -1; break; } *************** *** 384,390 **** case FILE_BEQUAD: case FILE_LEQUAD: v = file_signextend(ms, m, p->q); ! if (file_printf(ms, m->desc, (uint64_t) v) == -1) return -1; t = ms->offset + sizeof(int64_t); break; --- 399,405 ---- case FILE_BEQUAD: case FILE_LEQUAD: v = file_signextend(ms, m, p->q); ! if (file_printf(ms, MAGIC_DESC, (uint64_t) v) == -1) return -1; t = ms->offset + sizeof(int64_t); break; *************** *** 394,409 **** case FILE_BESTRING16: case FILE_LESTRING16: if (m->reln == '=' || m->reln == '!') { ! if (file_printf(ms, m->desc, m->value.s) == -1) return -1; t = ms->offset + m->vallen; } else { if (*m->value.s == '\0') p->s[strcspn(p->s, "\n")] = '\0'; ! if (file_printf(ms, m->desc, p->s) == -1) return -1; t = ms->offset + strlen(p->s); } break; --- 409,426 ---- case FILE_BESTRING16: case FILE_LESTRING16: if (m->reln == '=' || m->reln == '!') { ! if (file_printf(ms, MAGIC_DESC, m->value.s) == -1) return -1; t = ms->offset + m->vallen; } else { if (*m->value.s == '\0') p->s[strcspn(p->s, "\n")] = '\0'; ! if (file_printf(ms, MAGIC_DESC, p->s) == -1) return -1; t = ms->offset + strlen(p->s); + if (m->type == FILE_PSTRING) + t++; } break; *************** *** 411,417 **** case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: ! if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1) return -1; t = ms->offset + sizeof(time_t); break; --- 428,434 ---- case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: ! if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 1)) == -1) return -1; t = ms->offset + sizeof(time_t); break; *************** *** 420,426 **** case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: ! if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1) return -1; t = ms->offset + sizeof(time_t); break; --- 437,443 ---- case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: ! if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 0)) == -1) return -1; t = ms->offset + sizeof(time_t); break; *************** *** 428,434 **** case FILE_QDATE: case FILE_BEQDATE: case FILE_LEQDATE: ! if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 1)) == -1) return -1; t = ms->offset + sizeof(uint64_t); --- 445,451 ---- case FILE_QDATE: case FILE_BEQDATE: case FILE_LEQDATE: ! if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 1)) == -1) return -1; t = ms->offset + sizeof(uint64_t); *************** *** 437,448 **** case FILE_QLDATE: case FILE_BEQLDATE: case FILE_LEQLDATE: ! if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 0)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; case FILE_REGEX: { char *cp; int rval; --- 454,507 ---- case FILE_QLDATE: case FILE_BEQLDATE: case FILE_LEQLDATE: ! if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 0)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: + vf = p->f; + switch (check_fmt(ms, m)) { + case -1: + return -1; + case 1: + if (asprintf(&buf, "%g", vf) < 0) + return -1; + if (file_printf(ms, MAGIC_DESC, buf) == -1) + return -1; + break; + default: + if (file_printf(ms, MAGIC_DESC, vf) == -1) + return -1; + break; + } + t = ms->offset + sizeof(float); + break; + + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: + vd = p->d; + switch (check_fmt(ms, m)) { + case -1: + return -1; + case 1: + if (asprintf(&buf, "%g", vd) < 0) + return -1; + if (file_printf(ms, MAGIC_DESC, buf) == -1) + return -1; + break; + default: + if (file_printf(ms, MAGIC_DESC, vd) == -1) + return -1; + break; + } + t = ms->offset + sizeof(double); + break; + case FILE_REGEX: { char *cp; int rval; *************** *** 452,458 **** file_oomem(ms, ms->search.rm_len); return -1; } ! rval = file_printf(ms, m->desc, cp); free(cp); if (rval == -1) --- 511,517 ---- file_oomem(ms, ms->search.rm_len); return -1; } ! rval = file_printf(ms, MAGIC_DESC, cp); free(cp); if (rval == -1) *************** *** 466,472 **** } case FILE_SEARCH: ! if (file_printf(ms, m->desc, m->value.s) == -1) return -1; if ((m->str_flags & REGEX_OFFSET_START)) t = ms->search.offset; --- 525,531 ---- } case FILE_SEARCH: ! if (file_printf(ms, MAGIC_DESC, m->value.s) == -1) return -1; if ((m->str_flags & REGEX_OFFSET_START)) t = ms->search.offset; *************** *** 475,481 **** break; case FILE_DEFAULT: ! if (file_printf(ms, m->desc, m->value.s) == -1) return -1; t = ms->offset; break; --- 534,540 ---- break; case FILE_DEFAULT: ! if (file_printf(ms, MAGIC_DESC, m->value.s) == -1) return -1; t = ms->offset; break; *************** *** 543,548 **** --- 602,636 ---- DO_CVT(q, (uint64_t)); } + #define DO_CVT2(fld, cast) \ + if (m->num_mask) \ + switch (m->mask_op & FILE_OPS_MASK) { \ + case FILE_OPADD: \ + p->fld += cast m->num_mask; \ + break; \ + case FILE_OPMINUS: \ + p->fld -= cast m->num_mask; \ + break; \ + case FILE_OPMULTIPLY: \ + p->fld *= cast m->num_mask; \ + break; \ + case FILE_OPDIVIDE: \ + p->fld /= cast m->num_mask; \ + break; \ + } \ + + private void + cvt_float(union VALUETYPE *p, const struct magic *m) + { + DO_CVT2(f, (float)); + } + + private void + cvt_double(union VALUETYPE *p, const struct magic *m) + { + DO_CVT2(d, (double)); + } + /* * Convert the byte order of the data we are looking at * While we're here, let's apply the mask operation *************** *** 609,618 **** case FILE_BEQUAD: case FILE_BEQDATE: case FILE_BEQLDATE: ! p->q = (int64_t) ! (((int64_t)p->hq[0]<<56)|((int64_t)p->hq[1]<<48)| ! ((int64_t)p->hq[2]<<40)|((int64_t)p->hq[3]<<32)| ! (p->hq[4]<<24)|(p->hq[5]<<16)|(p->hq[6]<<8)|(p->hq[7])); cvt_64(p, m); return 1; case FILE_LESHORT: --- 697,707 ---- case FILE_BEQUAD: case FILE_BEQDATE: case FILE_BEQLDATE: ! p->q = (uint64_t) ! (((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)| ! ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)| ! ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)| ! ((uint64_t)p->hq[6]<<8)|((uint64_t)p->hq[7])); cvt_64(p, m); return 1; case FILE_LESHORT: *************** *** 629,638 **** case FILE_LEQUAD: case FILE_LEQDATE: case FILE_LEQLDATE: ! p->q = (int64_t) ! (((int64_t)p->hq[7]<<56)|((int64_t)p->hq[6]<<48)| ! ((int64_t)p->hq[5]<<40)|((int64_t)p->hq[4]<<32)| ! (p->hq[3]<<24)|(p->hq[2]<<16)|(p->hq[1]<<8)|(p->hq[0])); cvt_64(p, m); return 1; case FILE_MELONG: --- 718,728 ---- case FILE_LEQUAD: case FILE_LEQDATE: case FILE_LEQLDATE: ! p->q = (uint64_t) ! (((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)| ! ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)| ! ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)| ! ((uint64_t)p->hq[1]<<8)|((uint64_t)p->hq[0])); cvt_64(p, m); return 1; case FILE_MELONG: *************** *** 642,647 **** --- 732,767 ---- ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2])); cvt_32(p, m); return 1; + case FILE_FLOAT: + cvt_float(p, m); + return 1; + case FILE_BEFLOAT: + p->l = ((uint32_t)p->hl[0]<<24)|((uint32_t)p->hl[1]<<16)| + ((uint32_t)p->hl[2]<<8) |((uint32_t)p->hl[3]); + cvt_float(p, m); + return 1; + case FILE_LEFLOAT: + p->l = ((uint32_t)p->hl[3]<<24)|((uint32_t)p->hl[2]<<16)| + ((uint32_t)p->hl[1]<<8) |((uint32_t)p->hl[0]); + cvt_float(p, m); + return 1; + case FILE_DOUBLE: + cvt_double(p, m); + return 1; + case FILE_BEDOUBLE: + p->q = ((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)| + ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)| + ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)| + ((uint64_t)p->hq[6]<<8) |((uint64_t)p->hq[7]); + cvt_double(p, m); + return 1; + case FILE_LEDOUBLE: + p->q = ((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)| + ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)| + ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)| + ((uint64_t)p->hq[1]<<8) |((uint64_t)p->hq[0]); + cvt_double(p, m); + return 1; case FILE_REGEX: case FILE_SEARCH: case FILE_DEFAULT: *************** *** 675,687 **** case FILE_SEARCH: ms->search.s = (const char *)s + offset; ms->search.s_len = nbytes - offset; return 0; case FILE_REGEX: { - /* - * offset is interpreted as last line to search, - * (starting at 1), not as bytes-from start-of-file - */ const char *b; const char *c; const char *last; /* end of search region */ --- 795,804 ---- case FILE_SEARCH: ms->search.s = (const char *)s + offset; ms->search.s_len = nbytes - offset; + ms->search.offset = offset; return 0; case FILE_REGEX: { const char *b; const char *c; const char *last; /* end of search region */ *************** *** 728,740 **** offset); return -1; } ! for (/*EMPTY*/; src < esrc; src++, dst++) { if (dst < edst) ! *dst = *src++; else break; ! if (*dst == '\0') ! *dst = ' '; } *edst = '\0'; return 0; --- 845,861 ---- offset); return -1; } ! for (/*EMPTY*/; src < esrc; src += 2, dst++) { if (dst < edst) ! *dst = *src; else break; ! if (*dst == '\0') { ! if (type == FILE_BESTRING16 ? ! *(src - 1) != '\0' : ! *(src + 1) != '\0') ! *dst = ' '; ! } } *edst = '\0'; return 0; *************** *** 772,778 **** struct magic *m, size_t nbytes, unsigned int cont_level) { uint32_t offset = ms->offset; ! uint32_t count = m->str_count; union VALUETYPE *p = &ms->ms_value; if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1) --- 893,899 ---- struct magic *m, size_t nbytes, unsigned int cont_level) { uint32_t offset = ms->offset; ! uint32_t count = m->str_range; union VALUETYPE *p = &ms->ms_value; if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1) *************** *** 1233,1245 **** case FILE_OPMODULO: offset = p->l % off; break; - /* case TOOMANYSWITCHBLOCKS: - * ugh = p->eye % m->strain; - * rub; - * case BEER: - * off = p->tab & m->in_gest; - * sleep; - */ } } else offset = p->l; --- 1354,1359 ---- *************** *** 1287,1296 **** --- 1401,1420 ---- case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: if (nbytes < (offset + 4)) return 0; break; + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: + if (nbytes < (offset + 8)) + return 0; + break; + case FILE_STRING: case FILE_PSTRING: case FILE_SEARCH: *************** *** 1326,1335 **** uint64_t v; /* ! * What we want here is: ! * v = strncmp(m->value.s, p->s, m->vallen); ! * but ignoring any nulls. bcmp doesn't give -/+/0 ! * and isn't universally available anyway. */ v = 0; if (0L == flags) { /* normal string: do it fast */ --- 1450,1457 ---- uint64_t v; /* ! * What we want here is v = strncmp(s1, s2, len), ! * but ignoring any nulls. */ v = 0; if (0L == flags) { /* normal string: do it fast */ *************** *** 1393,1398 **** --- 1515,1522 ---- { uint64_t l = m->value.q; uint64_t v; + float fl, fv; + double dl, dv; int matched; union VALUETYPE *p = &ms->ms_value; *************** *** 1434,1439 **** --- 1558,1629 ---- v = p->q; break; + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: + fl = m->value.f; + fv = p->f; + switch (m->reln) { + case 'x': + matched = 1; + break; + + case '!': + matched = fv != fl; + break; + + case '=': + matched = fv == fl; + break; + + case '>': + matched = fv > fl; + break; + + case '<': + matched = fv < fl; + break; + + default: + matched = 0; + file_magerror(ms, "cannot happen with float: invalid relation `%c'", m->reln); + return -1; + } + return matched; + + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: + dl = m->value.d; + dv = p->d; + switch (m->reln) { + case 'x': + matched = 1; + break; + + case '!': + matched = dv != dl; + break; + + case '=': + matched = dv == dl; + break; + + case '>': + matched = dv > dl; + break; + + case '<': + matched = dv < dl; + break; + + default: + matched = 0; + file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln); + return -1; + } + return matched; + case FILE_DEFAULT: l = 0; v = 0; *************** *** 1461,1475 **** slen = MIN(m->vallen, sizeof(m->value.s)); l = 0; v = 0; - ms->search.offset = m->offset; ! for (idx = 0; m->str_count == 0 || idx < m->str_count; idx++) { if (slen + idx > ms->search.s_len) break; v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags); if (v == 0) { /* found match */ ! ms->search.offset = m->offset + idx; break; } } --- 1651,1664 ---- slen = MIN(m->vallen, sizeof(m->value.s)); l = 0; v = 0; ! for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) { if (slen + idx > ms->search.s_len) break; v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags); if (v == 0) { /* found match */ ! ms->search.offset += idx; break; } }