Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package file for openSUSE:Factory checked in 
at 2022-03-29 18:13:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/file (Old)
 and      /work/SRC/openSUSE:Factory/.file.new.1900 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "file"

Tue Mar 29 18:13:43 2022 rev:125 rq:964719 version:5.41

Changes:
--------
--- /work/SRC/openSUSE:Factory/file/file.changes        2022-02-25 
21:24:50.675635872 +0100
+++ /work/SRC/openSUSE:Factory/.file.new.1900/file.changes      2022-03-29 
18:13:45.103036112 +0200
@@ -1,0 +2,11 @@
+Wed Mar 23 09:02:37 UTC 2022 - Dirk M??ller <dmuel...@suse.com>
+
+- add file-5.41-cache-regexps-locale-restore.patch to restore
+  previous locale handling behavior 
+
+-------------------------------------------------------------------
+Sat Mar 19 18:00:32 UTC 2022 - Dirk M??ller <dmuel...@suse.com>
+
+- add file-5.41-cache-regexps.patch to cache regexp lookups 
+
+-------------------------------------------------------------------
--- /work/SRC/openSUSE:Factory/file/python-magic.changes        2021-10-23 
00:50:20.461120989 +0200
+++ /work/SRC/openSUSE:Factory/.file.new.1900/python-magic.changes      
2022-03-29 18:13:45.139036145 +0200
@@ -1,0 +2,5 @@
+Sat Mar 19 18:01:52 UTC 2022 - Dirk M??ller <dmuel...@suse.com>
+
+- spec-cleaner run 
+
+-------------------------------------------------------------------

New:
----
  file-5.41-cache-regexps-locale-restore.patch
  file-5.41-cache-regexps.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ file.spec ++++++
--- /var/tmp/diff_new_pack.rweeoo/_old  2022-03-29 18:13:46.423037327 +0200
+++ /var/tmp/diff_new_pack.rweeoo/_new  2022-03-29 18:13:46.431037334 +0200
@@ -62,7 +62,9 @@
 Patch32:        file-5.19-clicfs.dif
 Patch34:        file-5.23-endian.patch
 Patch37:        file-secure_getenv.patch
+Patch38:        file-5.41-cache-regexps.patch
 Patch39:        file-5.28-btrfs-image.dif
+Patch40:        file-5.41-cache-regexps-locale-restore.patch
 # Upstream commits as patches
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 %global         _sysconfdir /etc
@@ -125,7 +127,9 @@
 %patch32 -p0 -b .clicfs
 %patch34 -p0 -b .endian
 %patch37 -p1 -b .getenv
+%patch38 -p1 -b .regexp
 %patch39 -p1 -b .btrfs
+%patch40 -p1 -b .locale
 %patch -b .0
 test -s src/magic.h.in || cp -p src/magic.h src/magic.h.in
 rm -fv src/magic.h

++++++ python-magic.spec ++++++
--- /var/tmp/diff_new_pack.rweeoo/_old  2022-03-29 18:13:46.455037356 +0200
+++ /var/tmp/diff_new_pack.rweeoo/_new  2022-03-29 18:13:46.459037360 +0200
@@ -19,25 +19,23 @@
 # PyPI package name is file-magic. Version is taken from setup.py
 %define file_magic_version 0.3.0
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
-
+%global         _miscdir    %{_datadir}/misc
 Name:           python-magic
-BuildRequires:  %{python_module setuptools}
-BuildRequires:  findutils
-BuildRequires:  libtool
-BuildRequires:  python-rpm-macros
-BuildRequires:  zlib-devel
-URL:            http://www.darwinsys.com/file/
 Version:        5.41
 Release:        0
 Summary:        Python module to use libmagic
 License:        BSD-3-Clause AND BSD-4-Clause
 Group:          Development/Languages/Python
-%{expand:%(sed -n -e '/^Source0\?:/,/^BuildRoot:/p' <%{_sourcedir}/file.spec)}
+URL:            https://www.darwinsys.com/file/
 Source99:       file.spec
