]> granicus.if.org Git - file/commitdiff
factor out all the duplicated regex code into a wrapper.
authorChristos Zoulas <christos@zoulas.com>
Mon, 5 May 2014 20:53:10 +0000 (20:53 +0000)
committerChristos Zoulas <christos@zoulas.com>
Mon, 5 May 2014 20:53:10 +0000 (20:53 +0000)
src/file.h
src/funcs.c
src/softmagic.c

index eb9af74bee63b614589bcc912e95311d0985078c..c17c51240befe9bad9a72337d3c902ce19158eab 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.148 2014/02/12 23:20:53 christos Exp $
+ * @(#)$File: file.h,v 1.149 2014/03/15 21:47:40 christos Exp $
  */
 
 #ifndef __file_h__
@@ -468,6 +468,18 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *,
     size_t);
 #endif /* __EMX__ */
 
+typedef struct {
+       const char *pat;
+       char *old_lc_ctype;
+       int rc;
+       regex_t rx;
+} file_regex_t;
+
+protected int file_regcomp(file_regex_t *, const char *, int);
+protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
+    int);
+protected void file_regfree(file_regex_t *);
+protected void file_regerror(file_regex_t *, int, struct magic_set *);
 
 #ifndef COMPILE_ONLY
 extern const char *file_names[];
