Imported Upstream version 5.32
[platform/upstream/file.git] / src / apprentice.c
index f8f2e17..a7b4dd8 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.260 2017/04/28 16:27:58 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -612,8 +612,7 @@ buffer_apprentice(struct magic_set *ms, struct magic **bufs,
        if (nbufs == 0)
                return -1;
 
-       if (ms->mlist[0] != NULL)
-               file_reset(ms);
+       (void)file_reset(ms, 0);
 
        init_file_tables();
 
@@ -656,8 +655,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
        int file_err, errs = -1;
        size_t i;
 
-       if (ms->mlist[0] != NULL)
-               file_reset(ms);
+       (void)file_reset(ms, 0);
 
        if ((fn = magic_getpath(fn, action)) == NULL)
                return -1;
@@ -779,6 +777,59 @@ nonmagic(const char *str)
        return rv == 0 ? 1 : rv;        /* Return at least 1 */
 }
 
+
+private size_t
+typesize(int type)
+{
+       switch (type) {
+       case FILE_BYTE:
+               return 1;
+
+       case FILE_SHORT:
+       case FILE_LESHORT:
+       case FILE_BESHORT:
+               return 2;
+
+       case FILE_LONG:
+       case FILE_LELONG:
+       case FILE_BELONG:
+       case FILE_MELONG:
+               return 4;
+
+       case FILE_DATE:
+       case FILE_LEDATE:
+       case FILE_BEDATE:
+       case FILE_MEDATE:
+       case FILE_LDATE:
+       case FILE_LELDATE:
+       case FILE_BELDATE:
+       case FILE_MELDATE:
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               return 4;
+
+       case FILE_QUAD:
+       case FILE_BEQUAD:
+       case FILE_LEQUAD:
+       case FILE_QDATE:
+       case FILE_LEQDATE:
+       case FILE_BEQDATE:
+       case FILE_QLDATE:
+       case FILE_LEQLDATE:
+       case FILE_BEQLDATE:
+       case FILE_QWDATE:
+       case FILE_LEQWDATE:
+       case FILE_BEQWDATE:
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               return 8;
+       default:
+               return (size_t)~0;
+       }
+}
+
 /*
  * Get weight of this magic entry, for sorting purposes.
  */
@@ -786,7 +837,7 @@ private size_t
 apprentice_magic_strength(const struct magic *m)
 {
 #define MULT 10
-       size_t v, val = 2 * MULT;       /* baseline strength */
+       size_t ts, v, val = 2 * MULT;   /* baseline strength */
 
        switch (m->type) {
        case FILE_DEFAULT:      /* make sure this sorts last */
@@ -795,41 +846,13 @@ apprentice_magic_strength(const struct magic *m)
                return 0;
 
        case FILE_BYTE:
-               val += 1 * MULT;
-               break;
-
        case FILE_SHORT:
        case FILE_LESHORT:
        case FILE_BESHORT:
-               val += 2 * MULT;
-               break;
-
        case FILE_LONG:
        case FILE_LELONG:
        case FILE_BELONG:
        case FILE_MELONG:
-               val += 4 * MULT;
-               break;
-
-       case FILE_PSTRING:
-       case FILE_STRING:
-               val += m->vallen * MULT;
-               break;
-
-       case FILE_BESTRING16:
-       case FILE_LESTRING16:
-               val += m->vallen * MULT / 2;
-               break;
-
-       case FILE_SEARCH:
-               val += m->vallen * MAX(MULT / m->vallen, 1);
-               break;
-
-       case FILE_REGEX:
-               v = nonmagic(m->value.s);
-               val += v * MAX(MULT / v, 1);
-               break;
-
        case FILE_DATE:
        case FILE_LEDATE:
        case FILE_BEDATE:
@@ -841,9 +864,6 @@ apprentice_magic_strength(const struct magic *m)
        case FILE_FLOAT:
        case FILE_BEFLOAT:
        case FILE_LEFLOAT:
-               val += 4 * MULT;
-               break;
-
        case FILE_QUAD:
        case FILE_BEQUAD:
        case FILE_LEQUAD:
@@ -859,7 +879,29 @@ apprentice_magic_strength(const struct magic *m)
        case FILE_DOUBLE:
        case FILE_BEDOUBLE:
        case FILE_LEDOUBLE:
-               val += 8 * MULT;
+               ts = typesize(m->type);
+               if (ts == (size_t)~0)
+                       abort();
+               val += ts * MULT;
+               break;
+
+       case FILE_PSTRING:
+       case FILE_STRING:
+               val += m->vallen * MULT;
+               break;
+
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               val += m->vallen * MULT / 2;
+               break;
+
+       case FILE_SEARCH:
+               val += m->vallen * MAX(MULT / m->vallen, 1);
+               break;
+
+       case FILE_REGEX:
+               v = nonmagic(m->value.s);
+               val += v * MAX(MULT / v, 1);
                break;
 
        case FILE_INDIRECT:
@@ -2623,9 +2665,46 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
        default:
                if (m->reln != 'x') {
                        char *ep;
+                       uint64_t ull;
                        errno = 0;
-                       m->value.q = file_signextend(ms, m,
-                           (uint64_t)strtoull(*p, &ep, 0));
+                       ull = (uint64_t)strtoull(*p, &ep, 0);
+                       m->value.q = file_signextend(ms, m, ull);
+                       if (*p == ep) {
+                               file_magwarn(ms, "Unparseable number `%s'", *p);
+                       } else {
+                               size_t ts = typesize(m->type);
+                               uint64_t x;
+                               const char *q;
+
+                               if (ts == (size_t)~0) {
+                                       file_magwarn(ms, "Expected numeric type got `%s'",
+                                           type_tbl[m->type].name);
+                               }
+                               for (q = *p; isspace((unsigned char)*q); q++)
+                                       continue;
+                               if (*q == '-')
+                                       ull = -(int64_t)ull;
+                               switch (ts) {
+                               case 1:
+                                       x = ull & ~0xffULL;
+                                       break;
+                               case 2:
+                                       x = ull & ~0xffffULL;
+                                       break;
+                               case 4:
+                                       x = ull & ~0xffffffffULL;
+                                       break;
+                               case 8:
+                                       x = 0;
+                                       break;
+                               default:
+                                       abort();
+                               }
+                               if (x) {
+                                       file_magwarn(ms, "Overflow for numeric type `%s' value %#" PRIx64,
+                                           type_tbl[m->type].name, ull);
+                               }
+                       }
                        if (errno == 0) {
                                *p = ep;
                                eatsize(p);