1 #include <string.h>
2 #include "regexp.h"
3 #include "debug.h"
4 #include "error.h"
5 #include "util/xmalloc.h"
6
regexp_match_nosub(const char * pattern,const char * buf,size_t size)7 bool regexp_match_nosub(const char *pattern, const char *buf, size_t size)
8 {
9 regex_t re;
10 bool compiled = regexp_compile(&re, pattern, REG_NEWLINE | REG_NOSUB);
11 BUG_ON(!compiled);
12 regmatch_t m;
13 bool ret = regexp_exec(&re, buf, size, 1, &m, 0);
14 regfree(&re);
15 return ret;
16 }
17
regexp_match(const char * pattern,const char * buf,size_t size,PointerArray * m)18 bool regexp_match (
19 const char *pattern,
20 const char *buf,
21 size_t size,
22 PointerArray *m
23 ) {
24 regex_t re;
25 bool compiled = regexp_compile(&re, pattern, REG_NEWLINE);
26 BUG_ON(!compiled);
27 bool ret = regexp_exec_sub(&re, buf, size, m, 0);
28 regfree(&re);
29 return ret;
30 }
31
regexp_compile_internal(regex_t * re,const char * pattern,int flags)32 bool regexp_compile_internal(regex_t *re, const char *pattern, int flags)
33 {
34 int err = regcomp(re, pattern, flags);
35
36 if (err) {
37 char msg[1024];
38 regerror(err, re, msg, sizeof(msg));
39 error_msg("%s: %s", msg, pattern);
40 return false;
41 }
42 return true;
43 }
44
regexp_exec(const regex_t * re,const char * buf,size_t size,size_t nr_m,regmatch_t * m,int flags)45 bool regexp_exec (
46 const regex_t *re,
47 const char *buf,
48 size_t size,
49 size_t nr_m,
50 regmatch_t *m,
51 int flags
52 ) {
53 BUG_ON(!nr_m);
54 // Clang's address sanitizer seemingly doesn't take REG_STARTEND into
55 // account when checking for buffer overflow.
56 #if defined(REG_STARTEND) && !defined(CLANG_ASAN_ENABLED)
57 m[0].rm_so = 0;
58 m[0].rm_eo = size;
59 return !regexec(re, buf, nr_m, m, flags | REG_STARTEND);
60 #else
61 // Buffer must be null-terminated if REG_STARTEND isn't supported
62 char *tmp = xstrcut(buf, size);
63 int ret = !regexec(re, tmp, nr_m, m, flags);
64 free(tmp);
65 return ret;
66 #endif
67 }
68
regexp_exec_sub(const regex_t * re,const char * buf,size_t size,PointerArray * matches,int flags)69 bool regexp_exec_sub (
70 const regex_t *re,
71 const char *buf,
72 size_t size,
73 PointerArray *matches,
74 int flags
75 ) {
76 regmatch_t m[16];
77 bool ret = regexp_exec(re, buf, size, ARRAY_COUNT(m), m, flags);
78 if (!ret) {
79 return false;
80 }
81 for (size_t i = 0; i < ARRAY_COUNT(m); i++) {
82 if (m[i].rm_so == -1) {
83 break;
84 }
85 ptr_array_add(matches, xstrslice(buf, m[i].rm_so, m[i].rm_eo));
86 }
87 return true;
88 }
89