summaryrefslogtreecommitdiffstats
path: root/regex.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-04-17 07:29:49 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-04-17 07:29:49 -0700
commit8daa2d98fe335ae2a9ec6a074d3a2c4037dcd79c (patch)
tree4788374a97ecc482d59c67aba71bf7f83a3ffd03 /regex.c
parentd3af854c269878f9a8ee2b383b43d61d2cd914fe (diff)
downloadtxr-8daa2d98fe335ae2a9ec6a074d3a2c4037dcd79c.tar.gz
txr-8daa2d98fe335ae2a9ec6a074d3a2c4037dcd79c.tar.bz2
txr-8daa2d98fe335ae2a9ec6a074d3a2c4037dcd79c.zip
regex: duplicate character range crash fix.
* regex.c (L1_fill_range, L2_fill_range, L3_fill_range): Bug: when the arguments ch0 and ch1 indicate that a block is to be filled entirely, we assume that the pointer is either null or else a pointer to an allocated block, either of which we can free and replace with a -1 pointer to indicate a full block. However the pointer may already be -1, in which case we wrongly pass that to free(). We must check for it.
Diffstat (limited to 'regex.c')
-rw-r--r--regex.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/regex.c b/regex.c
index 1fc90fa5..936269c6 100644
--- a/regex.c
+++ b/regex.c
@@ -320,8 +320,10 @@ static void L1_fill_range(cset_L1_t *L1, wchar_t ch0, wchar_t ch1)
cset_L0_t *L0;
if (i1 > i10 && i1 < i11) {
- free((*L1)[i1]);
- (*L1)[i1] = coerce(cset_L0_t *, -1);
+ if ((*L1)[i1] != coerce(cset_L0_t *, -1)) {
+ free((*L1)[i1]);
+ (*L1)[i1] = coerce(cset_L0_t *, -1);
+ }
continue;
} else if (i10 == i11) {
c0 = ch0;
@@ -401,8 +403,10 @@ static void L2_fill_range(cset_L2_t *L2, wchar_t ch0, wchar_t ch1)
cset_L1_t *L1;
if (i2 > i20 && i2 < i21) {
- free((*L2)[i2]);
- (*L2)[i2] = coerce(cset_L1_t *, -1);
+ if ((*L2)[i2] != coerce(cset_L1_t *, -1)) {
+ free((*L2)[i2]);
+ (*L2)[i2] = coerce(cset_L1_t *, -1);
+ }
continue;
} else if (i20 == i21) {
c0 = ch0;
@@ -473,8 +477,10 @@ static void L3_fill_range(cset_L3_t *L3, wchar_t ch0, wchar_t ch1)
cset_L2_t *L2;
if (i3 > i30 && i3 < i31) {
- free((*L3)[i3]);
- (*L3)[i3] = coerce(cset_L2_t *, -1);
+ if ((*L3)[i3] != coerce(cset_L2_t *, -1)) {
+ free((*L3)[i3]);
+ (*L3)[i3] = coerce(cset_L2_t *, -1);
+ }
continue;
} else if (i30 == i31) {
c0 = ch0;