+BuildRequires:  %{python_module setuptools}
+BuildRequires:  findutils
+BuildRequires:  libtool
+BuildRequires:  python-rpm-macros
+BuildRequires:  zlib-devel
 Requires:       libmagic1
 Provides:       python-file-magic = %{file_magic_version}
-%global         _miscdir    %{_datadir}/misc
-
+%{expand:%(sed -n -e '/^Source0\?:/,/^BuildRoot:/p' <%{_sourcedir}/file.spec)}
 %python_subpackages
 
 %description
@@ -58,7 +56,6 @@
 popd
 
 %files %{python_files}
-%defattr(-,root,root)
 %doc python/README python/example.py
 %{python_sitelib}/magic.py*
 %pycache_only %{python_sitelib}/__pycache__

++++++ file-5.41-cache-regexps-locale-restore.patch ++++++
>From 7d438e28c16773e28a3707935c8e5d9927a515a7 Mon Sep 17 00:00:00 2001
From: Christos Zoulas <chris...@zoulas.com>
Date: Sat, 19 Mar 2022 19:52:09 +0000
Subject: [PATCH] Now that we are cacheing regex's we cannot assume that we
 always do regcomp->regexec->regfree, so this causes memory corruption (and
 increased memory use with all the locale copies) in xlocale systems. Instead
 save and restore locales in regcomp and regexec as needed.

---
 src/apprentice.c | 13 +++++++++--
 src/file.h       | 18 +++++++--------
 src/funcs.c      | 57 +++++++++++++++++++++++++++++-------------------
 src/softmagic.c  | 11 +++++-----
 4 files changed, 59 insertions(+), 40 deletions(-)

Index: file-5.41/src/apprentice.c
===================================================================
--- file-5.41.orig/src/apprentice.c
+++ file-5.41/src/apprentice.c
@@ -516,6 +516,9 @@ file_ms_free(struct magic_set *ms)
        free(ms->o.pbuf);
        free(ms->o.buf);
        free(ms->c.li);
+#ifdef USE_C_LOCALE
+       freelocale(ms->c_lc_ctype);
+#endif
        free(ms);
 }
 
@@ -555,6 +558,10 @@ file_ms_alloc(int flags)
        ms->regex_max = FILE_REGEX_MAX;
        ms->bytes_max = FILE_BYTES_MAX;
        ms->encoding_max = FILE_ENCODING_MAX;
+#ifdef USE_C_LOCALE
+       ms->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
+       assert(ms->c_lc_ctype != NULL);
+#endif
        return ms;
 free:
        free(ms);
@@ -628,6 +635,7 @@ mlist_free_one(struct mlist *ml)
                if (ml->magic_rxcomp[i]) {
                        file_regfree(ml->magic_rxcomp[i]);
                        free(ml->magic_rxcomp[i]);
+                       ml->magic_rxcomp[i] = NULL;
                }
        }
        free(ml->magic_rxcomp);
