In IEEE 1003.1-2008 [1] and earlier revisions, BRE/ERE grammar allows for
any character to be escaped, but "ORD_CHAR preceded by an unescaped
<backslash> character [gives undefined results]".
Historically, we've interpreted an escaped ordinary character as the
ordinary character itself. This becomes problematic when some extensions
give special meanings to an otherwise ordinary character
(e.g. GNU's \b, \s, \w), meaning we may have two different valid
interpretations of the same sequence.
To make this easier to deal with and given that the standard calls this
undefined, we should throw an error (EESCAPE) if we run into this scenario
to ease transition into a state where some escaped ordinaries are blessed
with a special meaning -- it will either error out or have extended
behavior, rather than have two entirely different versions of undefined
behavior that leave the consumer of regex(3) guessing as to what behavior
will be used or leaving them with false impressions.
This change bumps the symbol version of regcomp to FBSD_1.6 and provides the
old escape semantics for legacy applications, just in case one has an older
application that would immediately turn into a pumpkin because of an
extraneous escape that's embedded or otherwise critical to its operation.
This is the final piece needed before enhancing libregex with GNU extensions
and flipping the switch on bsdgrep.
[1] http://pubs.opengroup.org/onlinepubs/9699919799.2016edition/
PR: 229925 (exp-run, courtesy of antoine)
Differential Revision: https://reviews.freebsd.org/D10510
This fixes the obscure endless loop seen with case-insensitive
patterns containing characters in 128-255 range; originally
found running GNU grep test suite.
Our regex implementation being kludgy translates the characters
in case-insensitive pattern to bracket expression containing both
cases for the character and doesn't correctly handle the case when
original character is in bitmap and the other case is not, falling
into the endless loop going through in p_bracket(), ordinary(),
and bothcases().
Reducing the bitmap to 0-127 range for multibyte locales solves this
as none of these characters have other case mapping outside of bitmap.
We are also safe in the case when the original character outside of
bitmap has other case mapping in the bitmap (there are several of those
in our current ctype maps having unidirectional mapping into bitmap).
Reviewed by: bapt, kevans, pfg
Differential revision: https://reviews.freebsd.org/D18302
regcomp uses some libc internal collation bits that are not available in the
libregex context. It's easy enough to bring in the needed parts that can
work in a libregex world, so do so.
Pointy hat to: me
libc is set for WARNS=2, but the incoming libregex will use WARNS=6.
Sprinkle some casts and (void)bc's to alleviate the warnings that come along
with the higher WARNS level.
These 'bc' parameters could be outright removed, but as of right now they
will be used in some parts of libregex land. Silence the warnings instead
rather than flip-flopping.
Mainly focus on files that use BSD 3-Clause license.
The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
Special thanks to Wind River for providing access to "The Duke of
Highlander" tool: an older (2014) run over FreeBSD tree was useful as a
starting point.
The bug is an out-of-bounds read detected with address sanitizer that
happens when 'sp' in p_b_coll_elems() includes NUL byte[s], e.g. if it's
equal to "GS\x00". In that case len will be equal to 4, and the
strncmp(cp->name, sp, len) call will succeed when cp->name is "GS" but the
cp->name[len] == '\0' comparison will cause the read to go out-of-bounds.
Checking the length using strlen() instead eliminates the issue.
The bug was found in LLVM with oss-fuzz:
https://reviews.llvm.org/D39380
MFC after: 1 week
Obtained from: Vlad Tsyrklevich through posting on openbsd-tech
Currently, regex(3) exhibits the following wrong behavior as demonstrated
with sed:
- echo "a{1,2,3}b" | sed -r "s/{/_/" (1)
- echo "a{1,2,3}b" | sed "s/\}/_/" (2)
- echo "a{1,2,3}b" | sed -r "s/{}/_/" (3)
Cases (1) and (3) should throw errors but they actually succeed, and (2)
throws an error when it should match the literal '}'. The correct behavior
was decided by comparing to the behavior with the equivalent BRE (1)(3) or
ERE (2) and consulting POSIX, along with some reasonable evaluation.
Tests were also adjusted/added accordingly.
PR: 166861
Reviewed by: emaste, ngie, pfg
Approved by: emaste (mentor)
MFC after: never
Differential Revision: https://reviews.freebsd.org/D10315
An oversight in r320742 caused BREs to become sensitive to the branching operator prematurely, which caused
breakage in some limited situations -- namely, those that tried to use branching in a BRE. Most of these scenarios
had already been corrected beforehand to properly use gsed or grep for GNU extensions, so the damage is
slightly mitigated.
Reported by: antoine
Reported by: antoine
Approved by: emaste (mentor)
Differential Revision: https://reviews.freebsd.org/D11522
p_branch_empty was declared but never used due to an oversight. Use it as
designed, further comment on its return value.
Reported by: Jenkins (head-sparc64)
Reviewed by: emaste
Approved by: emaste (mentor)
MFC with: r320742
Differential Revision: https://reviews.freebsd.org/D11506
EREs closer together. Prepare for this and reduce the diff of libregex changes by
refactoring and combining the top-level parsers for EREs/BREs ahead of time.
Branching functionality has been split out to make it easier to follow the combined
version of the top-level parser. It may also be enabled in the parsing context to make
it easier when libregex enables branching for BREs.
A branching context was also added for the various branching functions and so that
BREs, for instance, can determine if they're the first expression in a chain of expressions
within the current branch and treat '*' as ordinary if so.
This should have no functional impact and negligible performance impact.
Reviewed by: cem, emaste, pfg
Approved by: emaste (mentor)
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D10920
When passed the invalid regular expression "a**", the error is
eventually detected and seterr() is called. It sets p->error
appropriatly and p->next and p->end to nuls which is a never used char
nuls[10] which is zeros due to .bss initialization. Unfortunatly,
p_ere_exp() and p_simp_re() both have fall through cases where they set
the error, decrement p->next and access it which means a read from what
ever .bss variable comes before nuls.
Found with regex_test:repet_multi and CHERI bounds checking.
Reviewed by: ngie, pfg, emaste
Obtained from: CheriBSD
Sponsored by: DARPA, AFRL
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D10541
Taking some hints from the regex variant in nvi(1) and higher-level
compiler warnings, update some types in our regex(3) implementation.
Joint work with: Kyle Evans
MFC after: 2 weeks
reallocarray(3) is a non portable extension that originated in OpenBSD.
Given that it is already in FreeBSD's libc it is useful for the cases
where reallocation involves a multiplication.
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D9955
Renumber cluase 4 to 3, per what everybody else did when BSD granted
them permission to remove clause 3. My insistance on keeping the same
numbering for legal reasons is too pedantic, so give up on that point.
Submitted by: Jan Schaumann <jschauma@stevens.edu>
Pull Request: https://github.com/freebsd/freebsd/pull/96
locale (which cause core dump) by removing whole 'table' argument
by which it passed.
2) Restore __collate_range_cmp() in __sccl().
3) Collating [a-z] range in regcomp() only for single bytes locales
(we can't do it now for other ones). In previous state only first 256
wchars are considered and all others are just silently dropped from the
range.
Instead of changing whole course to another POSIX-permitted way
for consistency and uniformity I decide to completely ignore missing
regex fucntionality and concentrace on fixing bugs in what we have now,
too many small obstacles instead, counting ports.
Only first 256 wide chars are considered currently, all other are just
dropped from the range. Proper implementation require reverse tables
database lookup, since objects are really big as max UTF-8 (1114112
code points), so just the same scanning as it was for 256 chars will
slow things down.
POSIX does not require collation for [a-z] type ranges and does not
prohibit it for non-POSIX locales. POSIX require collation for ranges
only for POSIX (or C) locale which is equal to ASCII and binary for
other chars, so we already have it.
No other *BSD implements collation for [a-z] type ranges.
Restore ABI compatibility with unused now __collate_range_cmp() which
is visible from outside (will be removed later).
When collation support was brought in, the second and third
arguments in __collate_range_cmp() were changed from int to
wchar_t, breaking the ABI. Change them to a "char" type which
makes more sense and keeps the ABI compatible.
Also introduce __wcollate_range_cmp() which does work with wide
characters. This function is used only internally in libc so
we don't export it. Use the new function in glob(3), fnmatch(3),
and regexec(3).
PR: 179721
Suggested by: ache. jilles
MFC after: 3 weeks (perhaps partial only)
Solaris and other OSs have support for \< and \> as word
delimiters in utilities like sed(1). These are useful to
have for general compatiblity with Solaris but should be
avoided for portability with other systems, including the
traditional BSDs.
Bump __FreeBSD_version as this is likely to affect some
userland utilities.
Reference:
https://www.illumos.org/issues/516
PR: bin/153257
Obtained from: Illumos
MFC after: 1 month
The code doesn't really benefit of using reallocf() in this case.
Also, the realloc() results being assigned temporary variable which
makes blind replacement with reallocf() mostly useless.
Pointed out by: stefanf, bde
Use of reallocf is useful in libraries as we are not certain the
application will exit after NULL.
This somewhat reduces portability but if since you are building
this as part of libc it is likely you have our non-standard
reallocf(3) already.
Reviewed by: ache
MFC after: 5 days
load of _l suffixed versions of various standard library functions that use
the global locale, making them take an explicit locale parameter. Also
adds support for per-thread locales. This work was funded by the FreeBSD
Foundation.
Please test any code you have that uses the C standard locale functions!
Reviewed by: das (gdtoa changes)
Approved by: dim (mentor)
multibyte character support:
- In CHadd(), avoid writing past the end of the character set bitmap when
the opposite-case counterpart of wide characters with values less than
NC have values greater than or equal to NC.
- In CHaddtype(), fix a braino that caused alphabetic characters to be
added to all character classes! (but only with REG_ICASE)
PR: 71367
idea is that we perform multibyte->wide character conversion while parsing
and compiling, then convert byte sequences to wide characters when they're
needed for comparison and stepping through the string during execution.
As with tr(1), the main complication is to efficiently represent sets of
characters in bracket expressions. The old bitmap representation is replaced
by a bitmap for the first 256 characters combined with a vector of individual
wide characters, a vector of character ranges (for [A-Z] etc.), and a vector
of character classes (for [[:alpha:]] etc.).
One other point of interest is that although the Boyer-Moore algorithm had
to be disabled in the general multibyte case, it is still enabled for UTF-8
because of its self-synchronizing nature. This greatly speeds up matching
by reducing the number of multibyte conversions that need to be done.
Only warnings that could be fixed without changing the generated object
code and without restructuring the source code have been handled.
Reviewed by: /sbin/md5
access an array beyond it's length. This only happens in the last iteration of
a loop, and the value fetched is not used then, so the bug is a relatively
innocent one. Fix this by not fetching any value on the last iteration of said
loop.
Submitted by: MKI <mki@mozone.net>
MFC after: 1 week
of the processing of the recursion, "scan" would be pointing to O_CH
(or O_QUEST), which would then be interpreted as being the end character
for altoffset().
We avoid this by properly increasing scan before leaving the switch.
Without this, something like (a?b?)?cc would result in a g->moffset of
1 instead of 2.
I added a case to the soon-to-be-imported regex(3) test code to catch
this error.