[augeas-devel] augeas: master - Properly check regexp literals for syntax errors
David Lutterkort
lutter at fedoraproject.org
Thu Nov 26 01:15:44 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=51cfb5af2805ff602c8b1f398b13cf4930c688b4
Commit: 51cfb5af2805ff602c8b1f398b13cf4930c688b4
Parent: 4effdd8e3d94bbd49cd50f1ff21b41b03cd10e1b
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Wed Nov 25 17:10:27 2009 -0800
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Wed Nov 25 17:10:27 2009 -0800
Properly check regexp literals for syntax errors
* src/regexp.h (regexp_check): new function
* src/regexp.c (regexp_compile_internal): new function to base both
regexp_compile and regexp_check off
* src/syntax.c (check_value): produce a syntax error if regexp does not
pass regexp_check; (check_exp): make sure we do check values
Fixes ticket #93
---
src/regexp.c | 20 ++++++++++++++++----
src/regexp.h | 6 ++++++
src/syntax.c | 8 ++++++--
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/src/regexp.c b/src/regexp.c
index caecce4..85dea58 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -26,6 +26,7 @@
#include "internal.h"
#include "syntax.h"
#include "memory.h"
+#include "errcode.h"
static const struct string empty_pattern_string = {
.ref = REF_MAX, .str = (char *) "()"
@@ -331,7 +332,7 @@ struct regexp *regexp_make_empty(struct info *info) {
return regexp;
}
-int regexp_compile(struct regexp *r) {
+static int regexp_compile_internal(struct regexp *r, const char **c) {
/* See the GNU regex manual or regex.h in gnulib for
* an explanation of these flags. They are set so that the regex
* matcher interprets regular expressions the same way that libfa
@@ -343,21 +344,32 @@ int regexp_compile(struct regexp *r) {
|RE_NO_BK_VBAR|RE_NO_EMPTY_RANGES
|RE_NO_POSIX_BACKTRACKING|RE_CONTEXT_INVALID_DUP|RE_NO_GNU_OPS;
reg_syntax_t old_syntax = re_syntax_options;
- const char *c = NULL;
+
+ *c = NULL;
if (r->re == NULL)
CALLOC(r->re, 1);
re_syntax_options = syntax;
- c = re_compile_pattern(r->pattern->str, strlen(r->pattern->str), r->re);
+ *c = re_compile_pattern(r->pattern->str, strlen(r->pattern->str), r->re);
re_syntax_options = old_syntax;
r->re->regs_allocated = REGS_REALLOCATE;
- if (c != NULL)
+ if (*c != NULL)
return -1;
return 0;
}
+int regexp_compile(struct regexp *r) {
+ const char *c;
+
+ return regexp_compile_internal(r, &c);
+}
+
+int regexp_check(struct regexp *r, const char **msg) {
+ return regexp_compile_internal(r, msg);
+}
+
int regexp_match(struct regexp *r,
const char *string, const int size,
const int start, struct re_registers *regs) {
diff --git a/src/regexp.h b/src/regexp.h
index ef601d8..783b123 100644
--- a/src/regexp.h
+++ b/src/regexp.h
@@ -57,6 +57,12 @@ void free_regexp(struct regexp *regexp);
*/
int regexp_compile(struct regexp *r);
+/* Check the syntax of R->PATTERN; return -1 if the pattern has a syntax
+ * error, and a string indicating the error in *C. Return 0 if the pattern
+ * is a valid regular expression.
+ */
+int regexp_check(struct regexp *r, const char **msg);
+
/* Call RE_MATCH on R->RE and return its result; if R hasn't been compiled
* yet, compile it. Return -3 if compilation fails
*/
diff --git a/src/syntax.c b/src/syntax.c
index 686d0c8..6918376 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1147,9 +1147,13 @@ static int check_binop(const char *opname, struct term *term,
}
static int check_value(struct value *v) {
+ const char *msg;
+
if (v->tag == V_REGEXP) {
- if (regexp_compile(v->regexp) == -1)
+ if (regexp_check(v->regexp, &msg) == -1) {
+ syntax_error(v->info, "Invalid regular expression: %s", msg);
return 0;
+ }
}
return 1;
}
@@ -1158,7 +1162,7 @@ static int check_value(struct value *v) {
static int check_exp(struct term *term, struct ctx *ctx) {
int result = 1;
assert(term->type == NULL || term->tag == A_VALUE || term->ref > 1);
- if (term->type != NULL)
+ if (term->type != NULL && term->tag != A_VALUE)
return 1;
switch (term->tag) {
More information about the augeas-devel
mailing list