Coverage Report

Created: 2024-05-20 06:31

/src/clamav/libclamav/regex/regexec.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: regexec.c,v 1.14 2018/07/11 12:38:46 martijn Exp $ */
2
/*-
3
 * Copyright (c) 1992, 1993, 1994 Henry Spencer.
4
 * Copyright (c) 1992, 1993, 1994
5
 *  The Regents of the University of California.  All rights reserved.
6
 *
7
 * This code is derived from software contributed to Berkeley by
8
 * Henry Spencer.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of the University nor the names of its contributors
19
 *    may be used to endorse or promote products derived from this software
20
 *    without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 *
34
 *  @(#)regexec.c 8.3 (Berkeley) 3/20/94
35
 */
36
37
/*
38
 * the outer shell of regexec()
39
 *
40
 * This file includes engine.c *twice*, after muchos fiddling with the
41
 * macros that code uses.  This lets the same code operate on two different
42
 * representations for state sets.
43
 */
44
#include <sys/types.h>
45
#include <stdio.h>
46
#include <stdlib.h>
47
#include <string.h>
48
#include <limits.h>
49
#include <ctype.h>
50
#include "others.h"
51
#include "regex.h"
52
53
#include "utils.h"
54
#include "regex2.h"
55
56
/* macros for manipulating states, small version */
57
0
#define states  long
58
#define states1 long    /* for later use in cli_regexec() decision */
59
0
#define CLEAR(v)  ((v) = 0)
60
#define SET0(v, n)  ((v) &= ~((unsigned long)1 << (n)))
61
0
#define SET1(v, n)  ((v) |= (unsigned long)1 << (n))
62
0
#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0)
63
0
#define ASSIGN(d, s)  ((d) = (s))
64
0
#define EQ(a, b)  ((a) == (b))
65
#define STATEVARS long dummy  /* dummy version */
66
#define STATESETUP(m, n)  /* nothing */
67
#define STATETEARDOWN(m)  /* nothing */
68
0
#define SETUP(v)  ((v) = 0)
69
0
#define onestate  long
70
0
#define INIT(o, n)  ((o) = (unsigned long)1 << (n))
71
0
#define INC(o)    ((o) <<= 1)
72
0
#define ISSTATEIN(v, o) (((v) & (o)) != 0)
73
/* some abbreviations; note that some of these know variable names! */
74
/* do "if I'm here, I can also be there" etc without branches */
75
0
#define FWD(dst, src, n)  ((dst) |= ((unsigned long)(src)&(here)) << (n))
76
0
#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n))
77
0
#define ISSETBACK(v, n)   (((v) & ((unsigned long)here >> (n))) != 0)
78
/* function names */
79
#define SNAMES      /* engine.c looks after details */
80
81
#include "engine.c"
82
83
/* now undo things */
84
#undef  states
85
#undef  CLEAR
86
#undef  SET0
87
#undef  SET1
88
#undef  ISSET
89
#undef  ASSIGN
90
#undef  EQ
91
#undef  STATEVARS
92
#undef  STATESETUP
93
#undef  STATETEARDOWN
94
#undef  SETUP
95
#undef  onestate
96
#undef  INIT
97
#undef  INC
98
#undef  ISSTATEIN
99
#undef  FWD
100
#undef  BACK
101
#undef  ISSETBACK
102
#undef  SNAMES
103
104
/* macros for manipulating states, large version */
105
0
#define states  char *
106
0
#define CLEAR(v)  memset(v, 0, m->g->nstates)
107
#define SET0(v, n)  ((v)[n] = 0)
108
0
#define SET1(v, n)  ((v)[n] = 1)
109
0
#define ISSET(v, n) ((v)[n])
110
0
#define ASSIGN(d, s)  memcpy(d, s, m->g->nstates)
111
0
#define EQ(a, b)  (memcmp(a, b, m->g->nstates) == 0)
112
#define STATEVARS long vn; char *space
113
0
#define STATESETUP(m, nv) { (m)->space = cli_max_malloc((nv)*(m)->g->nstates); \
114
0
        if ((m)->space == NULL) return(REG_ESPACE); \
115
0
        (m)->vn = 0; }
116
0
#define STATETEARDOWN(m)  { free((m)->space); }
117
0
#define SETUP(v)  ((v) = &m->space[m->vn++ * m->g->nstates])
118
0
#define onestate  long
119
0
#define INIT(o, n)  ((o) = (n))
120
0
#define INC(o)  ((o)++)
121
0
#define ISSTATEIN(v, o) ((v)[o])
122
/* some abbreviations; note that some of these know variable names! */
123
/* do "if I'm here, I can also be there" etc without branches */
124
0
#define FWD(dst, src, n)  ((dst)[here+(n)] |= (src)[here])
125
0
#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
126
0
#define ISSETBACK(v, n) ((v)[here - (n)])
127
/* function names */
128
#define LNAMES      /* flag */
129
130
#include "engine.c"
131
132
/*
133
 - regexec - interface for matching
134
 *
135
 * We put this here so we can exploit knowledge of the state representation
136
 * when choosing which matcher to call.  Also, by this point the matchers
137
 * have been prototyped.
138
 */
139
int       /* 0 success, REG_NOMATCH failure */
140
cli_regexec(const regex_t *preg, const char *string, size_t nmatch,
141
    regmatch_t pmatch[], int eflags)
142
0
{
143
0
  struct re_guts *g = preg->re_g;
144
145
#ifdef REDEBUG
146
# define  GOODFLAGS(f)  (f)
147
#else
148
0
# define  GOODFLAGS(f)  ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
149
0
#endif
150
151
0
  if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
152
0
    return(REG_BADPAT);
153
0
  assert(!(g->iflags&REGEX_BAD));
154
0
  if (g->iflags&REGEX_BAD)   /* backstop for no-debug case */
155
0
    return(REG_BADPAT);
156
0
  eflags = GOODFLAGS(eflags);
157
158
0
  if ((unsigned long)g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
159
0
    return(smatcher(g, string, nmatch, pmatch, eflags));
160
0
  else
161
0
    return(lmatcher(g, string, nmatch, pmatch, eflags));
162
0
}