From d3bc3aa5b5bdbd05de47c3db8118056435bed5e8 Mon Sep 17 00:00:00 2001 From: Christos Zoulas Date: Mon, 5 May 2014 20:53:10 +0000 Subject: [PATCH] factor out all the duplicated regex code into a wrapper. --- src/file.h | 14 ++++++++++- src/funcs.c | 62 ++++++++++++++++++++++++++++++++++++------------- src/softmagic.c | 50 +++++++++++---------------------------- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/src/file.h b/src/file.h index eb9af74b..c17c5124 100644 --- a/src/file.h +++ b/src/file.h @@ -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[]; diff --git a/src/funcs.c b/src/funcs.c index 863871d7..fe14dd10 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -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); +} diff --git a/src/softmagic.c b/src/softmagic.c index 44d3cbdc..3153d437 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -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; -- 2.40.0