index 863871d7d047d9ffa6b1ad968f095349a270268c..fe14dd107f7e9b4e130cd9fa7fc1e222273bad66 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.69 2014/03/06 16:03:39 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.70 2014/03/14 19:02:37 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -427,35 +427,65 @@ file_printedlen(const struct magic_set *ms)
 protected int
 file_replace(struct magic_set *ms, const char *pat, const char *rep)
 {
-       regex_t rx;
+       file_regex_t rx;
        int rc, rv = -1;
-       char *old_lc_ctype;
 
-       old_lc_ctype = setlocale(LC_CTYPE, NULL);
-       assert(old_lc_ctype != NULL);
-       old_lc_ctype = strdup(old_lc_ctype);
-       assert(old_lc_ctype != NULL);
-       (void)setlocale(LC_CTYPE, "C");
-       rc = regcomp(&rx, pat, REG_EXTENDED);
+       rc = file_regcomp(&rx, pat, REG_EXTENDED);
        if (rc) {
-               char errmsg[512];
-               (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
-               file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
+               file_regerror(&rx, rc, ms);
        } else {
                regmatch_t rm;
                int nm = 0;
-               while (regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
+               while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
                        ms->o.buf[rm.rm_so] = '\0';
                        if (file_printf(ms, "%s%s", rep,
                            rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
                                goto out;
                        nm++;
                }
-               regfree(&rx);
                rv = nm;
        }
 out:
-       (void)setlocale(LC_CTYPE, old_lc_ctype);
-       free(old_lc_ctype);
+       file_regfree(&rx);
        return rv;
 }
+
+protected int
+file_regcomp(file_regex_t *rx, const char *pat, int flags)
+{
+       rx->old_lc_ctype = setlocale(LC_CTYPE, NULL);
+       assert(rx->old_lc_ctype != NULL);
+       rx->old_lc_ctype = strdup(rx->old_lc_ctype);
+       assert(rx->old_lc_ctype != NULL);
+       rx->pat = pat;
+
+       (void)setlocale(LC_CTYPE, "C");
+       return rx->rc = regcomp(&rx->rx, pat, flags);
+}
+
+protected int
+file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
+    regmatch_t* pmatch, int eflags)
+{
+       assert(rx->rc == 0);
+       return regexec(&rx->rx, str, nmatch, pmatch, eflags);
+}
+
+protected void
+file_regfree(file_regex_t *rx)
+{
+       if (rx->rc == 0)
+               regfree(&rx->rx);
+       (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
+       free(rx->old_lc_ctype);
+}
+
+protected void
+file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
+{
+       char errmsg[512];
+
+       (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg));
+       file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
+           errmsg);
+}
index 44d3cbdc0c5c950942c90503c3eea867620a04ee..3153d437cab50e124e7d96e8c5d68b35e98e4abb 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.184 2014/04/12 15:47:10 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.185 2014/04/30 21:41:02 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -364,30 +364,20 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
 private int
 check_fmt(struct magic_set *ms, struct magic *m)
 {
-       regex_t rx;
+       file_regex_t rx;
        int rc, rv = -1;
-       char *old_lc_ctype;
 
        if (strchr(m->desc, '%') == NULL)
                return 0;
 
-       old_lc_ctype = setlocale(LC_CTYPE, NULL);
-       assert(old_lc_ctype != NULL);
-       old_lc_ctype = strdup(old_lc_ctype);
-       assert(old_lc_ctype != NULL);
-       (void)setlocale(LC_CTYPE, "C");
-       rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
+       rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
        if (rc) {
-               char errmsg[512];
-               (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
-               file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
+               file_regerror(&rx, rc, ms);
        } else {
-               rc = regexec(&rx, m->desc, 0, 0, 0);
-               regfree(&rx);
+               rc = file_regexec(&rx, m->desc, 0, 0, 0);
                rv = !rc;
        }
-       (void)setlocale(LC_CTYPE, old_lc_ctype);
-       free(old_lc_ctype);
+       file_regfree(&rx);
        return rv;
 }
 
@@ -1776,7 +1766,6 @@ magiccheck(struct magic_set *ms, struct magic *m)
        double dl, dv;
        int matched;
        union VALUETYPE *p = &ms->ms_value;
-       char *old_lc_ctype;
 
        switch (m->type) {
        case FILE_BYTE:
@@ -1929,28 +1918,19 @@ magiccheck(struct magic_set *ms, struct magic *m)
        }
        case FILE_REGEX: {
                int rc;
-               regex_t rx;
-               char errmsg[512];
+               file_regex_t rx;
 
                if (ms->search.s == NULL)
                        return 0;
 
-               old_lc_ctype = setlocale(LC_CTYPE, NULL);
-               assert(old_lc_ctype != NULL);
-               old_lc_ctype = strdup(old_lc_ctype);
-               assert(old_lc_ctype != NULL);
-               (void)setlocale(LC_CTYPE, "C");
                l = 0;
-               rc = regcomp(&rx, m->value.s,
+               rc = file_regcomp(&rx, m->value.s,
                    REG_EXTENDED|REG_NEWLINE|
                    ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
                if (rc) {
-                       (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
-                       file_magerror(ms, "regex error %d, (%s)",
-                           rc, errmsg);
+                       file_regerror(&rx, rc, ms);
                        v = (uint64_t)-1;
-               }
-               else {
+               } else {
                        regmatch_t pmatch[1];
 #ifndef REG_STARTEND
 #define        REG_STARTEND    0
@@ -1961,7 +1941,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
                        pmatch[0].rm_so = 0;
                        pmatch[0].rm_eo = ms->search.s_len;
 #endif
-                       rc = regexec(&rx, (const char *)ms->search.s,
+                       rc = file_regexec(&rx, (const char *)ms->search.s,
                            1, pmatch, REG_STARTEND);
 #if REG_STARTEND == 0
                        ((char *)(intptr_t)ms->search.s)[l] = c;
@@ -1980,16 +1960,12 @@ magiccheck(struct magic_set *ms, struct magic *m)
                                break;
 
                        default:
-                               (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
-                               file_magerror(ms, "regexec error %d, (%s)",
-                                   rc, errmsg);
+                               file_regerror(&rx, rc, ms);
                                v = (uint64_t)-1;
                                break;
                        }
-                       regfree(&rx);
                }
-               (void)setlocale(LC_CTYPE, old_lc_ctype);
-               free(old_lc_ctype);
+               file_regfree(&rx);
                if (v == (uint64_t)-1)
                        return -1;
                break;