@@ -2741,7 +2749,8 @@ getvalue(struct magic_set *ms, struct ma
                }
                if (m->type == FILE_REGEX) {
                        file_regex_t rx;
-                       int rc = file_regcomp(&rx, m->value.s, REG_EXTENDED);
+                       int rc = file_regcomp(ms, &rx, m->value.s,
+                           REG_EXTENDED);
                        if (rc) {
                                if (ms->flags & MAGIC_CHECK)
                                        file_regerror(&rx, rc, ms);
Index: file-5.41/src/file.h
===================================================================
--- file-5.41.orig/src/file.h
+++ file-5.41/src/file.h
@@ -173,13 +173,6 @@
 
 typedef struct {
        const char *pat;
-#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && 
defined(HAVE_FREELOCALE)
-#define USE_C_LOCALE
-       locale_t old_lc_ctype;
-       locale_t c_lc_ctype;
-#else
-       char *old_lc_ctype;
-#endif
        int rc;
        regex_t rx;
 } file_regex_t;
@@ -495,6 +488,10 @@ struct magic_set {
 #define        FILE_NAME_MAX                   50
 #define        FILE_REGEX_MAX                  8192
 #define        FILE_ENCODING_MAX               (64 * 1024)
+#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && 
defined(HAVE_FREELOCALE)
+#define USE_C_LOCALE
+       locale_t c_lc_ctype;
+#endif
 };
 
 /* Type for Unicode characters */
@@ -588,9 +585,10 @@ protected int buffer_fill(const struct b
 
 
 
-protected int file_regcomp(file_regex_t *, const char *, int);
-protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
+protected int file_regcomp(struct magic_set *, file_regex_t *, const char *,
     int);
+protected int file_regexec(struct magic_set *, 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 *);
 
Index: file-5.41/src/funcs.c
===================================================================
--- file-5.41.orig/src/funcs.c
+++ file-5.41/src/funcs.c
@@ -634,13 +634,13 @@ file_replace(struct magic_set *ms, const
        file_regex_t rx;
        int rc, rv = -1;
 
-       rc = file_regcomp(&rx, pat, REG_EXTENDED);
+       rc = file_regcomp(ms, &rx, pat, REG_EXTENDED);
        if (rc) {
                file_regerror(&rx, rc, ms);
        } else {
                regmatch_t rm;
                int nm = 0;
-               while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
+               while (file_regexec(ms, &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)
@@ -655,34 +655,52 @@ out:
 }
 
 protected int
-file_regcomp(file_regex_t *rx, const char *pat, int flags)
+file_regcomp(struct magic_set *ms, file_regex_t *rx, const char *pat, int 
flags)
 {
 #ifdef USE_C_LOCALE
-       rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
-       assert(rx->c_lc_ctype != NULL);
-       rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
-       assert(rx->old_lc_ctype != NULL);
+       locale_t old = uselocale(ms->c_lc_ctype);
+       assert(old != NULL);
 #else
-       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);
+       char old[1024];
+       strlcpy(old, setlocale(LC_CTYPE, NULL), sizeof(old));
        (void)setlocale(LC_CTYPE, "C");
 #endif
        rx->pat = pat;
 
-       return rx->rc = regcomp(&rx->rx, pat, flags);
+       rx->rc = regcomp(&rx->rx, pat, flags);
+
+#ifdef USE_C_LOCALE
+       uselocale(old);
+#else
+       (void)setlocale(LC_CTYPE, old);
+#endif
+       return rx->rc;
 }
 
 protected int
-file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
-    regmatch_t* pmatch, int eflags)
+file_regexec(struct magic_set *ms, file_regex_t *rx, const char *str,
+    size_t nmatch, regmatch_t* pmatch, int eflags)
 {
+#ifdef USE_C_LOCALE
+       locale_t old = uselocale(ms->c_lc_ctype);
+       assert(old != NULL);
+#else
+       char old[1024];
+       strlcpy(old, setlocale(LC_CTYPE, NULL), sizeof(old));
+       (void)setlocale(LC_CTYPE, "C");
+#endif
+       int rc;
        assert(rx->rc == 0);
        /* XXX: force initialization because glibc does not always do this */
        if (nmatch != 0)
                memset(pmatch, 0, nmatch * sizeof(*pmatch));
-       return regexec(&rx->rx, str, nmatch, pmatch, eflags);
+       rc = regexec(&rx->rx, str, nmatch, pmatch, eflags);
+#ifdef USE_C_LOCALE
+       uselocale(old);
+#else
+       (void)setlocale(LC_CTYPE, old);
+#endif
+       return rc;
 }
 
 protected void
@@ -690,13 +708,6 @@ file_regfree(file_regex_t *rx)
 {
        if (rx->rc == 0)
                regfree(&rx->rx);
-#ifdef USE_C_LOCALE
-       (void)uselocale(rx->old_lc_ctype);
-       freelocale(rx->c_lc_ctype);
-#else
-       (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
-       free(rx->old_lc_ctype);
-#endif
 }
 
 protected void
Index: file-5.41/src/softmagic.c
===================================================================
--- file-5.41.orig/src/softmagic.c
+++ file-5.41/src/softmagic.c
@@ -479,11 +479,11 @@ check_fmt(struct magic_set *ms, const ch
        if (strchr(fmt, '%') == NULL)
                return 0;
 
-       rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
+       rc = file_regcomp(ms, &rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
        if (rc) {
                file_regerror(&rx, rc, ms);
        } else {
-               rc = file_regexec(&rx, fmt, 0, 0, 0);
+               rc = file_regexec(ms, &rx, fmt, 0, 0, 0);
                rv = !rc;
        }
        file_regfree(&rx);
@@ -2192,7 +2192,7 @@ magiccheck(struct magic_set *ms, struct
 
                if (rx == NULL) {
                        rx = *m_cache = CAST(file_regex_t*, 
malloc(sizeof(file_regex_t)));
-                       rc = file_regcomp(rx, m->value.s,
+                       rc = file_regcomp(ms, rx, m->value.s,
                                REG_EXTENDED|REG_NEWLINE|
                                ((m->str_flags & STRING_IGNORE_CASE) ? 
REG_ICASE : 0));
                        if (rc) {
@@ -2222,7 +2222,7 @@ magiccheck(struct magic_set *ms, struct
                            search = CCAST(char *, "");
                            copy = NULL;
                        }
-                       rc = file_regexec(rx, RCAST(const char *, search),
+                       rc = file_regexec(ms, rx, RCAST(const char *, search),
                            1, &pmatch, 0);
                        free(copy);
                        switch (rc) {

++++++ file-5.41-cache-regexps.patch ++++++
>From 1957db8212e9c74e5d626de3023e49d0bb502052 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dirk=20M=C3=BCller?= <d...@dmllr.de>
Date: Fri, 11 Mar 2022 23:51:55 +0100
Subject: [PATCH] Cache compiled regexps between magic matches

regcomp() is relatively expensive compared to regexec() for matching,
so it helps to only compile once and then reuse the compiled version
for future matches of the same magic.

when doing equivalent of `find | xargs file` this provides a massive
speedup, between factor 2 and 4 depending on how heavy the magic
is on regexp usage.

The memory overhead is mediocre (~ 200kb ) and it compiles regexps
lazy, so it doesn't add significant overhead to single match usecases.
---
 src/apprentice.c | 26 +++++++++++++++++++----
 src/file.h       | 40 ++++++++++++++++++-----------------
 src/softmagic.c  | 54 +++++++++++++++++++++++++++---------------------
 3 files changed, 73 insertions(+), 47 deletions(-)

Index: file-5.41/src/apprentice.c
===================================================================
--- file-5.41.orig/src/apprentice.c
+++ file-5.41/src/apprentice.c
@@ -427,7 +427,14 @@ add_mlist(struct mlist *mlp, struct magi
        ml->map = idx == 0 ? map : NULL;
        ml->magic = map->magic[idx];
        ml->nmagic = map->nmagic[idx];
-
+       ml->magic_rxcomp = NULL;
+       if (ml->nmagic) {
+               ml->magic_rxcomp = CAST(file_regex_t**, calloc(ml->nmagic, 
sizeof(file_regex_t*)));
+               if (ml->magic_rxcomp == NULL) {
+                       free(ml);
+                       return -1;
+               }
+       }
        mlp->prev->next = ml;
        ml->prev = mlp->prev;
        ml->next = mlp;
@@ -612,8 +619,19 @@ mlist_free_all(struct magic_set *ms)
 private void
 mlist_free_one(struct mlist *ml)
 {
+       size_t i;
+
        if (ml->map)
                apprentice_unmap(CAST(struct magic_map *, ml->map));
+
+       for (i = 0; i < ml->nmagic; ++i) {
+               if (ml->magic_rxcomp[i]) {
+                       file_regfree(ml->magic_rxcomp[i]);
+                       free(ml->magic_rxcomp[i]);
+               }
+       }
+       free(ml->magic_rxcomp);
+       ml->magic_rxcomp = NULL;
        free(ml);
 }
 
@@ -3489,16 +3507,16 @@ file_magicfind(struct magic_set *ms, con
 
        for (ml = mlist->next; ml != mlist; ml = ml->next) {
                struct magic *ma = ml->magic;
-               uint32_t nma = ml->nmagic;
-               for (i = 0; i < nma; i++) {
+               for (i = 0; i < ml->nmagic; i++) {
                        if (ma[i].type != FILE_NAME)
                                continue;
                        if (strcmp(ma[i].value.s, name) == 0) {
                                v->magic = &ma[i];
-                               for (j = i + 1; j < nma; j++)
+                               for (j = i + 1; j < ml->nmagic; j++)
                                    if (ma[j].cont_level == 0)
                                            break;
                                v->nmagic = j - i;
+                               v->magic_rxcomp = ml->magic_rxcomp;
                                return 0;
                        }
                }
Index: file-5.41/src/file.h
===================================================================
--- file-5.41.orig/src/file.h
+++ file-5.41/src/file.h
@@ -88,6 +88,10 @@
 /* Do this here and now, because struct stat gets re-defined on solaris */
 #include <sys/stat.h>
 #include <stdarg.h>
+#include <locale.h>
+#if defined(HAVE_XLOCALE_H)
+#include <xlocale.h>
+#endif
 
 #define ENABLE_CONDITIONALS
 
@@ -167,6 +171,19 @@
 #define FILE_COMPILE   2
 #define FILE_LIST      3
 
+typedef struct {
+       const char *pat;
+#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && 
defined(HAVE_FREELOCALE)
+#define USE_C_LOCALE
+       locale_t old_lc_ctype;
+       locale_t c_lc_ctype;
+#else
+       char *old_lc_ctype;
+#endif
+       int rc;
+       regex_t rx;
+} file_regex_t;
+
 struct buffer {
        int fd;
        struct stat st;
@@ -397,9 +414,10 @@ struct magic {
 
 /* list of magic entries */
 struct mlist {
-       struct magic *magic;            /* array of magic entries */
-       uint32_t nmagic;                /* number of entries in array */
-       void *map;                      /* internal resources used by entry */
+       struct magic *magic;                    /* array of magic entries */
+       file_regex_t **magic_rxcomp;    /* array of compiled regexps */
+       size_t nmagic;                                  /* number of entries in 
array */
+       void *map;                              /* internal resources used by 
entry */
        struct mlist *next, *prev;
 };
 
@@ -568,23 +586,7 @@ protected void buffer_init(struct buffer
 protected void buffer_fini(struct buffer *);
 protected int buffer_fill(const struct buffer *);
 
-#include <locale.h>
-#if defined(HAVE_XLOCALE_H)
-#include <xlocale.h>
-#endif
 
-typedef struct {
-       const char *pat;
-#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && 
defined(HAVE_FREELOCALE)
-#define USE_C_LOCALE
-       locale_t old_lc_ctype;
-       locale_t c_lc_ctype;
-#else
-       char *old_lc_ctype;
-#endif
-       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 *,
Index: file-5.41/src/softmagic.c
===================================================================
--- file-5.41.orig/src/softmagic.c
+++ file-5.41/src/softmagic.c
@@ -43,7 +43,7 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.3
 #include <time.h>
 #include "der.h"
 
-private int match(struct magic_set *, struct magic *, uint32_t,
+private int match(struct magic_set *, struct magic *, file_regex_t **, 
uint32_t,
     const struct buffer *, size_t, int, int, int, uint16_t *,
     uint16_t *, int *, int *, int *, int *);
 private int mget(struct magic_set *, struct magic *, const struct buffer *,
@@ -52,7 +52,7 @@ private int mget(struct magic_set *, str
     uint16_t *, int *, int *, int *, int *);
 private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
     const struct buffer *, size_t, unsigned int);
-private int magiccheck(struct magic_set *, struct magic *);
+private int magiccheck(struct magic_set *, struct magic *, file_regex_t **);
 private int32_t mprint(struct magic_set *, struct magic *);
 private int moffset(struct magic_set *, struct magic *, const struct buffer *,
     int32_t *);
@@ -131,7 +131,7 @@ file_softmagic(struct magic_set *ms, con
        }
 
        for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
-               if ((rv = match(ms, ml->magic, ml->nmagic, b, 0, mode,
+               if ((rv = match(ms, ml->magic, ml->magic_rxcomp, ml->nmagic, b, 
0, mode,
                    text, 0, indir_count, name_count,
                    &printed_something, &need_separator, NULL, NULL)) != 0)
                        return rv;
@@ -191,7 +191,7 @@ file_fmtcheck(struct magic_set *ms, cons
  *     so that higher-level continuations are processed.
  */
 private int
-match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
+match(struct magic_set *ms, struct magic *magic, file_regex_t **magic_rxcomp, 
uint32_t nmagic,
     const struct buffer *b, size_t offset, int mode, int text,
     int flip, uint16_t *indir_count, uint16_t *name_count,
     int *printed_something, int *need_separator, int *returnval,
@@ -220,6 +220,7 @@ match(struct magic_set *ms, struct magic
        for (magindex = 0; magindex < nmagic; magindex++) {
                int flush = 0;
                struct magic *m = &magic[magindex];
+               file_regex_t** m_rxcomp = &magic_rxcomp[magindex];
 
                if (m->type != FILE_NAME)
                if ((IS_STRING(m->type) &&
@@ -257,7 +258,7 @@ flush:
                                *returnval = 1;
                        }
 
-                       switch (magiccheck(ms, m)) {
+                       switch (magiccheck(ms, m, m_rxcomp)) {
                        case -1:
                                return -1;
                        case 0:
@@ -318,6 +319,7 @@ flush:
                while (magindex + 1 < nmagic &&
                    magic[magindex + 1].cont_level != 0) {
                        m = &magic[++magindex];
+                       m_rxcomp = &magic_rxcomp[magindex];
                        ms->line = m->lineno; /* for messages */
 
                        if (cont_level < m->cont_level)
@@ -371,7 +373,7 @@ flush:
                                break;
                        }
 
-                       switch (flush ? 1 : magiccheck(ms, m)) {
+                       switch (flush ? 1 : magiccheck(ms, m, m_rxcomp)) {
                        case -1:
                                return -1;
                        case 0:
@@ -655,7 +657,7 @@ mprint(struct magic_set *ms, struct magi
 
                        if (m->str_flags & STRING_TRIM)
                                str = file_strtrim(str);
-                                       
+
                        if (file_printf(ms, F(ms, desc, "%s"),
                            file_printable(ms, sbuf, sizeof(sbuf), str,
                                sizeof(p->s) - (str - p->s))) == -1)
@@ -770,7 +772,7 @@ mprint(struct magic_set *ms, struct magi
                        return -1;
                }
                scp = (m->str_flags & STRING_TRIM) ? file_strtrim(cp) : cp;
-                                       
+
                rval = file_printf(ms, F(ms, desc, "%s"), file_printable(ms,
                    sbuf, sizeof(sbuf), scp, ms->search.rm_len));
                free(cp);
@@ -1822,7 +1824,7 @@ mget(struct magic_set *ms, struct magic
                for (mlp = ms->mlist[0]->next; mlp != ms->mlist[0];
                    mlp = mlp->next)
                {
-                       if ((rv = match(ms, mlp->magic, mlp->nmagic, &bb, 0,
+                       if ((rv = match(ms, mlp->magic, mlp->magic_rxcomp, 
mlp->nmagic, &bb, 0,
                            BINTEST, text, 0, indir_count, name_count,
                            printed_something, need_separator, NULL,
                            NULL)) != 0)
@@ -1875,7 +1877,7 @@ mget(struct magic_set *ms, struct magic
                nfound_match = 0;
                (*name_count)++;
                eoffset = ms->eoffset;
-               rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
+               rv = match(ms, ml.magic, ml.magic_rxcomp, ml.nmagic, b, offset 
+ o,
                    mode, text, flip, indir_count, name_count,
                    printed_something, need_separator, returnval,
                    &nfound_match);
@@ -1999,7 +2001,7 @@ file_strncmp16(const char *a, const char
 }
 
 private int
-magiccheck(struct magic_set *ms, struct magic *m)
+magiccheck(struct magic_set *ms, struct magic *m, file_regex_t** m_cache)
 {
        uint64_t l = m->value.q;
        uint64_t v;
@@ -2182,27 +2184,32 @@ magiccheck(struct magic_set *ms, struct
        }
        case FILE_REGEX: {
                int rc;
-               file_regex_t rx;
+               file_regex_t *rx = *m_cache;
                const char *search;
 
                if (ms->search.s == NULL)
                        return 0;
 
+               if (rx == NULL) {
+                       rx = *m_cache = CAST(file_regex_t*, 
malloc(sizeof(file_regex_t)));
+                       rc = file_regcomp(rx, m->value.s,
+                               REG_EXTENDED|REG_NEWLINE|
+                               ((m->str_flags & STRING_IGNORE_CASE) ? 
REG_ICASE : 0));
+                       if (rc) {
+                               file_regerror(rx, rc, ms);
+                               file_regfree(rx);
+                               v = CAST(uint64_t, -1);
+                               break;
+                       }
+               }
                l = 0;
-               rc = file_regcomp(&rx, m->value.s,
-                   REG_EXTENDED|REG_NEWLINE|
-                   ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
-               if (rc) {
-                       file_regerror(&rx, rc, ms);
-                       v = CAST(uint64_t, -1);
-               } else {
+               {
                        regmatch_t pmatch;
                        size_t slen = ms->search.s_len;
                        char *copy;
                        if (slen != 0) {
                            copy = CAST(char *, malloc(slen));
                            if (copy == NULL)  {
-                               file_regfree(&rx);
                                file_error(ms, errno,
                                    "can't allocate %" SIZE_T_FORMAT "u bytes",
                                    slen);
@@ -2215,14 +2222,14 @@ magiccheck(struct magic_set *ms, struct
                            search = CCAST(char *, "");
                            copy = NULL;
                        }
-                       rc = file_regexec(&rx, RCAST(const char *, search),
+                       rc = file_regexec(rx, RCAST(const char *, search),
                            1, &pmatch, 0);
                        free(copy);
                        switch (rc) {
                        case 0:
                                ms->search.s += CAST(int, pmatch.rm_so);
                                ms->search.offset += CAST(size_t, pmatch.rm_so);
-                               ms->search.rm_len = CAST(size_t, 
+                               ms->search.rm_len = CAST(size_t,
                                    pmatch.rm_eo - pmatch.rm_so);
                                v = 0;
                                break;
@@ -2232,12 +2239,11 @@ magiccheck(struct magic_set *ms, struct
                                break;
 
                        default:
-                               file_regerror(&rx, rc, ms);
+                               file_regerror(rx, rc, ms);
                                v = CAST(uint64_t, -1);
                                break;
                        }
                }
-               file_regfree(&rx);
                if (v == CAST(uint64_t, -1))
                        return -1;
                break;

Reply via email to