]> git.neil.brown.name Git - edlib.git/commitdiff
rexel: don't accidentally make back-refs with impossible capnum.
authorNeilBrown <neil@brown.name>
Wed, 31 May 2023 11:12:32 +0000 (21:12 +1000)
committerNeilBrown <neil@brown.name>
Thu, 8 Jun 2023 10:38:57 +0000 (20:38 +1000)
If we try to make a backref with an impossible CAPture NUMber, it will
look like an invalid opcode, and rexel will abort() (which it
shouldn't...).  So make sure it doesn't happen.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
rexel.c

index b1e06c449ad2386a178645ee8fdc38c071d9433f..874bf6a523ed4e19645bb0aa732cc5bb801538d7 100644 (file)
@@ -172,6 +172,7 @@ Module features
 
 ### rexel
 
+- [ ] don't abort if something looks wrong, just fail.
 - [ ] move to separate git repo and document well.
 - [ ] review return code of rxl_advance().  What should be
       returned if a flag allowed a match, but the char didn't.
diff --git a/rexel.c b/rexel.c
index f631f32e7f543097a8bc9213570943ee10e522dc..6486073f00c1aeff254efd3ad697a2149e75e4a4 100644 (file)
--- a/rexel.c
+++ b/rexel.c
@@ -274,6 +274,7 @@ static inline void clear_bit(int bit, unsigned long *set safe)
 #define        REC_ISSET(x)    (((x) & 0xe000) == REC_SET)
 #define        REC_ISCAPTURE(x) (((x) & 0xf000) == REC_CAPTURE)
 #define        REC_ISBACKREF(x) (((x) & 0xf000) == REC_BACKREF)
+#define        REC_BACKREF_MAKE(x) (REC_BACKREF | ((x) & 0x7ff))
 #define        REC_ADDR(x)     ((x) & 0x0fff)
 #define        REC_ISFIRST(x)  (!!((x) & (REC_FORKFIRST ^ REC_FORKLAST)))
 #define        REC_CAPNUM(x)   ((x) & 0x07ff)
@@ -1528,7 +1529,7 @@ static bool parse_atom(struct parse_state *st safe)
                                ch = ch * 10 + st->patn[0] - '0';
                                st->patn += 1;
                        }
-                       add_cmd(st, REC_BACKREF | ch);
+                       add_cmd(st, REC_BACKREF_MAKE(ch));
                        return True;
                }
                add_cmd(st, REC_EOL);
@@ -1626,7 +1627,7 @@ static bool parse_atom(struct parse_state *st safe)
                                ch = ch * 10 + st->patn[1] - '0';
                                st->patn += 1;
                        }
-                       ch |= REC_BACKREF;
+                       ch = REC_BACKREF_MAKE(ch);
                        break;
                case 'd': ch = add_class_set(st, "digit", 1); break;
                case 'D': ch = add_class_set(st, "digit", 0); break;