From 27f0a62a27d82a3ee787efab59ac502637b60def Mon Sep 17 00:00:00 2001 From: wenlong_12 Date: Thu, 20 Apr 2023 14:47:54 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=20=20=20=20=20RE2=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8D=87=E7=BA=A7:openEuler:re2=20=20=20=20=20=20Signed-off-by?= =?UTF-8?q?:=20wenlong=5F12=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wenlong_12 --- BUILD | 20 +- CMakeLists.txt | 39 +- Makefile | 74 +- README | 8 +- WORKSPACE | 8 - doc/mksyntaxgo | 3 +- doc/syntax.html | 278 ++++--- doc/syntax.txt | 9 + libre2.map | 2 + libre2.symbols | 3 + libre2.symbols.darwin | 3 + re2/bitmap256.h | 7 +- re2/bitstate.cc | 36 +- re2/compile.cc | 296 ++++---- re2/dfa.cc | 266 +++---- re2/filtered_re2.cc | 20 +- re2/filtered_re2.h | 41 +- re2/fuzzing/compiler-rt/LICENSE | 219 ++++++ .../include/fuzzer/FuzzedDataProvider.h | 305 ++++++++ re2/fuzzing/re2_fuzzer.cc | 240 ++++-- re2/make_perl_groups.pl | 2 +- re2/mimics_pcre.cc | 30 +- re2/nfa.cc | 154 ++-- re2/onepass.cc | 4 +- re2/parse.cc | 81 +- re2/perl_groups.cc | 68 +- re2/pod_array.h | 2 +- re2/prefilter.cc | 5 +- re2/prefilter_tree.cc | 4 +- re2/prog.cc | 321 +++++++- re2/prog.h | 78 +- re2/re2.cc | 408 ++++++---- re2/re2.h | 416 +++++----- re2/regexp.cc | 152 ++-- re2/regexp.h | 17 +- re2/set.cc | 47 +- re2/set.h | 13 +- re2/simplify.cc | 24 +- re2/testing/backtrack.cc | 37 +- re2/testing/charclass_test.cc | 4 +- re2/testing/compile_test.cc | 126 +-- re2/testing/dfa_test.cc | 68 +- re2/testing/exhaustive_tester.cc | 4 +- re2/testing/filtered_re2_test.cc | 46 ++ re2/testing/null_walker.cc | 13 +- re2/testing/parse_test.cc | 1 + re2/testing/re2_arg_test.cc | 25 + re2/testing/re2_test.cc | 116 +-- re2/testing/regexp_benchmark.cc | 263 +++---- re2/testing/required_prefix_test.cc | 141 +++- re2/testing/search_test.cc | 2 + re2/testing/set_test.cc | 26 + re2/testing/string_generator.cc | 27 + re2/testing/string_generator.h | 13 + re2/testing/tester.cc | 37 +- re2/tostring.cc | 2 +- re2/unicode.py | 2 +- re2/unicode_casefold.cc | 40 +- re2/unicode_groups.cc | 717 ++++++++++++------ re2/walker-inl.h | 31 +- testinstall.cc | 35 +- util/mutex.h | 23 +- util/pcre.cc | 4 +- util/pcre.h | 6 +- 64 files changed, 3626 insertions(+), 1886 deletions(-) create mode 100644 re2/fuzzing/compiler-rt/LICENSE create mode 100644 re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h diff --git a/BUILD b/BUILD index 480646f..00330b6 100644 --- a/BUILD +++ b/BUILD @@ -9,22 +9,20 @@ licenses(["notice"]) exports_files(["LICENSE"]) config_setting( - name = "darwin", + name = "macos", values = {"cpu": "darwin"}, ) config_setting( - name = "windows", - values = {"cpu": "x64_windows"}, + name = "wasm", + values = {"cpu": "wasm32"}, ) config_setting( - name = "windows_msvc", - values = {"cpu": "x64_windows_msvc"}, + name = "windows", + values = {"cpu": "x64_windows"}, ) -load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") - cc_library( name = "re2", srcs = [ @@ -75,17 +73,17 @@ cc_library( "re2/stringpiece.h", ], copts = select({ + ":wasm": [], ":windows": [], - ":windows_msvc": [], "//conditions:default": ["-pthread"], }), linkopts = select({ - # Darwin doesn't need `-pthread' when linking and it appears that + # macOS doesn't need `-pthread' when linking and it appears that # older versions of Clang will warn about the unused command line # argument, so just don't pass it. - ":darwin": [], + ":macos": [], + ":wasm": [], ":windows": [], - ":windows_msvc": [], "//conditions:default": ["-pthread"], }), visibility = ["//visibility:public"], diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c980f0..fcd3870 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,14 +5,15 @@ # Old enough to support Ubuntu Xenial. cmake_minimum_required(VERSION 3.5.1) -if(POLICY CMP0048) - cmake_policy(SET CMP0048 NEW) -endif() - project(RE2 CXX) include(CTest) include(GNUInstallDirs) +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +endif() + option(BUILD_SHARED_LIBS "build shared libraries" OFF) option(USEPCRE "use PCRE in tests and benchmarks" OFF) @@ -20,6 +21,10 @@ option(USEPCRE "use PCRE in tests and benchmarks" OFF) # so we provide an option similar to BUILD_TESTING, but just for RE2. option(RE2_BUILD_TESTING "enable testing for RE2" ON) +# ABI version +# http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html +set(SONAME 9) + set(EXTRA_TARGET_LINK_LIBRARIES) if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") @@ -36,19 +41,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # Without a byte order mark (BOM), Visual Studio assumes that the source # file is encoded using the current user code page, so we specify UTF-8. add_compile_options(/utf-8) -elseif(CYGWIN OR MINGW) - # See https://stackoverflow.com/questions/38139631 for details. - add_compile_options(-std=gnu++11) -elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - add_compile_options(-std=c++11) endif() if(WIN32) add_definitions(-DUNICODE -D_UNICODE -DSTRICT -DNOMINMAX) add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) elseif(UNIX) - add_compile_options(-pthread) - list(APPEND EXTRA_TARGET_LINK_LIBRARIES -pthread) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) endif() if(USEPCRE) @@ -56,8 +56,6 @@ if(USEPCRE) list(APPEND EXTRA_TARGET_LINK_LIBRARIES pcre) endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - set(RE2_SOURCES re2/bitstate.cc re2/compile.cc @@ -84,8 +82,14 @@ set(RE2_SOURCES ) add_library(re2 ${RE2_SOURCES}) +target_include_directories(re2 PUBLIC $) +set_target_properties(re2 PROPERTIES SOVERSION ${SONAME} VERSION ${SONAME}.0.0) add_library(re2::re2 ALIAS re2) +if(UNIX) + target_link_libraries(re2 PUBLIC Threads::Threads) +endif() + if(RE2_BUILD_TESTING) set(TESTING_SOURCES re2/testing/backtrack.cc @@ -99,6 +103,7 @@ if(RE2_BUILD_TESTING) ) add_library(testing STATIC ${TESTING_SOURCES}) + target_link_libraries(testing PUBLIC re2) set(TEST_TARGETS charclass_test @@ -130,14 +135,14 @@ if(RE2_BUILD_TESTING) foreach(target ${TEST_TARGETS}) add_executable(${target} re2/testing/${target}.cc util/test.cc) - target_link_libraries(${target} testing re2 ${EXTRA_TARGET_LINK_LIBRARIES}) + target_link_libraries(${target} testing ${EXTRA_TARGET_LINK_LIBRARIES}) add_test(NAME ${target} COMMAND ${target}) - endforeach(target) + endforeach() foreach(target ${BENCHMARK_TARGETS}) add_executable(${target} re2/testing/${target}.cc util/benchmark.cc) - target_link_libraries(${target} testing re2 ${EXTRA_TARGET_LINK_LIBRARIES}) - endforeach(target) + target_link_libraries(${target} testing ${EXTRA_TARGET_LINK_LIBRARIES}) + endforeach() endif() set(RE2_HEADERS diff --git a/Makefile b/Makefile index 15d7824..2409093 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ endif # ABI version # http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html -SONAME=0 +SONAME=9 # To rebuild the Tables generated by Perl and Python scripts (requires Internet # access for Unicode data), uncomment the following line: @@ -55,7 +55,7 @@ ifeq ($(shell uname),Darwin) SOEXT=dylib SOEXTVER=$(SONAME).$(SOEXT) SOEXTVER00=$(SONAME).0.0.$(SOEXT) -MAKE_SHARED_LIBRARY=$(CXX) -dynamiclib -Wl,-install_name,$(libdir)/libre2.$(SOEXTVER),-exported_symbols_list,libre2.symbols.darwin $(RE2_LDFLAGS) $(LDFLAGS) +MAKE_SHARED_LIBRARY=$(CXX) -dynamiclib -Wl,-compatibility_version,$(SONAME),-current_version,$(SONAME).0.0,-install_name,$(libdir)/libre2.$(SOEXTVER),-exported_symbols_list,libre2.symbols.darwin $(RE2_LDFLAGS) $(LDFLAGS) else ifeq ($(shell uname),SunOS) SOEXT=so SOEXTVER=$(SOEXT).$(SONAME) @@ -68,6 +68,7 @@ SOEXTVER00=$(SOEXT).$(SONAME).0.0 MAKE_SHARED_LIBRARY=$(CXX) -shared -Wl,-soname,libre2.$(SOEXTVER),--version-script,libre2.symbols $(RE2_LDFLAGS) $(LDFLAGS) endif +.PHONY: all all: obj/libre2.a obj/so/libre2.$(SOEXT) INSTALL_HFILES=\ @@ -176,40 +177,49 @@ DTESTOFILES=$(patsubst obj/%,obj/dbg/%,$(TESTOFILES)) DTESTS=$(patsubst obj/%,obj/dbg/%,$(TESTS)) DBIGTESTS=$(patsubst obj/%,obj/dbg/%,$(BIGTESTS)) +.PRECIOUS: obj/%.o obj/%.o: %.cc $(HFILES) @mkdir -p $$(dirname $@) $(CXX) -c -o $@ $(CPPFLAGS) $(RE2_CXXFLAGS) $(CXXFLAGS) -DNDEBUG $*.cc +.PRECIOUS: obj/dbg/%.o obj/dbg/%.o: %.cc $(HFILES) @mkdir -p $$(dirname $@) $(CXX) -c -o $@ $(CPPFLAGS) $(RE2_CXXFLAGS) $(CXXFLAGS) $*.cc +.PRECIOUS: obj/so/%.o obj/so/%.o: %.cc $(HFILES) @mkdir -p $$(dirname $@) $(CXX) -c -o $@ -fPIC $(CPPFLAGS) $(RE2_CXXFLAGS) $(CXXFLAGS) -DNDEBUG $*.cc +.PRECIOUS: obj/libre2.a obj/libre2.a: $(OFILES) @mkdir -p obj $(AR) $(ARFLAGS) obj/libre2.a $(OFILES) +.PRECIOUS: obj/dbg/libre2.a obj/dbg/libre2.a: $(DOFILES) @mkdir -p obj/dbg $(AR) $(ARFLAGS) obj/dbg/libre2.a $(DOFILES) -obj/so/libre2.$(SOEXT): $(SOFILES) +.PRECIOUS: obj/so/libre2.$(SOEXT) +obj/so/libre2.$(SOEXT): $(SOFILES) libre2.symbols libre2.symbols.darwin @mkdir -p obj/so $(MAKE_SHARED_LIBRARY) -o obj/so/libre2.$(SOEXTVER) $(SOFILES) ln -sf libre2.$(SOEXTVER) $@ +.PRECIOUS: obj/dbg/test/% obj/dbg/test/%: obj/dbg/libre2.a obj/dbg/re2/testing/%.o $(DTESTOFILES) obj/dbg/util/test.o @mkdir -p obj/dbg/test $(CXX) -o $@ obj/dbg/re2/testing/$*.o $(DTESTOFILES) obj/dbg/util/test.o obj/dbg/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) +.PRECIOUS: obj/test/% obj/test/%: obj/libre2.a obj/re2/testing/%.o $(TESTOFILES) obj/util/test.o @mkdir -p obj/test $(CXX) -o $@ obj/re2/testing/$*.o $(TESTOFILES) obj/util/test.o obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) # Test the shared lib, falling back to the static lib for private symbols +.PRECIOUS: obj/so/test/% obj/so/test/%: obj/so/libre2.$(SOEXT) obj/libre2.a obj/re2/testing/%.o $(TESTOFILES) obj/util/test.o @mkdir -p obj/so/test $(CXX) -o $@ obj/re2/testing/$*.o $(TESTOFILES) obj/util/test.o -Lobj/so -lre2 obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) @@ -223,69 +233,100 @@ obj/test/regexp_benchmark: obj/libre2.a obj/re2/testing/regexp_benchmark.o $(TES # is simply a way to check that the target builds and then to run it against a # fixed set of inputs. To perform real fuzzing, refer to the documentation for # libFuzzer (llvm.org/docs/LibFuzzer.html) and AFL (lcamtuf.coredump.cx/afl/). +obj/test/re2_fuzzer: CXXFLAGS:=-I./re2/fuzzing/compiler-rt/include $(CXXFLAGS) obj/test/re2_fuzzer: obj/libre2.a obj/re2/fuzzing/re2_fuzzer.o obj/util/fuzz.o @mkdir -p obj/test $(CXX) -o $@ obj/re2/fuzzing/re2_fuzzer.o obj/util/fuzz.o obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) ifdef REBUILD_TABLES +.PRECIOUS: re2/perl_groups.cc re2/perl_groups.cc: re2/make_perl_groups.pl perl $< > $@ -re2/unicode_%.cc: re2/make_unicode_%.py - python $< > $@ - -.PRECIOUS: re2/perl_groups.cc re2/unicode_casefold.cc re2/unicode_groups.cc +.PRECIOUS: re2/unicode_%.cc +re2/unicode_%.cc: re2/make_unicode_%.py re2/unicode.py + python3 $< > $@ endif +.PHONY: distclean distclean: clean rm -f re2/perl_groups.cc re2/unicode_casefold.cc re2/unicode_groups.cc +.PHONY: clean clean: rm -rf obj rm -f re2/*.pyc +.PHONY: testofiles testofiles: $(TESTOFILES) +.PHONY: test test: $(DTESTS) $(TESTS) $(STESTS) debug-test static-test shared-test +.PHONY: debug-test debug-test: $(DTESTS) @./runtests $(DTESTS) +.PHONY: static-test static-test: $(TESTS) @./runtests $(TESTS) +.PHONY: shared-test shared-test: $(STESTS) @./runtests -shared-library-path obj/so $(STESTS) +.PHONY: debug-bigtest debug-bigtest: $(DTESTS) $(DBIGTESTS) @./runtests $(DTESTS) $(DBIGTESTS) +.PHONY: static-bigtest static-bigtest: $(TESTS) $(BIGTESTS) @./runtests $(TESTS) $(BIGTESTS) +.PHONY: shared-bigtest shared-bigtest: $(STESTS) $(SBIGTESTS) @./runtests -shared-library-path obj/so $(STESTS) $(SBIGTESTS) +.PHONY: benchmark benchmark: obj/test/regexp_benchmark +.PHONY: fuzz fuzz: obj/test/re2_fuzzer -install: obj/libre2.a obj/so/libre2.$(SOEXT) - mkdir -p $(DESTDIR)$(includedir)/re2 $(DESTDIR)$(libdir)/pkgconfig - $(INSTALL_DATA) $(INSTALL_HFILES) $(DESTDIR)$(includedir)/re2 +.PHONY: install +install: static-install shared-install + +.PHONY: static +static: obj/libre2.a + +.PHONY: static-install +static-install: obj/libre2.a common-install $(INSTALL) obj/libre2.a $(DESTDIR)$(libdir)/libre2.a + +.PHONY: shared +shared: obj/so/libre2.$(SOEXT) + +.PHONY: shared-install +shared-install: obj/so/libre2.$(SOEXT) common-install $(INSTALL) obj/so/libre2.$(SOEXT) $(DESTDIR)$(libdir)/libre2.$(SOEXTVER00) ln -sf libre2.$(SOEXTVER00) $(DESTDIR)$(libdir)/libre2.$(SOEXTVER) ln -sf libre2.$(SOEXTVER00) $(DESTDIR)$(libdir)/libre2.$(SOEXT) + +.PHONY: common-install +common-install: + mkdir -p $(DESTDIR)$(includedir)/re2 $(DESTDIR)$(libdir)/pkgconfig + $(INSTALL_DATA) $(INSTALL_HFILES) $(DESTDIR)$(includedir)/re2 $(INSTALL_DATA) re2.pc $(DESTDIR)$(libdir)/pkgconfig/re2.pc $(SED_INPLACE) -e "s#@includedir@#$(includedir)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc $(SED_INPLACE) -e "s#@libdir@#$(libdir)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc +.PHONY: testinstall testinstall: static-testinstall shared-testinstall @echo @echo Install tests passed. @echo +.PHONY: static-testinstall static-testinstall: CXXFLAGS:=-std=c++11 -pthread -I$(DESTDIR)$(includedir) $(CXXFLAGS) static-testinstall: LDFLAGS:=-pthread -L$(DESTDIR)$(libdir) -l:libre2.a $(LDICU) $(LDFLAGS) static-testinstall: @@ -300,6 +341,7 @@ else obj/testinstall endif +.PHONY: shared-testinstall shared-testinstall: CXXFLAGS:=-std=c++11 -pthread -I$(DESTDIR)$(includedir) $(CXXFLAGS) shared-testinstall: LDFLAGS:=-pthread -L$(DESTDIR)$(libdir) -lre2 $(LDICU) $(LDFLAGS) shared-testinstall: @@ -312,19 +354,14 @@ else LD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(LD_LIBRARY_PATH)" obj/testinstall endif +.PHONY: benchlog benchlog: obj/test/regexp_benchmark (echo '==BENCHMARK==' `hostname` `date`; \ (uname -a; $(CXX) --version; git rev-parse --short HEAD; file obj/test/regexp_benchmark) | sed 's/^/# /'; \ echo; \ ./obj/test/regexp_benchmark 'PCRE|RE2') | tee -a benchlog.$$(hostname | sed 's/\..*//') -# Keep gmake from deleting intermediate files it creates. -# This makes repeated builds faster and preserves debug info on OS X. - -.PRECIOUS: obj/%.o obj/dbg/%.o obj/so/%.o obj/libre2.a \ - obj/dbg/libre2.a obj/so/libre2.a \ - obj/test/% obj/so/test/% obj/dbg/test/% - +.PHONY: log log: $(MAKE) clean $(MAKE) CXXFLAGS="$(CXXFLAGS) -DLOGGING=1" \ @@ -340,6 +377,3 @@ log: echo '#' RE2 basic search tests built by make $@ >re2-search.txt echo '#' $$(date) >>re2-search.txt obj/test/search_test |grep -v '^PASS$$' >>re2-search.txt - -x: x.cc obj/libre2.a - g++ -I. -o x x.cc obj/libre2.a diff --git a/README b/README index d1ef431..caee6af 100644 --- a/README +++ b/README @@ -27,12 +27,16 @@ under the BSD-style license found in the LICENSE file. RE2's native language is C++. +The Python wrapper is at https://github.com/google/re2/tree/abseil/python +and on PyPI (https://pypi.org/project/google-re2/). + A C wrapper is at https://github.com/marcomaggi/cre2/. +A D wrapper is at https://github.com/ShigekiKarita/re2d/ and on DUB (code.dlang.org). An Erlang wrapper is at https://github.com/dukesoferl/re2/ and on Hex (hex.pm). An Inferno wrapper is at https://github.com/powerman/inferno-re2/. A Node.js wrapper is at https://github.com/uhop/node-re2/ and on NPM (npmjs.com). An OCaml wrapper is at https://github.com/janestreet/re2/ and on OPAM (opam.ocaml.org). A Perl wrapper is at https://github.com/dgl/re-engine-RE2/ and on CPAN (cpan.org). -A Python wrapper is at https://github.com/facebook/pyre2/ and on PyPI (pypi.org). -An R wrapper is at https://github.com/qinwf/re2r/ and on CRAN (cran.r-project.org). +An R wrapper is at https://github.com/girishji/re2/ and on CRAN (cran.r-project.org). A Ruby wrapper is at https://github.com/mudge/re2/ and on RubyGems (rubygems.org). +A WebAssembly wrapper is at https://github.com/google/re2-wasm/ and on NPM (npmjs.com). diff --git a/WORKSPACE b/WORKSPACE index 484abfe..b35619c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -5,11 +5,3 @@ # Bazel (http://bazel.io/) WORKSPACE file for RE2. workspace(name = "com_googlesource_code_re2") - -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "rules_cc", - strip_prefix = "rules_cc-master", - urls = ["https://github.com/bazelbuild/rules_cc/archive/master.zip"], -) diff --git a/doc/mksyntaxgo b/doc/mksyntaxgo index caad9b6..d30d281 100755 --- a/doc/mksyntaxgo +++ b/doc/mksyntaxgo @@ -15,7 +15,7 @@ sam -d $out <<'!' ,s/\n\n\n+/\n\n/g ,x/(^.* .*\n)+/ | awk -F' ' '{printf(" %-14s %s\n", $1, $2)}' 1,2c -// Copyright 2012 The Go Authors. All rights reserved. +// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -33,6 +33,7 @@ Parts of the syntax can be disabled by passing alternate flags to Parse. . $a +Unicode character classes are those in unicode.Categories and unicode.Scripts. */ package syntax . diff --git a/doc/syntax.html b/doc/syntax.html index aa08b11..f0e0138 100644 --- a/doc/syntax.html +++ b/doc/syntax.html @@ -47,6 +47,10 @@ x{-n}(≡ x{n}?) VIM x=(≡ x?) VIM +Implementation restriction: The counting forms x{n,m}, x{n,}, and x{n} +reject forms that create a minimum or maximum repetition count above 1000. +Unlimited repetitions are not subject to this restriction. + Possessive repetitions: x*+zero or more x, possessive x++one or more x, possessive @@ -56,10 +60,10 @@ x{n}+exactly n x, possessive Grouping: -(re)numbered capturing group -(?P<name>re)named & numbered capturing group -(?<name>re)named & numbered capturing group -(?'name're)named & numbered capturing group +(re)numbered capturing group (submatch) +(?P<name>re)named & numbered capturing group (submatch) +(?<name>re)named & numbered capturing group (submatch) +(?'name're)named & numbered capturing group (submatch) (?:re)non-capturing group (?flags)set flags within current group; non-capturing (?flags:re)set flags during re; non-capturing @@ -80,8 +84,8 @@ ^at beginning of text or line (m=true) $at end of text (like \z not \Z) or line (m=true) \Aat beginning of text -\bat word boundary (\w on one side and \W, \A, or \z on the other) -\Bnot a word boundary +\bat ASCII word boundary (\w on one side and \W, \A, or \z on the other) +\Bnot at ASCII word boundary \Gat beginning of subtext being searched PCRE \Gat end of last match PERL \Zat end of text, or before newline at end of text @@ -166,7 +170,7 @@ [\p{Name}]named Unicode property inside character class (≡ \p{Name}) [^\p{Name}]named Unicode property inside negated character class (≡ \P{Name}) -Perl character classes: +Perl character classes (all ASCII-only): \ddigits (≡ [0-9]) \Dnot digits (≡ [^0-9]) \swhitespace (≡ [\t\n\f\r ]) @@ -237,105 +241,167 @@ Zsspace separator Unicode character class names--scripts: -ArabicArabic -ArmenianArmenian -BalineseBalinese -BamumBamum -BatakBatak -BengaliBengali -BopomofoBopomofo -BrahmiBrahmi -BrailleBraille -BugineseBuginese -BuhidBuhid -Canadian_AboriginalCanadian Aboriginal -CarianCarian -ChakmaChakma -ChamCham -CherokeeCherokee -Commoncharacters not specific to one script -CopticCoptic -CuneiformCuneiform -CypriotCypriot -CyrillicCyrillic -DeseretDeseret -DevanagariDevanagari -Egyptian_HieroglyphsEgyptian Hieroglyphs -EthiopicEthiopic -GeorgianGeorgian -GlagoliticGlagolitic -GothicGothic -GreekGreek -GujaratiGujarati -GurmukhiGurmukhi -HanHan -HangulHangul -HanunooHanunoo -HebrewHebrew -HiraganaHiragana -Imperial_AramaicImperial Aramaic -Inheritedinherit script from previous character -Inscriptional_PahlaviInscriptional Pahlavi -Inscriptional_ParthianInscriptional Parthian -JavaneseJavanese -KaithiKaithi -KannadaKannada -KatakanaKatakana -Kayah_LiKayah Li -KharoshthiKharoshthi -KhmerKhmer -LaoLao -LatinLatin -LepchaLepcha -LimbuLimbu -Linear_BLinear B -LycianLycian -LydianLydian -MalayalamMalayalam -MandaicMandaic -Meetei_MayekMeetei Mayek -Meroitic_CursiveMeroitic Cursive -Meroitic_HieroglyphsMeroitic Hieroglyphs -MiaoMiao -MongolianMongolian -MyanmarMyanmar -New_Tai_LueNew Tai Lue (aka Simplified Tai Lue) -NkoNko -OghamOgham -Ol_ChikiOl Chiki -Old_ItalicOld Italic -Old_PersianOld Persian -Old_South_ArabianOld South Arabian -Old_TurkicOld Turkic -OriyaOriya -OsmanyaOsmanya -Phags_Pa'Phags Pa -PhoenicianPhoenician -RejangRejang -RunicRunic -SaurashtraSaurashtra -SharadaSharada -ShavianShavian -SinhalaSinhala -Sora_SompengSora Sompeng -SundaneseSundanese -Syloti_NagriSyloti Nagri -SyriacSyriac -TagalogTagalog -TagbanwaTagbanwa -Tai_LeTai Le -Tai_ThamTai Tham -Tai_VietTai Viet -TakriTakri -TamilTamil -TeluguTelugu -ThaanaThaana -ThaiThai -TibetanTibetan -TifinaghTifinagh -UgariticUgaritic -VaiVai -YiYi +Adlam +Ahom +Anatolian_Hieroglyphs +Arabic +Armenian +Avestan +Balinese +Bamum +Bassa_Vah +Batak +Bengali +Bhaiksuki +Bopomofo +Brahmi +Braille +Buginese +Buhid +Canadian_Aboriginal +Carian +Caucasian_Albanian +Chakma +Cham +Cherokee +Chorasmian +Common +Coptic +Cuneiform +Cypriot +Cypro_Minoan +Cyrillic +Deseret +Devanagari +Dives_Akuru +Dogra +Duployan +Egyptian_Hieroglyphs +Elbasan +Elymaic +Ethiopic +Georgian +Glagolitic +Gothic +Grantha +Greek +Gujarati +Gunjala_Gondi +Gurmukhi +Han +Hangul +Hanifi_Rohingya +Hanunoo +Hatran +Hebrew +Hiragana +Imperial_Aramaic +Inherited +Inscriptional_Pahlavi +Inscriptional_Parthian +Javanese +Kaithi +Kannada +Katakana +Kayah_Li +Kharoshthi +Khitan_Small_Script +Khmer +Khojki +Khudawadi +Lao +Latin +Lepcha +Limbu +Linear_A +Linear_B +Lisu +Lycian +Lydian +Mahajani +Makasar +Malayalam +Mandaic +Manichaean +Marchen +Masaram_Gondi +Medefaidrin +Meetei_Mayek +Mende_Kikakui +Meroitic_Cursive +Meroitic_Hieroglyphs +Miao +Modi +Mongolian +Mro +Multani +Myanmar +Nabataean +Nandinagari +New_Tai_Lue +Newa +Nko +Nushu +Nyiakeng_Puachue_Hmong +Ogham +Ol_Chiki +Old_Hungarian +Old_Italic +Old_North_Arabian +Old_Permic +Old_Persian +Old_Sogdian +Old_South_Arabian +Old_Turkic +Old_Uyghur +Oriya +Osage +Osmanya +Pahawh_Hmong +Palmyrene +Pau_Cin_Hau +Phags_Pa +Phoenician +Psalter_Pahlavi +Rejang +Runic +Samaritan +Saurashtra +Sharada +Shavian +Siddham +SignWriting +Sinhala +Sogdian +Sora_Sompeng +Soyombo +Sundanese +Syloti_Nagri +Syriac +Tagalog +Tagbanwa +Tai_Le +Tai_Tham +Tai_Viet +Takri +Tamil +Tangsa +Tangut +Telugu +Thaana +Thai +Tibetan +Tifinagh +Tirhuta +Toto +Ugaritic +Vai +Vithkuqi +Wancho +Warang_Citi +Yezidi +Yi +Zanabazar_Square Vim character classes: \iidentifier character VIM diff --git a/doc/syntax.txt b/doc/syntax.txt index cb04bbf..c12a482 100644 --- a/doc/syntax.txt +++ b/doc/syntax.txt @@ -253,13 +253,16 @@ Caucasian_Albanian Chakma Cham Cherokee +Chorasmian Common Coptic Cuneiform Cypriot +Cypro_Minoan Cyrillic Deseret Devanagari +Dives_Akuru Dogra Duployan Egyptian_Hieroglyphs @@ -291,6 +294,7 @@ Kannada Katakana Kayah_Li Kharoshthi +Khitan_Small_Script Khmer Khojki Khudawadi @@ -338,6 +342,7 @@ Old_Persian Old_Sogdian Old_South_Arabian Old_Turkic +Old_Uyghur Oriya Osage Osmanya @@ -369,6 +374,7 @@ Tai_Tham Tai_Viet Takri Tamil +Tangsa Tangut Telugu Thaana @@ -376,10 +382,13 @@ Thai Tibetan Tifinagh Tirhuta +Toto Ugaritic Vai +Vithkuqi Wancho Warang_Citi +Yezidi Yi Zanabazar_Square diff --git a/libre2.map b/libre2.map index 5287893..cf15d15 100644 --- a/libre2.map +++ b/libre2.map @@ -4,6 +4,8 @@ "re2::RE2::~RE2()"; "re2::RE2::RE2(re2::StringPiece const&, re2::RE2::Options const&)"; "re2::RE2::FullMatchN(re2::StringPiece const&, re2::RE2 const&, re2::RE2::Arg const* const*, int)"; + "re2::RE2::GlobalReplace(std::__h::basic_string, std::__h::allocator >*, re2::RE2 const&, re2::StringPiece const&)"; + "re2::RE2::RE2(std::__h::basic_string, std::__h::allocator > const&)"; }; local: *; diff --git a/libre2.symbols b/libre2.symbols index 8308b64..93b71b4 100644 --- a/libre2.symbols +++ b/libre2.symbols @@ -11,6 +11,9 @@ # re2::FilteredRE2* _ZN3re211FilteredRE2*; _ZNK3re211FilteredRE2*; + # re2::re2_internal* + _ZN3re212re2_internal*; + _ZNK3re212re2_internal*; local: *; }; diff --git a/libre2.symbols.darwin b/libre2.symbols.darwin index 31e8c52..41ac96f 100644 --- a/libre2.symbols.darwin +++ b/libre2.symbols.darwin @@ -10,3 +10,6 @@ __ZN3re2ls* # re2::FilteredRE2* __ZN3re211FilteredRE2* __ZNK3re211FilteredRE2* +# re2::re2_internal* +__ZN3re212re2_internal* +__ZNK3re212re2_internal* diff --git a/re2/bitmap256.h b/re2/bitmap256.h index f649b4c..4899379 100644 --- a/re2/bitmap256.h +++ b/re2/bitmap256.h @@ -32,7 +32,7 @@ class Bitmap256 { DCHECK_GE(c, 0); DCHECK_LE(c, 255); - return (words_[c / 64] & (1ULL << (c % 64))) != 0; + return (words_[c / 64] & (uint64_t{1} << (c % 64))) != 0; } // Sets the bit with index c. @@ -40,7 +40,7 @@ class Bitmap256 { DCHECK_GE(c, 0); DCHECK_LE(c, 255); - words_[c / 64] |= (1ULL << (c % 64)); + words_[c / 64] |= (uint64_t{1} << (c % 64)); } // Finds the next non-zero bit with index >= c. @@ -51,7 +51,6 @@ class Bitmap256 { // Finds the least significant non-zero bit in n. static int FindLSBSet(uint64_t n) { DCHECK_NE(n, 0); - #if defined(__GNUC__) return __builtin_ctzll(n); #elif defined(_MSC_VER) && defined(_M_X64) @@ -89,7 +88,7 @@ int Bitmap256::FindNextSetBit(int c) const { // Check the word that contains the bit. Mask out any lower bits. int i = c / 64; - uint64_t word = words_[i] & (~0ULL << (c % 64)); + uint64_t word = words_[i] & (~uint64_t{0} << (c % 64)); if (word != 0) return (i * 64) + FindLSBSet(word); diff --git a/re2/bitstate.cc b/re2/bitstate.cc index f15c1e4..877e548 100644 --- a/re2/bitstate.cc +++ b/re2/bitstate.cc @@ -7,7 +7,7 @@ // Prog::SearchBitState is a regular expression search with submatch // tracking for small regular expressions and texts. Similarly to // testing/backtrack.cc, it allocates a bitmap with (count of -// lists) * (length of prog) bits to make sure it never explores the +// lists) * (length of text) bits to make sure it never explores the // same (instruction list, character position) multiple times. This // limits the search to run in time linear in the length of the text. // @@ -63,11 +63,14 @@ class BitState { int nsubmatch_; // # of submatches to fill in // Search state - static const int VisitedBits = 32; - PODArray visited_; // bitmap: (list ID, char*) pairs visited + static constexpr int kVisitedBits = 64; + PODArray visited_; // bitmap: (list ID, char*) pairs visited PODArray cap_; // capture registers PODArray job_; // stack of text positions to explore int njob_; // stack size + + BitState(const BitState&) = delete; + BitState& operator=(const BitState&) = delete; }; BitState::BitState(Prog* prog) @@ -87,9 +90,9 @@ BitState::BitState(Prog* prog) bool BitState::ShouldVisit(int id, const char* p) { int n = prog_->list_heads()[id] * static_cast(text_.size()+1) + static_cast(p-text_.data()); - if (visited_[n/VisitedBits] & (1 << (n & (VisitedBits-1)))) + if (visited_[n/kVisitedBits] & (uint64_t{1} << (n & (kVisitedBits-1)))) return false; - visited_[n/VisitedBits] |= 1 << (n & (VisitedBits-1)); + visited_[n/kVisitedBits] |= uint64_t{1} << (n & (kVisitedBits-1)); return true; } @@ -290,9 +293,9 @@ bool BitState::Search(const StringPiece& text, const StringPiece& context, context_ = context; if (context_.data() == NULL) context_ = text; - if (prog_->anchor_start() && context_.begin() != text.begin()) + if (prog_->anchor_start() && BeginPtr(context_) != BeginPtr(text)) return false; - if (prog_->anchor_end() && context_.end() != text.end()) + if (prog_->anchor_end() && EndPtr(context_) != EndPtr(text)) return false; anchored_ = anchored || prog_->anchor_start(); longest_ = longest || prog_->anchor_end(); @@ -304,8 +307,8 @@ bool BitState::Search(const StringPiece& text, const StringPiece& context, // Allocate scratch space. int nvisited = prog_->list_count() * static_cast(text.size()+1); - nvisited = (nvisited + VisitedBits-1) / VisitedBits; - visited_ = PODArray(nvisited); + nvisited = (nvisited + kVisitedBits-1) / kVisitedBits; + visited_ = PODArray(nvisited); memset(visited_.data(), 0, nvisited*sizeof visited_[0]); int ncap = 2*nsubmatch; @@ -329,14 +332,13 @@ bool BitState::Search(const StringPiece& text, const StringPiece& context, // This looks like it's quadratic in the size of the text, // but we are not clearing visited_ between calls to TrySearch, // so no work is duplicated and it ends up still being linear. - for (const char* p = text.data(); p <= text.data() + text.size(); p++) { - // Try to use memchr to find the first byte quickly. - int fb = prog_->first_byte(); - if (fb >= 0 && p < text.data() + text.size() && (p[0] & 0xFF) != fb) { - p = reinterpret_cast( - memchr(p, fb, text.data() + text.size() - p)); + const char* etext = text.data() + text.size(); + for (const char* p = text.data(); p <= etext; p++) { + // Try to use prefix accel (e.g. memchr) to skip ahead. + if (p < etext && prog_->can_prefix_accel()) { + p = reinterpret_cast(prog_->PrefixAccel(p, etext - p)); if (p == NULL) - p = text.data() + text.size(); + p = etext; } cap_[0] = p; @@ -375,7 +377,7 @@ bool Prog::SearchBitState(const StringPiece& text, bool longest = kind != kFirstMatch; if (!b.Search(text, context, anchored, longest, match, nmatch)) return false; - if (kind == kFullMatch && match[0].end() != text.end()) + if (kind == kFullMatch && EndPtr(match[0]) != EndPtr(text)) return false; return true; } diff --git a/re2/compile.cc b/re2/compile.cc index 7848dfc..61d801a 100644 --- a/re2/compile.cc +++ b/re2/compile.cc @@ -30,92 +30,60 @@ namespace re2 { // See http://swtch.com/~rsc/regexp/regexp1.html for inspiration. // // Because the out and out1 fields in Inst are no longer pointers, -// we can't use pointers directly here either. Instead, p refers -// to inst_[p>>1].out (p&1 == 0) or inst_[p>>1].out1 (p&1 == 1). -// p == 0 represents the NULL list. This is okay because instruction #0 +// we can't use pointers directly here either. Instead, head refers +// to inst_[head>>1].out (head&1 == 0) or inst_[head>>1].out1 (head&1 == 1). +// head == 0 represents the NULL list. This is okay because instruction #0 // is always the fail instruction, which never appears on a list. - struct PatchList { - uint32_t p; - // Returns patch list containing just p. - static PatchList Mk(uint32_t p); + static PatchList Mk(uint32_t p) { + return {p, p}; + } - // Patches all the entries on l to have value v. + // Patches all the entries on l to have value p. // Caller must not ever use patch list again. - static void Patch(Prog::Inst *inst0, PatchList l, uint32_t v); - - // Deref returns the next pointer pointed at by p. - static PatchList Deref(Prog::Inst *inst0, PatchList l); - - // Appends two patch lists and returns result. - static PatchList Append(Prog::Inst *inst0, PatchList l1, PatchList l2); -}; - -static PatchList nullPatchList = { 0 }; - -// Returns patch list containing just p. -PatchList PatchList::Mk(uint32_t p) { - PatchList l; - l.p = p; - return l; -} - -// Returns the next pointer pointed at by l. -PatchList PatchList::Deref(Prog::Inst* inst0, PatchList l) { - Prog::Inst* ip = &inst0[l.p>>1]; - if (l.p&1) - l.p = ip->out1(); - else - l.p = ip->out(); - return l; -} - -// Patches all the entries on l to have value v. -void PatchList::Patch(Prog::Inst *inst0, PatchList l, uint32_t val) { - while (l.p != 0) { - Prog::Inst* ip = &inst0[l.p>>1]; - if (l.p&1) { - l.p = ip->out1(); - ip->out1_ = val; - } else { - l.p = ip->out(); - ip->set_out(val); + static void Patch(Prog::Inst* inst0, PatchList l, uint32_t p) { + while (l.head != 0) { + Prog::Inst* ip = &inst0[l.head>>1]; + if (l.head&1) { + l.head = ip->out1(); + ip->out1_ = p; + } else { + l.head = ip->out(); + ip->set_out(p); + } } } -} -// Appends two patch lists and returns result. -PatchList PatchList::Append(Prog::Inst* inst0, PatchList l1, PatchList l2) { - if (l1.p == 0) - return l2; - if (l2.p == 0) - return l1; - - PatchList l = l1; - for (;;) { - PatchList next = PatchList::Deref(inst0, l); - if (next.p == 0) - break; - l = next; + // Appends two patch lists and returns result. + static PatchList Append(Prog::Inst* inst0, PatchList l1, PatchList l2) { + if (l1.head == 0) + return l2; + if (l2.head == 0) + return l1; + Prog::Inst* ip = &inst0[l1.tail>>1]; + if (l1.tail&1) + ip->out1_ = l2.head; + else + ip->set_out(l2.head); + return {l1.head, l2.tail}; } - Prog::Inst* ip = &inst0[l.p>>1]; - if (l.p&1) - ip->out1_ = l2.p; - else - ip->set_out(l2.p); + uint32_t head; + uint32_t tail; // for constant-time append +}; - return l1; -} +static const PatchList kNullPatchList = {0, 0}; // Compiled program fragment. struct Frag { uint32_t begin; PatchList end; + bool nullable; - Frag() : begin(0) { end.p = 0; } // needed so Frag can go in vector - Frag(uint32_t begin, PatchList end) : begin(begin), end(end) {} + Frag() : begin(0), end(kNullPatchList), nullable(false) {} + Frag(uint32_t begin, PatchList end, bool nullable) + : begin(begin), end(end), nullable(nullable) {} }; // Input encodings. @@ -212,8 +180,8 @@ class Compiler : public Regexp::Walker { int AddSuffixRecursive(int root, int id); // Finds the trie node for the given suffix. Returns a Frag in order to - // distinguish between pointing at the root node directly (end.p == 0) - // and pointing at an Alt's out1 or out (end.p&1 == 1 or 0, respectively). + // distinguish between pointing at the root node directly (end.head == 0) + // and pointing at an Alt's out1 or out (end.head&1 == 1 or 0, respectively). Frag FindByteRange(int root, int id); // Compares two ByteRanges and returns true iff they are equal. @@ -225,8 +193,8 @@ class Compiler : public Regexp::Walker { // Single rune. Frag Literal(Rune r, bool foldcase); - void Setup(Regexp::ParseFlags, int64_t, RE2::Anchor); - Prog* Finish(); + void Setup(Regexp::ParseFlags flags, int64_t max_mem, RE2::Anchor anchor); + Prog* Finish(Regexp* re); // Returns .* where dot = any byte Frag DotStar(); @@ -298,7 +266,7 @@ int Compiler::AllocInst(int n) { // Returns an unmatchable fragment. Frag Compiler::NoMatch() { - return Frag(0, nullPatchList); + return Frag(); } // Is a an unmatchable fragment? @@ -314,7 +282,7 @@ Frag Compiler::Cat(Frag a, Frag b) { // Elide no-op. Prog::Inst* begin = &inst_[a.begin]; if (begin->opcode() == kInstNop && - a.end.p == (a.begin << 1) && + a.end.head == (a.begin << 1) && begin->out() == 0) { // in case refs to a somewhere PatchList::Patch(inst_.data(), a.end, b.begin); @@ -324,11 +292,11 @@ Frag Compiler::Cat(Frag a, Frag b) { // To run backward over string, reverse all concatenations. if (reversed_) { PatchList::Patch(inst_.data(), b.end, a.begin); - return Frag(b.begin, a.end); + return Frag(b.begin, a.end, b.nullable && a.nullable); } PatchList::Patch(inst_.data(), a.end, b.begin); - return Frag(a.begin, b.end); + return Frag(a.begin, b.end, a.nullable && b.nullable); } // Given fragments for a and b, returns fragment for a|b. @@ -344,7 +312,8 @@ Frag Compiler::Alt(Frag a, Frag b) { return NoMatch(); inst_[id].InitAlt(a.begin, b.begin); - return Frag(id, PatchList::Append(inst_.data(), a.end, b.end)); + return Frag(id, PatchList::Append(inst_.data(), a.end, b.end), + a.nullable || b.nullable); } // When capturing submatches in like-Perl mode, a kOpAlt Inst @@ -354,27 +323,44 @@ Frag Compiler::Alt(Frag a, Frag b) { // then the operator is greedy. If out1_ is the repetition // (and out_ moves forward), then the operator is non-greedy. -// Given a fragment a, returns a fragment for a* or a*? (if nongreedy) -Frag Compiler::Star(Frag a, bool nongreedy) { +// Given a fragment for a, returns a fragment for a+ or a+? (if nongreedy) +Frag Compiler::Plus(Frag a, bool nongreedy) { int id = AllocInst(1); if (id < 0) return NoMatch(); - inst_[id].InitAlt(0, 0); - PatchList::Patch(inst_.data(), a.end, id); + PatchList pl; if (nongreedy) { - inst_[id].out1_ = a.begin; - return Frag(id, PatchList::Mk(id << 1)); + inst_[id].InitAlt(0, a.begin); + pl = PatchList::Mk(id << 1); } else { - inst_[id].set_out(a.begin); - return Frag(id, PatchList::Mk((id << 1) | 1)); + inst_[id].InitAlt(a.begin, 0); + pl = PatchList::Mk((id << 1) | 1); } + PatchList::Patch(inst_.data(), a.end, id); + return Frag(a.begin, pl, a.nullable); } -// Given a fragment for a, returns a fragment for a+ or a+? (if nongreedy) -Frag Compiler::Plus(Frag a, bool nongreedy) { - // a+ is just a* with a different entry point. - Frag f = Star(a, nongreedy); - return Frag(a.begin, f.end); +// Given a fragment for a, returns a fragment for a* or a*? (if nongreedy) +Frag Compiler::Star(Frag a, bool nongreedy) { + // When the subexpression is nullable, one Alt isn't enough to guarantee + // correct priority ordering within the transitive closure. The simplest + // solution is to handle it as (a+)? instead, which adds the second Alt. + if (a.nullable) + return Quest(Plus(a, nongreedy), nongreedy); + + int id = AllocInst(1); + if (id < 0) + return NoMatch(); + PatchList pl; + if (nongreedy) { + inst_[id].InitAlt(0, a.begin); + pl = PatchList::Mk(id << 1); + } else { + inst_[id].InitAlt(a.begin, 0); + pl = PatchList::Mk((id << 1) | 1); + } + PatchList::Patch(inst_.data(), a.end, id); + return Frag(id, pl, true); } // Given a fragment for a, returns a fragment for a? or a?? (if nongreedy) @@ -392,7 +378,7 @@ Frag Compiler::Quest(Frag a, bool nongreedy) { inst_[id].InitAlt(a.begin, 0); pl = PatchList::Mk((id << 1) | 1); } - return Frag(id, PatchList::Append(inst_.data(), pl, a.end)); + return Frag(id, PatchList::Append(inst_.data(), pl, a.end), true); } // Returns a fragment for the byte range lo-hi. @@ -401,7 +387,7 @@ Frag Compiler::ByteRange(int lo, int hi, bool foldcase) { if (id < 0) return NoMatch(); inst_[id].InitByteRange(lo, hi, foldcase, 0); - return Frag(id, PatchList::Mk(id << 1)); + return Frag(id, PatchList::Mk(id << 1), false); } // Returns a no-op fragment. Sometimes unavoidable. @@ -410,7 +396,7 @@ Frag Compiler::Nop() { if (id < 0) return NoMatch(); inst_[id].InitNop(0); - return Frag(id, PatchList::Mk(id << 1)); + return Frag(id, PatchList::Mk(id << 1), true); } // Returns a fragment that signals a match. @@ -419,7 +405,7 @@ Frag Compiler::Match(int32_t match_id) { if (id < 0) return NoMatch(); inst_[id].InitMatch(match_id); - return Frag(id, nullPatchList); + return Frag(id, kNullPatchList, false); } // Returns a fragment matching a particular empty-width op (like ^ or $) @@ -428,7 +414,7 @@ Frag Compiler::EmptyWidth(EmptyOp empty) { if (id < 0) return NoMatch(); inst_[id].InitEmptyWidth(empty, 0); - return Frag(id, PatchList::Mk(id << 1)); + return Frag(id, PatchList::Mk(id << 1), true); } // Given a fragment a, returns a fragment with capturing parens around a. @@ -442,7 +428,7 @@ Frag Compiler::Capture(Frag a, int n) { inst_[id+1].InitCapture(2*n+1, 0); PatchList::Patch(inst_.data(), a.end, id+1); - return Frag(id, PatchList::Mk((id+1) << 1)); + return Frag(id, PatchList::Mk((id+1) << 1), a.nullable); } // A Rune is a name for a Unicode code point. @@ -467,7 +453,7 @@ static int MaxRune(int len) { void Compiler::BeginRange() { rune_cache_.clear(); rune_range_.begin = 0; - rune_range_.end = nullPatchList; + rune_range_.end = kNullPatchList; } int Compiler::UncachedRuneByteSuffix(uint8_t lo, uint8_t hi, bool foldcase, @@ -548,9 +534,9 @@ int Compiler::AddSuffixRecursive(int root, int id) { } int br; - if (f.end.p == 0) + if (f.end.head == 0) br = root; - else if (f.end.p&1) + else if (f.end.head&1) br = inst_[f.begin].out1(); else br = inst_[f.begin].out(); @@ -566,9 +552,9 @@ int Compiler::AddSuffixRecursive(int root, int id) { // Ensure that the parent points to the clone, not to the original. // Note that this could leave the head unreachable except via the cache. br = byterange; - if (f.end.p == 0) + if (f.end.head == 0) root = br; - else if (f.end.p&1) + else if (f.end.head&1) inst_[f.begin].out1_ = br; else inst_[f.begin].set_out(br); @@ -601,7 +587,7 @@ bool Compiler::ByteRangeEqual(int id1, int id2) { Frag Compiler::FindByteRange(int root, int id) { if (inst_[root].opcode() == kInstByteRange) { if (ByteRangeEqual(root, id)) - return Frag(root, nullPatchList); + return Frag(root, kNullPatchList, false); else return NoMatch(); } @@ -609,7 +595,7 @@ Frag Compiler::FindByteRange(int root, int id) { while (inst_[root].opcode() == kInstAlt) { int out1 = inst_[root].out1(); if (ByteRangeEqual(out1, id)) - return Frag(root, PatchList::Mk((root << 1) | 1)); + return Frag(root, PatchList::Mk((root << 1) | 1), false); // CharClass is a sorted list of ranges, so if out1 of the root Alt wasn't // what we're looking for, then we can stop immediately. Unfortunately, we @@ -621,7 +607,7 @@ Frag Compiler::FindByteRange(int root, int id) { if (inst_[out].opcode() == kInstAlt) root = out; else if (ByteRangeEqual(out, id)) - return Frag(root, PatchList::Mk(root << 1)); + return Frag(root, PatchList::Mk(root << 1), false); else return NoMatch(); } @@ -662,48 +648,43 @@ void Compiler::AddRuneRangeLatin1(Rune lo, Rune hi, bool foldcase) { static_cast(hi), foldcase, 0)); } -// Table describing how to make a UTF-8 matching machine -// for the rune range 80-10FFFF (Runeself-Runemax). -// This range happens frequently enough (for example /./ and /[^a-z]/) -// and the rune_cache_ map is slow enough that this is worth -// special handling. Makes compilation of a small expression -// with a dot in it about 10% faster. -// The * in the comments below mark whole sequences. -static struct ByteRangeProg { - int next; - int lo; - int hi; -} prog_80_10ffff[] = { - // Two-byte - { -1, 0x80, 0xBF, }, // 0: 80-BF - { 0, 0xC2, 0xDF, }, // 1: C2-DF 80-BF* - - // Three-byte - { 0, 0xA0, 0xBF, }, // 2: A0-BF 80-BF - { 2, 0xE0, 0xE0, }, // 3: E0 A0-BF 80-BF* - { 0, 0x80, 0xBF, }, // 4: 80-BF 80-BF - { 4, 0xE1, 0xEF, }, // 5: E1-EF 80-BF 80-BF* - - // Four-byte - { 4, 0x90, 0xBF, }, // 6: 90-BF 80-BF 80-BF - { 6, 0xF0, 0xF0, }, // 7: F0 90-BF 80-BF 80-BF* - { 4, 0x80, 0xBF, }, // 8: 80-BF 80-BF 80-BF - { 8, 0xF1, 0xF3, }, // 9: F1-F3 80-BF 80-BF 80-BF* - { 4, 0x80, 0x8F, }, // 10: 80-8F 80-BF 80-BF - { 10, 0xF4, 0xF4, }, // 11: F4 80-8F 80-BF 80-BF* -}; - void Compiler::Add_80_10ffff() { - int inst[arraysize(prog_80_10ffff)] = { 0 }; // does not need to be initialized; silences gcc warning - for (size_t i = 0; i < arraysize(prog_80_10ffff); i++) { - const ByteRangeProg& p = prog_80_10ffff[i]; - int next = 0; - if (p.next >= 0) - next = inst[p.next]; - inst[i] = UncachedRuneByteSuffix(static_cast(p.lo), - static_cast(p.hi), false, next); - if ((p.lo & 0xC0) != 0x80) - AddSuffix(inst[i]); + // The 80-10FFFF (Runeself-Runemax) rune range occurs frequently enough + // (for example, for /./ and /[^a-z]/) that it is worth simplifying: by + // permitting overlong encodings in E0 and F0 sequences and code points + // over 10FFFF in F4 sequences, the size of the bytecode and the number + // of equivalence classes are reduced significantly. + int id; + if (reversed_) { + // Prefix factoring matters, but we don't have to handle it here + // because the rune range trie logic takes care of that already. + id = UncachedRuneByteSuffix(0xC2, 0xDF, false, 0); + id = UncachedRuneByteSuffix(0x80, 0xBF, false, id); + AddSuffix(id); + + id = UncachedRuneByteSuffix(0xE0, 0xEF, false, 0); + id = UncachedRuneByteSuffix(0x80, 0xBF, false, id); + id = UncachedRuneByteSuffix(0x80, 0xBF, false, id); + AddSuffix(id); + + id = UncachedRuneByteSuffix(0xF0, 0xF4, false, 0); + id = UncachedRuneByteSuffix(0x80, 0xBF, false, id); + id = UncachedRuneByteSuffix(0x80, 0xBF, false, id); + id = UncachedRuneByteSuffix(0x80, 0xBF, false, id); + AddSuffix(id); + } else { + // Suffix factoring matters - and we do have to handle it here. + int cont1 = UncachedRuneByteSuffix(0x80, 0xBF, false, 0); + id = UncachedRuneByteSuffix(0xC2, 0xDF, false, cont1); + AddSuffix(id); + + int cont2 = UncachedRuneByteSuffix(0x80, 0xBF, false, cont1); + id = UncachedRuneByteSuffix(0xE0, 0xEF, false, cont2); + AddSuffix(id); + + int cont3 = UncachedRuneByteSuffix(0x80, 0xBF, false, cont2); + id = UncachedRuneByteSuffix(0xF0, 0xF4, false, cont3); + AddSuffix(id); } } @@ -711,9 +692,8 @@ void Compiler::AddRuneRangeUTF8(Rune lo, Rune hi, bool foldcase) { if (lo > hi) return; - // Pick off 80-10FFFF as a common special case - // that can bypass the slow rune_cache_. - if (lo == 0x80 && hi == 0x10ffff && !reversed_) { + // Pick off 80-10FFFF as a common special case. + if (lo == 0x80 && hi == 0x10ffff) { Add_80_10ffff(); return; } @@ -1095,8 +1075,6 @@ static bool IsAnchorEnd(Regexp** pre, int depth) { void Compiler::Setup(Regexp::ParseFlags flags, int64_t max_mem, RE2::Anchor anchor) { - prog_->set_flags(flags); - if (flags & Regexp::Latin1) encoding_ = kEncodingLatin1; max_mem_ = max_mem; @@ -1117,14 +1095,11 @@ void Compiler::Setup(Regexp::ParseFlags flags, int64_t max_mem, // on the program.) if (m >= 1<<24) m = 1<<24; - // Inst imposes its own limit (currently bigger than 2^24 but be safe). if (m > Prog::Inst::kMaxInst) m = Prog::Inst::kMaxInst; - max_ninst_ = static_cast(m); } - anchor_ = anchor; } @@ -1178,10 +1153,10 @@ Prog* Compiler::Compile(Regexp* re, bool reversed, int64_t max_mem) { c.prog_->set_start_unanchored(all.begin); // Hand ownership of prog_ to caller. - return c.Finish(); + return c.Finish(re); } -Prog* Compiler::Finish() { +Prog* Compiler::Finish(Regexp* re) { if (failed_) return NULL; @@ -1198,6 +1173,13 @@ Prog* Compiler::Finish() { prog_->Flatten(); prog_->ComputeByteMap(); + if (!prog_->reversed()) { + std::string prefix; + bool prefix_foldcase; + if (re->RequiredPrefixForAccel(&prefix, &prefix_foldcase)) + prog_->ConfigurePrefixAccel(prefix, prefix_foldcase); + } + // Record remaining memory for DFA. if (max_mem_ <= 0) { prog_->set_dfa_mem(1<<20); @@ -1254,7 +1236,7 @@ Prog* Compiler::CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max_mem) { c.prog_->set_start(all.begin); c.prog_->set_start_unanchored(all.begin); - Prog* prog = c.Finish(); + Prog* prog = c.Finish(re); if (prog == NULL) return NULL; diff --git a/re2/dfa.cc b/re2/dfa.cc index 816080a..d47c7d5 100644 --- a/re2/dfa.cc +++ b/re2/dfa.cc @@ -42,6 +42,7 @@ #include "util/strutil.h" #include "re2/pod_array.h" #include "re2/prog.h" +#include "re2/re2.h" #include "re2/sparse_set.h" #include "re2/stringpiece.h" @@ -52,20 +53,13 @@ namespace re2 { -#if !defined(__linux__) /* only Linux seems to have memrchr */ -static void* memrchr(const void* s, int c, size_t n) { - const unsigned char* p = (const unsigned char*)s; - for (p += n; n > 0; n--) - if (*--p == c) - return (void*)p; - - return NULL; -} -#endif - // Controls whether the DFA should bail out early if the NFA would be faster. static bool dfa_should_bail_when_slow = true; +void Prog::TESTING_ONLY_set_dfa_should_bail_when_slow(bool b) { + dfa_should_bail_when_slow = b; +} + // Changing this to true compiles in prints that trace execution of the DFA. // Generates a lot of output -- only useful for debugging. static const bool ExtraDebug = false; @@ -177,11 +171,8 @@ class DFA { typedef std::unordered_set StateSet; private: - // Special "first_byte" values for a state. (Values >= 0 denote actual bytes.) - enum { - kFbUnknown = -1, // No analysis has been performed. - kFbNone = -2, // The first-byte trick cannot be used. - }; + // Make it easier to swap in a scalable reader-writer mutex. + using CacheMutex = Mutex; enum { // Indices into start_ for unanchored searches. @@ -249,25 +240,26 @@ class DFA { struct SearchParams { SearchParams(const StringPiece& text, const StringPiece& context, RWLocker* cache_lock) - : text(text), context(context), + : text(text), + context(context), anchored(false), + can_prefix_accel(false), want_earliest_match(false), run_forward(false), start(NULL), - first_byte(kFbUnknown), cache_lock(cache_lock), failed(false), ep(NULL), - matches(NULL) { } + matches(NULL) {} StringPiece text; StringPiece context; bool anchored; + bool can_prefix_accel; bool want_earliest_match; bool run_forward; State* start; - int first_byte; - RWLocker *cache_lock; + RWLocker* cache_lock; bool failed; // "out" parameter: whether search gave up const char* ep; // "out" parameter: end pointer for match SparseSet* matches; @@ -278,15 +270,13 @@ class DFA { }; // Before each search, the parameters to Search are analyzed by - // AnalyzeSearch to determine the state in which to start and the - // "first_byte" for that state, if any. + // AnalyzeSearch to determine the state in which to start. struct StartInfo { - StartInfo() : start(NULL), first_byte(kFbUnknown) {} - State* start; - std::atomic first_byte; + StartInfo() : start(NULL) {} + std::atomic start; }; - // Fills in params->start and params->first_byte using + // Fills in params->start and params->can_prefix_accel using // the other search parameters. Returns true on success, // false on failure. // cache_mutex_.r <= L < mutex_ @@ -297,10 +287,10 @@ class DFA { // The generic search loop, inlined to create specialized versions. // cache_mutex_.r <= L < mutex_ // Might unlock and relock cache_mutex_ via params->cache_lock. - inline bool InlinedSearchLoop(SearchParams* params, - bool have_first_byte, - bool want_earliest_match, - bool run_forward); + template + inline bool InlinedSearchLoop(SearchParams* params); // The specialized versions of InlinedSearchLoop. The three letters // at the ends of the name denote the true/false values used as the @@ -322,13 +312,6 @@ class DFA { // Might unlock and relock cache_mutex_ via params->cache_lock. bool FastSearchLoop(SearchParams* params); - // For debugging, a slow search loop that calls InlinedSearchLoop - // directly -- because the booleans passed are not constants, the - // loop is not specialized like the SearchFFF etc. versions, so it - // runs much more slowly. Useful only for debugging. - // cache_mutex_.r <= L < mutex_ - // Might unlock and relock cache_mutex_ via params->cache_lock. - bool SlowSearchLoop(SearchParams* params); // Looks up bytes in bytemap_ but handles case c == kByteEndText too. int ByteMap(int c) { @@ -355,11 +338,14 @@ class DFA { // while holding cache_mutex_ for writing, to avoid interrupting other // readers. Any State* pointers are only valid while cache_mutex_ // is held. - Mutex cache_mutex_; + CacheMutex cache_mutex_; int64_t mem_budget_; // Total memory budget for all States. int64_t state_budget_; // Amount of memory remaining for new States. StateSet state_cache_; // All States computed so far. StartInfo start_[kMaxStart]; + + DFA(const DFA&) = delete; + DFA& operator=(const DFA&) = delete; }; // Shorthand for casting to uint8_t*. @@ -613,7 +599,7 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) { // Only ByteRange, EmptyWidth, and Match instructions are useful to keep: // those are the only operators with any effect in // RunWorkqOnEmptyString or RunWorkqOnByte. - int* inst = new int[q->size()]; + PODArray inst(q->size()); int n = 0; uint32_t needflags = 0; // flags needed by kInstEmptyWidth instructions bool sawmatch = false; // whether queue contains guaranteed kInstMatch @@ -643,7 +629,6 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) { (it == q->begin() && ip->greedy(prog_))) && (kind_ != Prog::kLongestMatch || !sawmark) && (flag & kFlagMatch)) { - delete[] inst; if (ExtraDebug) fprintf(stderr, " -> FullMatchState\n"); return FullMatchState; @@ -690,7 +675,6 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) { // the execution loop can stop early. This is only okay // if the state is *not* a matching state. if (n == 0 && flag == 0) { - delete[] inst; if (ExtraDebug) fprintf(stderr, " -> DeadState\n"); return DeadState; @@ -700,7 +684,7 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) { // unordered state sets separated by Marks. Sort each set // to canonicalize, to reduce the number of distinct sets stored. if (kind_ == Prog::kLongestMatch) { - int* ip = inst; + int* ip = inst.data(); int* ep = ip + n; while (ip < ep) { int* markp = ip; @@ -717,7 +701,7 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) { // we have an unordered set of states (i.e. we don't have Marks) // and sorting will reduce the number of distinct sets stored. if (kind_ == Prog::kManyMatch) { - int* ip = inst; + int* ip = inst.data(); int* ep = ip + n; std::sort(ip, ep); } @@ -736,8 +720,7 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) { // Save the needed empty-width flags in the top bits for use later. flag |= needflags << kFlagNeedShift; - State* state = CachedState(inst, n, flag); - delete[] inst; + State* state = CachedState(inst.data(), n, flag); return state; } @@ -971,8 +954,21 @@ void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq, break; case kInstByteRange: // can follow if c is in range - if (ip->Matches(c)) - AddToQueue(newq, ip->out(), flag); + if (!ip->Matches(c)) + break; + AddToQueue(newq, ip->out(), flag); + if (ip->hint() != 0) { + // We have a hint, but we must cancel out the + // increment that will occur after the break. + i += ip->hint() - 1; + } else { + // We have no hint, so we must find the end + // of the current list and then skip to it. + Prog::Inst* ip0 = ip; + while (!ip->last()) + ++ip; + i += ip - ip0; + } break; case kInstMatch: @@ -1117,7 +1113,7 @@ DFA::State* DFA::RunStateOnByte(State* state, int c) { class DFA::RWLocker { public: - explicit RWLocker(Mutex* mu); + explicit RWLocker(CacheMutex* mu); ~RWLocker(); // If the lock is only held for reading right now, @@ -1127,14 +1123,14 @@ class DFA::RWLocker { void LockForWriting(); private: - Mutex* mu_; + CacheMutex* mu_; bool writing_; RWLocker(const RWLocker&) = delete; RWLocker& operator=(const RWLocker&) = delete; }; -DFA::RWLocker::RWLocker(Mutex* mu) : mu_(mu), writing_(false) { +DFA::RWLocker::RWLocker(CacheMutex* mu) : mu_(mu), writing_(false) { mu_->ReaderLock(); } @@ -1171,11 +1167,14 @@ void DFA::ResetCache(RWLocker* cache_lock) { // Re-acquire the cache_mutex_ for writing (exclusive use). cache_lock->LockForWriting(); + hooks::GetDFAStateCacheResetHook()({ + state_budget_, + state_cache_.size(), + }); + // Clear the cache, reset the memory budget. - for (int i = 0; i < kMaxStart; i++) { - start_[i].start = NULL; - start_[i].first_byte.store(kFbUnknown, std::memory_order_relaxed); - } + for (int i = 0; i < kMaxStart; i++) + start_[i].start.store(NULL, std::memory_order_relaxed); ClearCache(); mem_budget_ = state_budget_; } @@ -1290,8 +1289,7 @@ DFA::State* DFA::StateSaver::Restore() { // situation, the DFA can do better than executing the simple loop. // Instead, it can call memchr to search very quickly for the byte c. // Whether the start state has this property is determined during a -// pre-compilation pass, and if so, the byte b is passed to the search -// loop as the "first_byte" argument, along with a boolean "have_first_byte". +// pre-compilation pass and the "can_prefix_accel" argument is set. // // Fourth, the desired behavior is to search for the leftmost-best match // (approximately, the same one that Perl would find), which is not @@ -1323,10 +1321,10 @@ DFA::State* DFA::StateSaver::Restore() { // The bools are equal to the same-named variables in params, but // making them function arguments lets the inliner specialize // this function to each combination (see two paragraphs above). -inline bool DFA::InlinedSearchLoop(SearchParams* params, - bool have_first_byte, - bool want_earliest_match, - bool run_forward) { +template +inline bool DFA::InlinedSearchLoop(SearchParams* params) { State* start = params->start; const uint8_t* bp = BytePtr(params->text.data()); // start of text const uint8_t* p = bp; // text scanning point @@ -1369,22 +1367,14 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params, if (ExtraDebug) fprintf(stderr, "@%td: %s\n", p - bp, DumpState(s).c_str()); - if (have_first_byte && s == start) { - // In start state, only way out is to find first_byte, - // so use optimized assembly in memchr to skip ahead. - // If first_byte isn't found, we can skip to the end - // of the string. - if (run_forward) { - if ((p = BytePtr(memchr(p, params->first_byte, ep - p))) == NULL) { - p = ep; - break; - } - } else { - if ((p = BytePtr(memrchr(ep, params->first_byte, p - ep))) == NULL) { - p = ep; - break; - } - p++; + if (can_prefix_accel && s == start) { + // In start state, only way out is to find the prefix, + // so we use prefix accel (e.g. memchr) to skip ahead. + // If not found, we can skip to the end of the string. + p = BytePtr(prog_->PrefixAccel(p, ep - p)); + if (p == NULL) { + p = ep; + break; } } @@ -1498,15 +1488,15 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params, int lastbyte; if (run_forward) { - if (params->text.end() == params->context.end()) + if (EndPtr(params->text) == EndPtr(params->context)) lastbyte = kByteEndText; else - lastbyte = params->text.end()[0] & 0xFF; + lastbyte = EndPtr(params->text)[0] & 0xFF; } else { - if (params->text.begin() == params->context.begin()) + if (BeginPtr(params->text) == BeginPtr(params->context)) lastbyte = kByteEndText; else - lastbyte = params->text.begin()[-1] & 0xFF; + lastbyte = BeginPtr(params->text)[-1] & 0xFF; } State* ns = s->next_[ByteMap(lastbyte)].load(std::memory_order_acquire); @@ -1559,36 +1549,28 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params, // Inline specializations of the general loop. bool DFA::SearchFFF(SearchParams* params) { - return InlinedSearchLoop(params, 0, 0, 0); + return InlinedSearchLoop(params); } bool DFA::SearchFFT(SearchParams* params) { - return InlinedSearchLoop(params, 0, 0, 1); + return InlinedSearchLoop(params); } bool DFA::SearchFTF(SearchParams* params) { - return InlinedSearchLoop(params, 0, 1, 0); + return InlinedSearchLoop(params); } bool DFA::SearchFTT(SearchParams* params) { - return InlinedSearchLoop(params, 0, 1, 1); + return InlinedSearchLoop(params); } bool DFA::SearchTFF(SearchParams* params) { - return InlinedSearchLoop(params, 1, 0, 0); + return InlinedSearchLoop(params); } bool DFA::SearchTFT(SearchParams* params) { - return InlinedSearchLoop(params, 1, 0, 1); + return InlinedSearchLoop(params); } bool DFA::SearchTTF(SearchParams* params) { - return InlinedSearchLoop(params, 1, 1, 0); + return InlinedSearchLoop(params); } bool DFA::SearchTTT(SearchParams* params) { - return InlinedSearchLoop(params, 1, 1, 1); -} - -// For debugging, calls the general code directly. -bool DFA::SlowSearchLoop(SearchParams* params) { - return InlinedSearchLoop(params, - params->first_byte >= 0, - params->want_earliest_match, - params->run_forward); + return InlinedSearchLoop(params); } // For performance, calls the appropriate specialized version @@ -1607,8 +1589,7 @@ bool DFA::FastSearchLoop(SearchParams* params) { &DFA::SearchTTT, }; - bool have_first_byte = params->first_byte >= 0; - int index = 4 * have_first_byte + + int index = 4 * params->can_prefix_accel + 2 * params->want_earliest_match + 1 * params->run_forward; return (this->*Searches[index])(params); @@ -1646,7 +1627,7 @@ bool DFA::AnalyzeSearch(SearchParams* params) { const StringPiece& context = params->context; // Sanity check: make sure that text lies within context. - if (text.begin() < context.begin() || text.end() > context.end()) { + if (BeginPtr(text) < BeginPtr(context) || EndPtr(text) > EndPtr(context)) { LOG(DFATAL) << "context does not contain text"; params->start = DeadState; return true; @@ -1656,13 +1637,13 @@ bool DFA::AnalyzeSearch(SearchParams* params) { int start; uint32_t flags; if (params->run_forward) { - if (text.begin() == context.begin()) { + if (BeginPtr(text) == BeginPtr(context)) { start = kStartBeginText; flags = kEmptyBeginText|kEmptyBeginLine; - } else if (text.begin()[-1] == '\n') { + } else if (BeginPtr(text)[-1] == '\n') { start = kStartBeginLine; flags = kEmptyBeginLine; - } else if (Prog::IsWordChar(text.begin()[-1] & 0xFF)) { + } else if (Prog::IsWordChar(BeginPtr(text)[-1] & 0xFF)) { start = kStartAfterWordChar; flags = kFlagLastWord; } else { @@ -1670,13 +1651,13 @@ bool DFA::AnalyzeSearch(SearchParams* params) { flags = 0; } } else { - if (text.end() == context.end()) { + if (EndPtr(text) == EndPtr(context)) { start = kStartBeginText; flags = kEmptyBeginText|kEmptyBeginLine; - } else if (text.end()[0] == '\n') { + } else if (EndPtr(text)[0] == '\n') { start = kStartBeginLine; flags = kEmptyBeginLine; - } else if (Prog::IsWordChar(text.end()[0] & 0xFF)) { + } else if (Prog::IsWordChar(EndPtr(text)[0] & 0xFF)) { start = kStartAfterWordChar; flags = kFlagLastWord; } else { @@ -1700,13 +1681,22 @@ bool DFA::AnalyzeSearch(SearchParams* params) { } } + params->start = info->start.load(std::memory_order_acquire); + + // Even if we could prefix accel, we cannot do so when anchored and, + // less obviously, we cannot do so when we are going to need flags. + // This trick works only when there is a single byte that leads to a + // different state! + if (prog_->can_prefix_accel() && + !params->anchored && + params->start > SpecialStateMax && + params->start->flag_ >> kFlagNeedShift == 0) + params->can_prefix_accel = true; + if (ExtraDebug) - fprintf(stderr, "anchored=%d fwd=%d flags=%#x state=%s first_byte=%d\n", + fprintf(stderr, "anchored=%d fwd=%d flags=%#x state=%s can_prefix_accel=%d\n", params->anchored, params->run_forward, flags, - DumpState(info->start).c_str(), info->first_byte.load()); - - params->start = info->start; - params->first_byte = info->first_byte.load(std::memory_order_acquire); + DumpState(params->start).c_str(), params->can_prefix_accel); return true; } @@ -1715,47 +1705,25 @@ bool DFA::AnalyzeSearch(SearchParams* params) { bool DFA::AnalyzeSearchHelper(SearchParams* params, StartInfo* info, uint32_t flags) { // Quick check. - int fb = info->first_byte.load(std::memory_order_acquire); - if (fb != kFbUnknown) + State* start = info->start.load(std::memory_order_acquire); + if (start != NULL) return true; MutexLock l(&mutex_); - fb = info->first_byte.load(std::memory_order_relaxed); - if (fb != kFbUnknown) + start = info->start.load(std::memory_order_relaxed); + if (start != NULL) return true; q0_->clear(); AddToQueue(q0_, params->anchored ? prog_->start() : prog_->start_unanchored(), flags); - info->start = WorkqToCachedState(q0_, NULL, flags); - if (info->start == NULL) + start = WorkqToCachedState(q0_, NULL, flags); + if (start == NULL) return false; - if (info->start == DeadState) { - // Synchronize with "quick check" above. - info->first_byte.store(kFbNone, std::memory_order_release); - return true; - } - - if (info->start == FullMatchState) { - // Synchronize with "quick check" above. - info->first_byte.store(kFbNone, std::memory_order_release); // will be ignored - return true; - } - - // Even if we have a first_byte, we cannot use it when anchored and, - // less obviously, we cannot use it when we are going to need flags. - // This trick works only when there is a single byte that leads to a - // different state! - int first_byte = prog_->first_byte(); - if (first_byte == -1 || - params->anchored || - info->start->flag_ >> kFlagNeedShift != 0) - first_byte = kFbNone; - // Synchronize with "quick check" above. - info->first_byte.store(first_byte, std::memory_order_release); + info->start.store(start, std::memory_order_release); return true; } @@ -1863,15 +1831,15 @@ bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context, StringPiece context = const_context; if (context.data() == NULL) context = text; - bool carat = anchor_start(); + bool caret = anchor_start(); bool dollar = anchor_end(); if (reversed_) { using std::swap; - swap(carat, dollar); + swap(caret, dollar); } - if (carat && context.begin() != text.begin()) + if (caret && BeginPtr(context) != BeginPtr(text)) return false; - if (dollar && context.end() != text.end()) + if (dollar && EndPtr(context) != EndPtr(text)) return false; // Handle full match by running an anchored longest match @@ -1904,8 +1872,12 @@ bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context, bool matched = dfa->Search(text, context, anchored, want_earliest_match, !reversed_, failed, &ep, matches); - if (*failed) + if (*failed) { + hooks::GetDFASearchFailureHook()({ + // Nothing yet... + }); return false; + } if (!matched) return false; if (endmatch && ep != (reversed_ ? text.data() : text.data() + text.size())) @@ -1998,10 +1970,6 @@ int Prog::BuildEntireDFA(MatchKind kind, const DFAStateCallback& cb) { return GetDFA(kind)->BuildAllStates(cb); } -void Prog::TEST_dfa_should_bail_when_slow(bool b) { - dfa_should_bail_when_slow = b; -} - // Computes min and max for matching string. // Won't return strings bigger than maxlen. bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) { diff --git a/re2/filtered_re2.cc b/re2/filtered_re2.cc index e5d8de5..5df9745 100644 --- a/re2/filtered_re2.cc +++ b/re2/filtered_re2.cc @@ -6,6 +6,7 @@ #include #include +#include #include "util/util.h" #include "util/logging.h" @@ -27,7 +28,22 @@ FilteredRE2::FilteredRE2(int min_atom_len) FilteredRE2::~FilteredRE2() { for (size_t i = 0; i < re2_vec_.size(); i++) delete re2_vec_[i]; - delete prefilter_tree_; +} + +FilteredRE2::FilteredRE2(FilteredRE2&& other) + : re2_vec_(std::move(other.re2_vec_)), + compiled_(other.compiled_), + prefilter_tree_(std::move(other.prefilter_tree_)) { + other.re2_vec_.clear(); + other.re2_vec_.shrink_to_fit(); + other.compiled_ = false; + other.prefilter_tree_.reset(new PrefilterTree()); +} + +FilteredRE2& FilteredRE2::operator=(FilteredRE2&& other) { + this->~FilteredRE2(); + (void) new (this) FilteredRE2(std::move(other)); + return *this; } RE2::ErrorCode FilteredRE2::Add(const StringPiece& pattern, @@ -38,7 +54,7 @@ RE2::ErrorCode FilteredRE2::Add(const StringPiece& pattern, if (!re->ok()) { if (options.log_errors()) { LOG(ERROR) << "Couldn't compile regular expression, skipping: " - << re << " due to error " << re->error(); + << pattern << " due to error " << re->error(); } delete re; } else { diff --git a/re2/filtered_re2.h b/re2/filtered_re2.h index 4118acc..dd618c7 100644 --- a/re2/filtered_re2.h +++ b/re2/filtered_re2.h @@ -10,17 +10,18 @@ // number of regexps that need to be actually searched. // // By design, it does not include a string matching engine. This is to -// allow the user of the class to use their favorite string match +// allow the user of the class to use their favorite string matching // engine. The overall flow is: Add all the regexps using Add, then -// Compile the FilteredRE2. The compile returns strings that need to -// be matched. Note that all returned strings are lowercase. For -// applying regexps to a search text, the caller does the string -// matching using the strings returned. When doing the string match, -// note that the caller has to do that on lower cased version of the -// search text. Then call FirstMatch or AllMatches with a vector of -// indices of strings that were found in the text to get the actual -// regexp matches. - +// Compile the FilteredRE2. Compile returns strings that need to be +// matched. Note that the returned strings are lowercased and distinct. +// For applying regexps to a search text, the caller does the string +// matching using the returned strings. When doing the string match, +// note that the caller has to do that in a case-insensitive way or +// on a lowercased version of the search text. Then call FirstMatch +// or AllMatches with a vector of indices of strings that were found +// in the text to get the actual regexp matches. + +#include #include #include @@ -36,18 +37,25 @@ class FilteredRE2 { explicit FilteredRE2(int min_atom_len); ~FilteredRE2(); + // Not copyable. + FilteredRE2(const FilteredRE2&) = delete; + FilteredRE2& operator=(const FilteredRE2&) = delete; + // Movable. + FilteredRE2(FilteredRE2&& other); + FilteredRE2& operator=(FilteredRE2&& other); + // Uses RE2 constructor to create a RE2 object (re). Returns // re->error_code(). If error_code is other than NoError, then re is // deleted and not added to re2_vec_. RE2::ErrorCode Add(const StringPiece& pattern, const RE2::Options& options, - int *id); + int* id); // Prepares the regexps added by Add for filtering. Returns a set // of strings that the caller should check for in candidate texts. - // The returned strings are lowercased. When doing string matching, - // the search text should be lowercased first to find matching - // strings from the set of strings returned by Compile. Call after + // The returned strings are lowercased and distinct. When doing + // string matching, it should be performed in a case-insensitive + // way or the search text should be lowercased first. Call after // all Add calls are done. void Compile(std::vector* strings_to_match); @@ -98,10 +106,7 @@ class FilteredRE2 { bool compiled_; // An AND-OR tree of string atoms used for filtering regexps. - PrefilterTree* prefilter_tree_; - - FilteredRE2(const FilteredRE2&) = delete; - FilteredRE2& operator=(const FilteredRE2&) = delete; + std::unique_ptr prefilter_tree_; }; } // namespace re2 diff --git a/re2/fuzzing/compiler-rt/LICENSE b/re2/fuzzing/compiler-rt/LICENSE new file mode 100644 index 0000000..f9dc506 --- /dev/null +++ b/re2/fuzzing/compiler-rt/LICENSE @@ -0,0 +1,219 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +--- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + diff --git a/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h b/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h new file mode 100644 index 0000000..3e069eb --- /dev/null +++ b/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h @@ -0,0 +1,305 @@ +//===- FuzzedDataProvider.h - Utility header for fuzz targets ---*- C++ -* ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// A single header library providing an utility class to break up an array of +// bytes. Whenever run on the same input, provides the same output, as long as +// its methods are called in the same order, with the same arguments. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ +#define LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// In addition to the comments below, the API is also briefly documented at +// https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider +class FuzzedDataProvider { + public: + // |data| is an array of length |size| that the FuzzedDataProvider wraps to + // provide more granular access. |data| must outlive the FuzzedDataProvider. + FuzzedDataProvider(const uint8_t *data, size_t size) + : data_ptr_(data), remaining_bytes_(size) {} + ~FuzzedDataProvider() = default; + + // Returns a std::vector containing |num_bytes| of input data. If fewer than + // |num_bytes| of data remain, returns a shorter std::vector containing all + // of the data that's left. Can be used with any byte sized type, such as + // char, unsigned char, uint8_t, etc. + template std::vector ConsumeBytes(size_t num_bytes) { + num_bytes = std::min(num_bytes, remaining_bytes_); + return ConsumeBytes(num_bytes, num_bytes); + } + + // Similar to |ConsumeBytes|, but also appends the terminator value at the end + // of the resulting vector. Useful, when a mutable null-terminated C-string is + // needed, for example. But that is a rare case. Better avoid it, if possible, + // and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods. + template + std::vector ConsumeBytesWithTerminator(size_t num_bytes, + T terminator = 0) { + num_bytes = std::min(num_bytes, remaining_bytes_); + std::vector result = ConsumeBytes(num_bytes + 1, num_bytes); + result.back() = terminator; + return result; + } + + // Returns a std::string containing |num_bytes| of input data. Using this and + // |.c_str()| on the resulting string is the best way to get an immutable + // null-terminated C string. If fewer than |num_bytes| of data remain, returns + // a shorter std::string containing all of the data that's left. + std::string ConsumeBytesAsString(size_t num_bytes) { + static_assert(sizeof(std::string::value_type) == sizeof(uint8_t), + "ConsumeBytesAsString cannot convert the data to a string."); + + num_bytes = std::min(num_bytes, remaining_bytes_); + std::string result( + reinterpret_cast(data_ptr_), + num_bytes); + Advance(num_bytes); + return result; + } + + // Returns a number in the range [min, max] by consuming bytes from the + // input data. The value might not be uniformly distributed in the given + // range. If there's no input data left, always returns |min|. |min| must + // be less than or equal to |max|. + template T ConsumeIntegralInRange(T min, T max) { + static_assert(std::is_integral::value, "An integral type is required."); + static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type."); + + if (min > max) + abort(); + + // Use the biggest type possible to hold the range and the result. + uint64_t range = static_cast(max) - min; + uint64_t result = 0; + size_t offset = 0; + + while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 && + remaining_bytes_ != 0) { + // Pull bytes off the end of the seed data. Experimentally, this seems to + // allow the fuzzer to more easily explore the input space. This makes + // sense, since it works by modifying inputs that caused new code to run, + // and this data is often used to encode length of data read by + // |ConsumeBytes|. Separating out read lengths makes it easier modify the + // contents of the data that is actually read. + --remaining_bytes_; + result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_]; + offset += CHAR_BIT; + } + + // Avoid division by 0, in case |range + 1| results in overflow. + if (range != std::numeric_limits::max()) + result = result % (range + 1); + + return static_cast(min + result); + } + + // Returns a std::string of length from 0 to |max_length|. When it runs out of + // input data, returns what remains of the input. Designed to be more stable + // with respect to a fuzzer inserting characters than just picking a random + // length and then consuming that many bytes with |ConsumeBytes|. + std::string ConsumeRandomLengthString(size_t max_length) { + // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\" + // followed by anything else to the end of the string. As a result of this + // logic, a fuzzer can insert characters into the string, and the string + // will be lengthened to include those new characters, resulting in a more + // stable fuzzer than picking the length of a string independently from + // picking its contents. + std::string result; + + // Reserve the anticipated capaticity to prevent several reallocations. + result.reserve(std::min(max_length, remaining_bytes_)); + for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) { + char next = ConvertUnsignedToSigned(data_ptr_[0]); + Advance(1); + if (next == '\\' && remaining_bytes_ != 0) { + next = ConvertUnsignedToSigned(data_ptr_[0]); + Advance(1); + if (next != '\\') + break; + } + result += next; + } + + result.shrink_to_fit(); + return result; + } + + // Returns a std::vector containing all remaining bytes of the input data. + template std::vector ConsumeRemainingBytes() { + return ConsumeBytes(remaining_bytes_); + } + + // Returns a std::string containing all remaining bytes of the input data. + // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string + // object. + std::string ConsumeRemainingBytesAsString() { + return ConsumeBytesAsString(remaining_bytes_); + } + + // Returns a number in the range [Type's min, Type's max]. The value might + // not be uniformly distributed in the given range. If there's no input data + // left, always returns |min|. + template T ConsumeIntegral() { + return ConsumeIntegralInRange(std::numeric_limits::min(), + std::numeric_limits::max()); + } + + // Reads one byte and returns a bool, or false when no data remains. + bool ConsumeBool() { return 1 & ConsumeIntegral(); } + + // Returns a copy of the value selected from the given fixed-size |array|. + template + T PickValueInArray(const T (&array)[size]) { + static_assert(size > 0, "The array must be non empty."); + return array[ConsumeIntegralInRange(0, size - 1)]; + } + + template + T PickValueInArray(std::initializer_list list) { + // TODO(Dor1s): switch to static_assert once C++14 is allowed. + if (!list.size()) + abort(); + + return *(list.begin() + ConsumeIntegralInRange(0, list.size() - 1)); + } + + // Returns an enum value. The enum must start at 0 and be contiguous. It must + // also contain |kMaxValue| aliased to its largest (inclusive) value. Such as: + // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue }; + template T ConsumeEnum() { + static_assert(std::is_enum::value, "|T| must be an enum type."); + return static_cast(ConsumeIntegralInRange( + 0, static_cast(T::kMaxValue))); + } + + // Returns a floating point number in the range [0.0, 1.0]. If there's no + // input data left, always returns 0. + template T ConsumeProbability() { + static_assert(std::is_floating_point::value, + "A floating point type is required."); + + // Use different integral types for different floating point types in order + // to provide better density of the resulting values. + using IntegralType = + typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t, + uint64_t>::type; + + T result = static_cast(ConsumeIntegral()); + result /= static_cast(std::numeric_limits::max()); + return result; + } + + // Returns a floating point value in the range [Type's lowest, Type's max] by + // consuming bytes from the input data. If there's no input data left, always + // returns approximately 0. + template T ConsumeFloatingPoint() { + return ConsumeFloatingPointInRange(std::numeric_limits::lowest(), + std::numeric_limits::max()); + } + + // Returns a floating point value in the given range by consuming bytes from + // the input data. If there's no input data left, returns |min|. Note that + // |min| must be less than or equal to |max|. + template T ConsumeFloatingPointInRange(T min, T max) { + if (min > max) + abort(); + + T range = .0; + T result = min; + constexpr T zero(.0); + if (max > zero && min < zero && max > min + std::numeric_limits::max()) { + // The diff |max - min| would overflow the given floating point type. Use + // the half of the diff as the range and consume a bool to decide whether + // the result is in the first of the second part of the diff. + range = (max / 2.0) - (min / 2.0); + if (ConsumeBool()) { + result += range; + } + } else { + range = max - min; + } + + return result + range * ConsumeProbability(); + } + + // Reports the remaining bytes available for fuzzed input. + size_t remaining_bytes() { return remaining_bytes_; } + + private: + FuzzedDataProvider(const FuzzedDataProvider &) = delete; + FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete; + + void Advance(size_t num_bytes) { + if (num_bytes > remaining_bytes_) + abort(); + + data_ptr_ += num_bytes; + remaining_bytes_ -= num_bytes; + } + + template + std::vector ConsumeBytes(size_t size, size_t num_bytes_to_consume) { + static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type."); + + // The point of using the size-based constructor below is to increase the + // odds of having a vector object with capacity being equal to the length. + // That part is always implementation specific, but at least both libc++ and + // libstdc++ allocate the requested number of bytes in that constructor, + // which seems to be a natural choice for other implementations as well. + // To increase the odds even more, we also call |shrink_to_fit| below. + std::vector result(size); + if (size == 0) { + if (num_bytes_to_consume != 0) + abort(); + return result; + } + + std::memcpy(result.data(), data_ptr_, num_bytes_to_consume); + Advance(num_bytes_to_consume); + + // Even though |shrink_to_fit| is also implementation specific, we expect it + // to provide an additional assurance in case vector's constructor allocated + // a buffer which is larger than the actual amount of data we put inside it. + result.shrink_to_fit(); + return result; + } + + template TS ConvertUnsignedToSigned(TU value) { + static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types."); + static_assert(!std::numeric_limits::is_signed, + "Source type must be unsigned."); + + // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream. + if (std::numeric_limits::is_modulo) + return static_cast(value); + + // Avoid using implementation-defined unsigned to signer conversions. + // To learn more, see https://stackoverflow.com/questions/13150449. + if (value <= std::numeric_limits::max()) { + return static_cast(value); + } else { + constexpr auto TS_min = std::numeric_limits::min(); + return TS_min + static_cast(value - TS_min); + } + } + + const uint8_t *data_ptr_; + size_t remaining_bytes_; +}; + +#endif // LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ diff --git a/re2/fuzzing/re2_fuzzer.cc b/re2/fuzzing/re2_fuzzer.cc index 061c418..3082a76 100644 --- a/re2/fuzzing/re2_fuzzer.cc +++ b/re2/fuzzing/re2_fuzzer.cc @@ -2,47 +2,155 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include #include #include -#include -#include -#include +#include #include +#include -#include "re2/prefilter.h" #include "re2/re2.h" +#include "re2/regexp.h" +#include "re2/walker-inl.h" using re2::StringPiece; // NOT static, NOT signed. uint8_t dummy = 0; -void Test(StringPiece pattern, const RE2::Options& options, StringPiece text) { +// Walks kRegexpConcat and kRegexpAlternate subexpressions +// to determine their maximum length. +class SubexpressionWalker : public re2::Regexp::Walker { + public: + SubexpressionWalker() = default; + ~SubexpressionWalker() override = default; + + int PostVisit(re2::Regexp* re, int parent_arg, int pre_arg, + int* child_args, int nchild_args) override { + switch (re->op()) { + case re2::kRegexpConcat: + case re2::kRegexpAlternate: { + int max = nchild_args; + for (int i = 0; i < nchild_args; i++) + max = std::max(max, child_args[i]); + return max; + } + + default: + break; + } + return -1; + } + + // Should never be called: we use Walk(), not WalkExponential(). + int ShortVisit(re2::Regexp* re, int parent_arg) override { + return parent_arg; + } + + private: + SubexpressionWalker(const SubexpressionWalker&) = delete; + SubexpressionWalker& operator=(const SubexpressionWalker&) = delete; +}; + +// Walks substrings (i.e. kRegexpLiteralString subexpressions) +// to determine their maximum length... in runes, but avoiding +// overheads due to UTF-8 encoding is worthwhile when fuzzing. +class SubstringWalker : public re2::Regexp::Walker { + public: + SubstringWalker() = default; + ~SubstringWalker() override = default; + + int PostVisit(re2::Regexp* re, int parent_arg, int pre_arg, + int* child_args, int nchild_args) override { + switch (re->op()) { + case re2::kRegexpConcat: + case re2::kRegexpAlternate: + case re2::kRegexpStar: + case re2::kRegexpPlus: + case re2::kRegexpQuest: + case re2::kRegexpRepeat: + case re2::kRegexpCapture: { + int max = -1; + for (int i = 0; i < nchild_args; i++) + max = std::max(max, child_args[i]); + return max; + } + + case re2::kRegexpLiteralString: + return re->nrunes(); + + default: + break; + } + return -1; + } + + // Should never be called: we use Walk(), not WalkExponential(). + int ShortVisit(re2::Regexp* re, int parent_arg) override { + return parent_arg; + } + + private: + SubstringWalker(const SubstringWalker&) = delete; + SubstringWalker& operator=(const SubstringWalker&) = delete; +}; + +void TestOneInput(StringPiece pattern, const RE2::Options& options, + StringPiece text) { + // Crudely limit the use of ., \p, \P, \d, \D, \s, \S, \w and \W. + // Otherwise, we will waste time on inputs that have long runs of various + // character classes. The fuzzer has shown itself to be easily capable of + // generating such patterns that fall within the other limits, but result + // in timeouts nonetheless. The marginal cost is high - even more so when + // counted repetition is involved - whereas the marginal benefit is zero. + // Crudely limit the use of 'k', 'K', 's' and 'S' too because they become + // three-element character classes when case-insensitive and using UTF-8. + // TODO(junyer): Handle [:isalnum:] et al. when they start to cause pain. + int char_class = 0; + int backslash_p = 0; // very expensive, so handle specially + for (size_t i = 0; i < pattern.size(); i++) { + if (pattern[i] == '.' || + pattern[i] == 'k' || pattern[i] == 'K' || + pattern[i] == 's' || pattern[i] == 'S') + char_class++; + if (pattern[i] != '\\') + continue; + i++; + if (i >= pattern.size()) + break; + if (pattern[i] == 'p' || pattern[i] == 'P' || + pattern[i] == 'd' || pattern[i] == 'D' || + pattern[i] == 's' || pattern[i] == 'S' || + pattern[i] == 'w' || pattern[i] == 'W') + char_class++; + if (pattern[i] == 'p' || pattern[i] == 'P') + backslash_p++; + } + if (char_class > 9) + return; + if (backslash_p > 1) + return; + + // The default is 1000. Even 100 turned out to be too generous + // for fuzzing, empirically speaking, so let's try 10 instead. + re2::Regexp::FUZZING_ONLY_set_maximum_repeat_count(10); + RE2 re(pattern, options); if (!re.ok()) return; + // Don't waste time fuzzing programs with large subexpressions. + // They can cause bug reports due to fuzzer timeouts. And they + // aren't interesting for fuzzing purposes. + if (SubexpressionWalker().Walk(re.Regexp(), -1) > 9) + return; + // Don't waste time fuzzing programs with large substrings. // They can cause bug reports due to fuzzer timeouts when they // are repetitions (e.g. hundreds of NUL bytes) and matching is // unanchored. And they aren't interesting for fuzzing purposes. - std::unique_ptr prefilter(re2::Prefilter::FromRE2(&re)); - if (prefilter == nullptr) + if (SubstringWalker().Walk(re.Regexp(), -1) > 9) return; - std::queue nodes; - nodes.push(prefilter.get()); - while (!nodes.empty()) { - re2::Prefilter* node = nodes.front(); - nodes.pop(); - if (node->op() == re2::Prefilter::ATOM) { - if (node->atom().size() > 9) - return; - } else if (node->op() == re2::Prefilter::AND || - node->op() == re2::Prefilter::OR) { - for (re2::Prefilter* sub : *node->subs()) - nodes.push(sub); - } - } // Don't waste time fuzzing high-size programs. // They can cause bug reports due to fuzzer timeouts. @@ -55,7 +163,7 @@ void Test(StringPiece pattern, const RE2::Options& options, StringPiece text) { // Don't waste time fuzzing high-fanout programs. // They can cause bug reports due to fuzzer timeouts. - std::map histogram; + std::vector histogram; int fanout = re.ProgramFanout(&histogram); if (fanout > 9) return; @@ -102,72 +210,38 @@ void Test(StringPiece pattern, const RE2::Options& options, StringPiece text) { // Entry point for libFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - if (size == 0 || size > 999) - return 0; - - // Crudely limit the use of ., \p, \P, \d, \D, \s, \S, \w and \W. - // Otherwise, we will waste time on inputs that have long runs of various - // character classes. The fuzzer has shown itself to be easily capable of - // generating such patterns that fall within the other limits, but result - // in timeouts nonetheless. The marginal cost is high - even more so when - // counted repetition is involved - whereas the marginal benefit is zero. - // TODO(junyer): Handle [:isalnum:] et al. when they start to cause pain. - int char_class = 0; - int backslash_p = 0; // very expensive, so handle specially - for (size_t i = 0; i < size; i++) { - if (data[i] == '.') - char_class++; - if (data[i] != '\\') - continue; - i++; - if (i >= size) - break; - if (data[i] == 'p' || data[i] == 'P' || - data[i] == 'd' || data[i] == 'D' || - data[i] == 's' || data[i] == 'S' || - data[i] == 'w' || data[i] == 'W') - char_class++; - if (data[i] == 'p' || data[i] == 'P') - backslash_p++; - } - if (char_class > 9) - return 0; - if (backslash_p > 1) + // An input larger than 4 KiB probably isn't interesting. (This limit + // allows for fdp.ConsumeRandomLengthString()'s backslash behaviour.) + if (size == 0 || size > 4096) return 0; - // The one-at-a-time hash by Bob Jenkins. - uint32_t hash = 0; - for (size_t i = 0; i < size; i++) { - hash += data[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); + FuzzedDataProvider fdp(data, size); + // The convention here is that fdp.ConsumeBool() returning false sets + // the default value whereas returning true sets the alternate value: + // most options default to false and so can be set directly; encoding + // defaults to UTF-8; case_sensitive defaults to true. We do NOT want + // to log errors. max_mem is 64 MiB because we can afford to use more + // RAM in exchange for (hopefully) faster fuzzing. RE2::Options options; + options.set_encoding(fdp.ConsumeBool() ? RE2::Options::EncodingLatin1 + : RE2::Options::EncodingUTF8); + options.set_posix_syntax(fdp.ConsumeBool()); + options.set_longest_match(fdp.ConsumeBool()); options.set_log_errors(false); options.set_max_mem(64 << 20); - options.set_encoding(hash & 1 ? RE2::Options::EncodingLatin1 - : RE2::Options::EncodingUTF8); - options.set_posix_syntax(hash & 2); - options.set_longest_match(hash & 4); - options.set_literal(hash & 8); - options.set_never_nl(hash & 16); - options.set_dot_nl(hash & 32); - options.set_never_capture(hash & 64); - options.set_case_sensitive(hash & 128); - options.set_perl_classes(hash & 256); - options.set_word_boundary(hash & 512); - options.set_one_line(hash & 1024); - - const char* ptr = reinterpret_cast(data); - int len = static_cast(size); - - StringPiece pattern(ptr, len); - StringPiece text(ptr, len); - Test(pattern, options, text); - + options.set_literal(fdp.ConsumeBool()); + options.set_never_nl(fdp.ConsumeBool()); + options.set_dot_nl(fdp.ConsumeBool()); + options.set_never_capture(fdp.ConsumeBool()); + options.set_case_sensitive(!fdp.ConsumeBool()); + options.set_perl_classes(fdp.ConsumeBool()); + options.set_word_boundary(fdp.ConsumeBool()); + options.set_one_line(fdp.ConsumeBool()); + + std::string pattern = fdp.ConsumeRandomLengthString(999); + std::string text = fdp.ConsumeRandomLengthString(999); + + TestOneInput(pattern, options, text); return 0; } diff --git a/re2/make_perl_groups.pl b/re2/make_perl_groups.pl index d9fcdaf..ed0d509 100755 --- a/re2/make_perl_groups.pl +++ b/re2/make_perl_groups.pl @@ -76,7 +76,7 @@ sub PrintClass($$@) { } else { $negname =~ y/a-z/A-Z/; } - return "{ \"$escname\", +1, code$cnum, $n }", "{ \"$negname\", -1, code$cnum, $n }"; + return "{ \"$escname\", +1, code$cnum, $n, 0, 0 }", "{ \"$negname\", -1, code$cnum, $n, 0, 0 }"; } my $cnum = 0; diff --git a/re2/mimics_pcre.cc b/re2/mimics_pcre.cc index ad197be..b1d6a51 100644 --- a/re2/mimics_pcre.cc +++ b/re2/mimics_pcre.cc @@ -38,14 +38,21 @@ static bool CanBeEmptyString(Regexp *re); class PCREWalker : public Regexp::Walker { public: PCREWalker() {} - bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, bool* child_args, - int nchild_args); - bool ShortVisit(Regexp* re, bool a) { - // Should never be called: we use Walk not WalkExponential. - LOG(DFATAL) << "EmptyStringWalker::ShortVisit called"; + virtual bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, + bool* child_args, int nchild_args); + + virtual bool ShortVisit(Regexp* re, bool a) { + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + LOG(DFATAL) << "PCREWalker::ShortVisit called"; +#endif return a; } + + private: + PCREWalker(const PCREWalker&) = delete; + PCREWalker& operator=(const PCREWalker&) = delete; }; // Called after visiting each of re's children and accumulating @@ -114,13 +121,16 @@ bool Regexp::MimicsPCRE() { class EmptyStringWalker : public Regexp::Walker { public: - EmptyStringWalker() { } - bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, - bool* child_args, int nchild_args); + EmptyStringWalker() {} + + virtual bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, + bool* child_args, int nchild_args); - bool ShortVisit(Regexp* re, bool a) { - // Should never be called: we use Walk not WalkExponential. + virtual bool ShortVisit(Regexp* re, bool a) { + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "EmptyStringWalker::ShortVisit called"; +#endif return a; } diff --git a/re2/nfa.cc b/re2/nfa.cc index 77fb5fb..c7339f8 100644 --- a/re2/nfa.cc +++ b/re2/nfa.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -107,18 +108,21 @@ class NFA { // Returns text version of capture information, for debugging. std::string FormatCapture(const char** capture); - inline void CopyCapture(const char** dst, const char** src); + void CopyCapture(const char** dst, const char** src) { + memmove(dst, src, ncapture_*sizeof src[0]); + } Prog* prog_; // underlying program int start_; // start instruction in program int ncapture_; // number of submatches to track bool longest_; // whether searching for longest match bool endmatch_; // whether match must end at text.end() - const char* btext_; // beginning of text being matched (for FormatSubmatch) - const char* etext_; // end of text being matched (for endmatch_) + const char* btext_; // beginning of text (for FormatSubmatch) + const char* etext_; // end of text (for endmatch_) Threadq q0_, q1_; // pre-allocated for Search. PODArray stack_; // pre-allocated for AddToThreadq - Thread* free_threads_; // free list + std::deque arena_; // thread arena + Thread* freelist_; // thread freelist const char** match_; // best match so far bool matched_; // any match so far? @@ -141,31 +145,30 @@ NFA::NFA(Prog* prog) { prog_->inst_count(kInstEmptyWidth) + prog_->inst_count(kInstNop) + 1; // + 1 for start inst stack_ = PODArray(nstack); - free_threads_ = NULL; + freelist_ = NULL; match_ = NULL; matched_ = false; } NFA::~NFA() { delete[] match_; - Thread* next; - for (Thread* t = free_threads_; t; t = next) { - next = t->next; - delete[] t->capture; - delete t; - } + for (const Thread& t : arena_) + delete[] t.capture; } NFA::Thread* NFA::AllocThread() { - Thread* t = free_threads_; - if (t == NULL) { - t = new Thread; + Thread* t = freelist_; + if (t != NULL) { + freelist_ = t->next; t->ref = 1; - t->capture = new const char*[ncapture_]; + // We don't need to touch t->capture because + // the caller will immediately overwrite it. return t; } - free_threads_ = t->next; + arena_.emplace_back(); + t = &arena_.back(); t->ref = 1; + t->capture = new const char*[ncapture_]; return t; } @@ -176,21 +179,13 @@ NFA::Thread* NFA::Incref(Thread* t) { } void NFA::Decref(Thread* t) { - if (t == NULL) - return; + DCHECK(t != NULL); t->ref--; if (t->ref > 0) return; DCHECK_EQ(t->ref, 0); - t->next = free_threads_; - free_threads_ = t; -} - -void NFA::CopyCapture(const char** dst, const char** src) { - for (int i = 0; i < ncapture_; i+=2) { - dst[i] = src[i]; - dst[i+1] = src[i+1]; - } + t->next = freelist_; + freelist_ = t; } // Follows all empty arrows from id0 and enqueues all the states reached. @@ -372,8 +367,10 @@ int NFA::Step(Threadq* runq, Threadq* nextq, int c, const StringPiece& context, matched_ = true; Decref(t); - for (++i; i != runq->end(); ++i) - Decref(i->value()); + for (++i; i != runq->end(); ++i) { + if (i->value() != NULL) + Decref(i->value()); + } runq->clear(); if (ip->greedy(prog_)) return ip->out1(); @@ -416,8 +413,10 @@ int NFA::Step(Threadq* runq, Threadq* nextq, int c, const StringPiece& context, // worse than the one we just found: don't run the // rest of the current Threadq. Decref(t); - for (++i; i != runq->end(); ++i) - Decref(i->value()); + for (++i; i != runq->end(); ++i) { + if (i->value() != NULL) + Decref(i->value()); + } runq->clear(); return 0; } @@ -457,14 +456,14 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, context = text; // Sanity check: make sure that text lies within context. - if (text.begin() < context.begin() || text.end() > context.end()) { + if (BeginPtr(text) < BeginPtr(context) || EndPtr(text) > EndPtr(context)) { LOG(DFATAL) << "context does not contain text"; return false; } - if (prog_->anchor_start() && context.begin() != text.begin()) + if (prog_->anchor_start() && BeginPtr(context) != BeginPtr(text)) return false; - if (prog_->anchor_end() && context.end() != text.end()) + if (prog_->anchor_end() && EndPtr(context) != EndPtr(text)) return false; anchored |= prog_->anchor_start(); if (prog_->anchor_end()) { @@ -489,6 +488,7 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, } match_ = new const char*[ncapture_]; + memset(match_, 0, ncapture_*sizeof match_[0]); matched_ = false; // For debugging prints. @@ -505,7 +505,6 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, Threadq* nextq = &q1_; runq->clear(); nextq->clear(); - memset(&match_[0], 0, ncapture_*sizeof match_[0]); // Loop over the text, stepping the machine. for (const char* p = text.data();; p++) { @@ -572,16 +571,14 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, // matches, since it would be to the right of the match // we already found.) if (!matched_ && (!anchored || p == text.data())) { - // If there's a required first byte for an unanchored search - // and we're not in the middle of any possible matches, - // use memchr to search for the byte quickly. - int fb = prog_->first_byte(); + // Try to use prefix accel (e.g. memchr) to skip ahead. + // The search must be unanchored and there must be zero + // possible matches already. if (!anchored && runq->size() == 0 && - fb >= 0 && p < etext_ && (p[0] & 0xFF) != fb) { - p = reinterpret_cast(memchr(p, fb, etext_ - p)); - if (p == NULL) { + p < etext_ && prog_->can_prefix_accel()) { + p = reinterpret_cast(prog_->PrefixAccel(p, etext_ - p)); + if (p == NULL) p = etext_; - } } Thread* t = AllocThread(); @@ -603,7 +600,7 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, // by simply not continuing the loop. // This complements the special case in NFA::Step(). if (p == NULL) { - (void)Step(runq, nextq, p < etext_ ? p[0] & 0xFF : -1, context, p); + (void) Step(runq, nextq, -1, context, p); DCHECK_EQ(runq->size(), 0); using std::swap; swap(nextq, runq); @@ -612,8 +609,10 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, } } - for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i) - Decref(i->value()); + for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i) { + if (i->value() != NULL) + Decref(i->value()); + } if (matched_) { for (int i = 0; i < nsubmatch; i++) @@ -629,67 +628,6 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context, return false; } -// Computes whether all successful matches have a common first byte, -// and if so, returns that byte. If not, returns -1. -int Prog::ComputeFirstByte() { - int b = -1; - SparseSet q(size()); - q.insert(start()); - for (SparseSet::iterator it = q.begin(); it != q.end(); ++it) { - int id = *it; - Prog::Inst* ip = inst(id); - switch (ip->opcode()) { - default: - LOG(DFATAL) << "unhandled " << ip->opcode() << " in ComputeFirstByte"; - break; - - case kInstMatch: - // The empty string matches: no first byte. - return -1; - - case kInstByteRange: - if (!ip->last()) - q.insert(id+1); - - // Must match only a single byte - if (ip->lo() != ip->hi()) - return -1; - if (ip->foldcase() && 'a' <= ip->lo() && ip->lo() <= 'z') - return -1; - // If we haven't seen any bytes yet, record it; - // otherwise must match the one we saw before. - if (b == -1) - b = ip->lo(); - else if (b != ip->lo()) - return -1; - break; - - case kInstNop: - case kInstCapture: - case kInstEmptyWidth: - if (!ip->last()) - q.insert(id+1); - - // Continue on. - // Ignore ip->empty() flags for kInstEmptyWidth - // in order to be as conservative as possible - // (assume all possible empty-width flags are true). - if (ip->out()) - q.insert(ip->out()); - break; - - case kInstAltMatch: - DCHECK(!ip->last()); - q.insert(id+1); - break; - - case kInstFail: - break; - } - } - return b; -} - bool Prog::SearchNFA(const StringPiece& text, const StringPiece& context, Anchor anchor, MatchKind kind, @@ -708,7 +646,7 @@ Prog::SearchNFA(const StringPiece& text, const StringPiece& context, } if (!nfa.Search(text, context, anchor == kAnchored, kind != kFirstMatch, match, nmatch)) return false; - if (kind == kFullMatch && match[0].end() != text.end()) + if (kind == kFullMatch && EndPtr(match[0]) != EndPtr(text)) return false; return true; } diff --git a/re2/onepass.cc b/re2/onepass.cc index 66a62d9..2639746 100644 --- a/re2/onepass.cc +++ b/re2/onepass.cc @@ -237,9 +237,9 @@ bool Prog::SearchOnePass(const StringPiece& text, StringPiece context = const_context; if (context.data() == NULL) context = text; - if (anchor_start() && context.begin() != text.begin()) + if (anchor_start() && BeginPtr(context) != BeginPtr(text)) return false; - if (anchor_end() && context.end() != text.end()) + if (anchor_end() && EndPtr(context) != EndPtr(text)) return false; if (anchor_end()) kind = kFullMatch; diff --git a/re2/parse.cc b/re2/parse.cc index 50dfdac..85f16f0 100644 --- a/re2/parse.cc +++ b/re2/parse.cc @@ -44,12 +44,12 @@ namespace re2 { -// Reduce the maximum repeat count by an order of magnitude when fuzzing. -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -static const int kMaxRepeat = 100; -#else -static const int kMaxRepeat = 1000; -#endif +// Controls the maximum repeat count permitted by the parser. +static int maximum_repeat_count = 1000; + +void Regexp::FUZZING_ONLY_set_maximum_repeat_count(int i) { + maximum_repeat_count = i; +} // Regular expression parse state. // The list of parsed regexps so far is maintained as a vector of @@ -93,7 +93,7 @@ class Regexp::ParseState { bool PushSimpleOp(RegexpOp op); // Pushes a ^ onto the stack. - bool PushCarat(); + bool PushCaret(); // Pushes a \b (word == true) or \B (word == false) onto the stack. bool PushWordBoundary(bool word); @@ -423,7 +423,7 @@ bool Regexp::ParseState::PushLiteral(Rune r) { } // Pushes a ^ onto the stack. -bool Regexp::ParseState::PushCarat() { +bool Regexp::ParseState::PushCaret() { if (flags_ & OneLine) { return PushSimpleOp(kRegexpBeginText); } @@ -556,9 +556,10 @@ int RepetitionWalker::PostVisit(Regexp* re, int parent_arg, int pre_arg, } int RepetitionWalker::ShortVisit(Regexp* re, int parent_arg) { - // This should never be called, since we use Walk and not - // WalkExponential. + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "RepetitionWalker::ShortVisit called"; +#endif return 0; } @@ -567,7 +568,9 @@ int RepetitionWalker::ShortVisit(Regexp* re, int parent_arg) { bool Regexp::ParseState::PushRepetition(int min, int max, const StringPiece& s, bool nongreedy) { - if ((max != -1 && max < min) || min > kMaxRepeat || max > kMaxRepeat) { + if ((max != -1 && max < min) || + min > maximum_repeat_count || + max > maximum_repeat_count) { status_->set_code(kRegexpRepeatSize); status_->set_error_arg(s); return false; @@ -590,7 +593,7 @@ bool Regexp::ParseState::PushRepetition(int min, int max, stacktop_ = re; if (min >= 2 || max >= 2) { RepetitionWalker w; - if (w.Walk(stacktop_, kMaxRepeat) == 0) { + if (w.Walk(stacktop_, maximum_repeat_count) == 0) { status_->set_code(kRegexpRepeatSize); status_->set_error_arg(s); return false; @@ -684,7 +687,7 @@ bool Regexp::ParseState::DoRightParen() { if ((r1 = stacktop_) == NULL || (r2 = r1->down_) == NULL || r2->op() != kLeftParen) { - status_->set_code(kRegexpMissingParen); + status_->set_code(kRegexpUnexpectedParen); status_->set_error_arg(whole_regexp_); return false; } @@ -1406,13 +1409,15 @@ static int StringPieceToRune(Rune *r, StringPiece *sp, RegexpStatus* status) { } } - status->set_code(kRegexpBadUTF8); - status->set_error_arg(StringPiece()); + if (status != NULL) { + status->set_code(kRegexpBadUTF8); + status->set_error_arg(StringPiece()); + } return -1; } -// Return whether name is valid UTF-8. -// If not, set status to kRegexpBadUTF8. +// Returns whether name is valid UTF-8. +// If not, sets status to kRegexpBadUTF8. static bool IsValidUTF8(const StringPiece& s, RegexpStatus* status) { StringPiece t = s; Rune r; @@ -1801,14 +1806,13 @@ ParseStatus ParseUnicodeGroup(StringPiece* s, Regexp::ParseFlags parse_flags, // Convert the UnicodeSet to a URange32 and UGroup that we can add. int nr = uset.getRangeCount(); - URange32* r = new URange32[nr]; + PODArray r(nr); for (int i = 0; i < nr; i++) { r[i].lo = uset.getRangeStart(i); r[i].hi = uset.getRangeEnd(i); } - UGroup g = {"", +1, 0, 0, r, nr}; + UGroup g = {"", +1, 0, 0, r.data(), nr}; AddUGroup(cc, &g, sign, parse_flags); - delete[] r; #endif return kParseOk; @@ -2011,19 +2015,34 @@ bool Regexp::ParseState::ParseCharClass(StringPiece* s, return true; } -// Is this a valid capture name? [A-Za-z0-9_]+ -// PCRE limits names to 32 bytes. -// Python rejects names starting with digits. -// We don't enforce either of those. +// Returns whether name is a valid capture name. static bool IsValidCaptureName(const StringPiece& name) { if (name.empty()) return false; - for (size_t i = 0; i < name.size(); i++) { - int c = name[i]; - if (('0' <= c && c <= '9') || - ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - c == '_') + + // Historically, we effectively used [0-9A-Za-z_]+ to validate; that + // followed Python 2 except for not restricting the first character. + // As of Python 3, Unicode characters beyond ASCII are also allowed; + // accordingly, we permit the Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd and + // Pc categories, but again without restricting the first character. + // Also, Unicode normalization (e.g. NFKC) isn't performed: Python 3 + // performs it for identifiers, but seemingly not for capture names; + // if they start doing that for capture names, we won't follow suit. + static const CharClass* const cc = []() { + CharClassBuilder ccb; + for (StringPiece group : + {"Lu", "Ll", "Lt", "Lm", "Lo", "Nl", "Mn", "Mc", "Nd", "Pc"}) + AddUGroup(&ccb, LookupGroup(group, unicode_groups, num_unicode_groups), + +1, Regexp::NoParseFlags); + return ccb.GetCharClass(); + }(); + + StringPiece t = name; + Rune r; + while (!t.empty()) { + if (StringPieceToRune(&r, &t, NULL) < 0) + return false; + if (cc->Contains(r)) continue; return false; } @@ -2271,7 +2290,7 @@ Regexp* Regexp::Parse(const StringPiece& s, ParseFlags global_flags, break; case '^': // Beginning of line. - if (!ps.PushCarat()) + if (!ps.PushCaret()) return NULL; t.remove_prefix(1); // '^' break; diff --git a/re2/perl_groups.cc b/re2/perl_groups.cc index 422b388..4687444 100644 --- a/re2/perl_groups.cc +++ b/re2/perl_groups.cc @@ -20,12 +20,12 @@ static const URange16 code3[] = { /* \w */ { 0x61, 0x7a }, }; const UGroup perl_groups[] = { - { "\\d", +1, code1, 1 }, - { "\\D", -1, code1, 1 }, - { "\\s", +1, code2, 3 }, - { "\\S", -1, code2, 3 }, - { "\\w", +1, code3, 4 }, - { "\\W", -1, code3, 4 }, + { "\\d", +1, code1, 1, 0, 0 }, + { "\\D", -1, code1, 1, 0, 0 }, + { "\\s", +1, code2, 3, 0, 0 }, + { "\\S", -1, code2, 3, 0, 0 }, + { "\\w", +1, code3, 4, 0, 0 }, + { "\\W", -1, code3, 4, 0, 0 }, }; const int num_perl_groups = 6; static const URange16 code4[] = { /* [:alnum:] */ @@ -85,34 +85,34 @@ static const URange16 code17[] = { /* [:xdigit:] */ { 0x61, 0x66 }, }; const UGroup posix_groups[] = { - { "[:alnum:]", +1, code4, 3 }, - { "[:^alnum:]", -1, code4, 3 }, - { "[:alpha:]", +1, code5, 2 }, - { "[:^alpha:]", -1, code5, 2 }, - { "[:ascii:]", +1, code6, 1 }, - { "[:^ascii:]", -1, code6, 1 }, - { "[:blank:]", +1, code7, 2 }, - { "[:^blank:]", -1, code7, 2 }, - { "[:cntrl:]", +1, code8, 2 }, - { "[:^cntrl:]", -1, code8, 2 }, - { "[:digit:]", +1, code9, 1 }, - { "[:^digit:]", -1, code9, 1 }, - { "[:graph:]", +1, code10, 1 }, - { "[:^graph:]", -1, code10, 1 }, - { "[:lower:]", +1, code11, 1 }, - { "[:^lower:]", -1, code11, 1 }, - { "[:print:]", +1, code12, 1 }, - { "[:^print:]", -1, code12, 1 }, - { "[:punct:]", +1, code13, 4 }, - { "[:^punct:]", -1, code13, 4 }, - { "[:space:]", +1, code14, 2 }, - { "[:^space:]", -1, code14, 2 }, - { "[:upper:]", +1, code15, 1 }, - { "[:^upper:]", -1, code15, 1 }, - { "[:word:]", +1, code16, 4 }, - { "[:^word:]", -1, code16, 4 }, - { "[:xdigit:]", +1, code17, 3 }, - { "[:^xdigit:]", -1, code17, 3 }, + { "[:alnum:]", +1, code4, 3, 0, 0 }, + { "[:^alnum:]", -1, code4, 3, 0, 0 }, + { "[:alpha:]", +1, code5, 2, 0, 0 }, + { "[:^alpha:]", -1, code5, 2, 0, 0 }, + { "[:ascii:]", +1, code6, 1, 0, 0 }, + { "[:^ascii:]", -1, code6, 1, 0, 0 }, + { "[:blank:]", +1, code7, 2, 0, 0 }, + { "[:^blank:]", -1, code7, 2, 0, 0 }, + { "[:cntrl:]", +1, code8, 2, 0, 0 }, + { "[:^cntrl:]", -1, code8, 2, 0, 0 }, + { "[:digit:]", +1, code9, 1, 0, 0 }, + { "[:^digit:]", -1, code9, 1, 0, 0 }, + { "[:graph:]", +1, code10, 1, 0, 0 }, + { "[:^graph:]", -1, code10, 1, 0, 0 }, + { "[:lower:]", +1, code11, 1, 0, 0 }, + { "[:^lower:]", -1, code11, 1, 0, 0 }, + { "[:print:]", +1, code12, 1, 0, 0 }, + { "[:^print:]", -1, code12, 1, 0, 0 }, + { "[:punct:]", +1, code13, 4, 0, 0 }, + { "[:^punct:]", -1, code13, 4, 0, 0 }, + { "[:space:]", +1, code14, 2, 0, 0 }, + { "[:^space:]", -1, code14, 2, 0, 0 }, + { "[:upper:]", +1, code15, 1, 0, 0 }, + { "[:^upper:]", -1, code15, 1, 0, 0 }, + { "[:word:]", +1, code16, 4, 0, 0 }, + { "[:^word:]", -1, code16, 4, 0, 0 }, + { "[:xdigit:]", +1, code17, 3, 0, 0 }, + { "[:^xdigit:]", -1, code17, 3, 0, 0 }, }; const int num_posix_groups = 28; diff --git a/re2/pod_array.h b/re2/pod_array.h index e8093ad..f234e97 100644 --- a/re2/pod_array.h +++ b/re2/pod_array.h @@ -13,7 +13,7 @@ namespace re2 { template class PODArray { public: - static_assert(std::is_pod::value, + static_assert(std::is_trivial::value && std::is_standard_layout::value, "T must be POD"); PODArray() diff --git a/re2/prefilter.cc b/re2/prefilter.cc index f61d54b..a47b312 100644 --- a/re2/prefilter.cc +++ b/re2/prefilter.cc @@ -648,14 +648,15 @@ Prefilter* Prefilter::FromRegexp(Regexp* re) { return NULL; Regexp* simple = re->Simplify(); - Prefilter::Info *info = BuildInfo(simple); + if (simple == NULL) + return NULL; + Prefilter::Info* info = BuildInfo(simple); simple->Decref(); if (info == NULL) return NULL; Prefilter* m = info->TakeMatch(); - delete info; return m; } diff --git a/re2/prefilter_tree.cc b/re2/prefilter_tree.cc index 187e2ec..fdf4e08 100644 --- a/re2/prefilter_tree.cc +++ b/re2/prefilter_tree.cc @@ -107,7 +107,7 @@ void PrefilterTree::Compile(std::vector* atom_vec) { Prefilter* PrefilterTree::CanonicalNode(NodeMap* nodes, Prefilter* node) { std::string node_string = NodeString(node); - std::map::iterator iter = nodes->find(node_string); + NodeMap::iterator iter = nodes->find(node_string); if (iter == nodes->end()) return NULL; return (*iter).second; @@ -377,7 +377,7 @@ void PrefilterTree::PrintDebugInfo(NodeMap* nodes) { LOG(ERROR) << it->first; } LOG(ERROR) << "Map:"; - for (std::map::const_iterator iter = nodes->begin(); + for (NodeMap::const_iterator iter = nodes->begin(); iter != nodes->end(); ++iter) LOG(ERROR) << "NodeId: " << (*iter).second->unique_id() << " Str: " << (*iter).first; diff --git a/re2/prog.cc b/re2/prog.cc index cc35917..55dc105 100644 --- a/re2/prog.cc +++ b/re2/prog.cc @@ -7,6 +7,12 @@ #include "re2/prog.h" +#if defined(__AVX2__) +#include +#ifdef _MSC_VER +#include +#endif +#endif #include #include #include @@ -109,9 +115,10 @@ Prog::Prog() start_unanchored_(0), size_(0), bytemap_range_(0), - first_byte_(-1), - flags_(0), + prefix_foldcase_(false), + prefix_size_(0), list_count_(0), + bit_state_text_max_size_(0), dfa_mem_(0), dfa_first_(NULL), dfa_longest_(NULL) { @@ -120,6 +127,8 @@ Prog::Prog() Prog::~Prog() { DeleteDFA(dfa_longest_); DeleteDFA(dfa_first_); + if (prefix_foldcase_) + delete[] prefix_dfa_; } typedef SparseSet Workq; @@ -185,14 +194,31 @@ std::string Prog::DumpByteMap() { return map; } -int Prog::first_byte() { - std::call_once(first_byte_once_, [](Prog* prog) { - prog->first_byte_ = prog->ComputeFirstByte(); - }, this); - return first_byte_; -} +// Is ip a guaranteed match at end of text, perhaps after some capturing? +static bool IsMatch(Prog* prog, Prog::Inst* ip) { + for (;;) { + switch (ip->opcode()) { + default: + LOG(DFATAL) << "Unexpected opcode in IsMatch: " << ip->opcode(); + return false; + + case kInstAlt: + case kInstAltMatch: + case kInstByteRange: + case kInstFail: + case kInstEmptyWidth: + return false; + + case kInstCapture: + case kInstNop: + ip = prog->inst(ip->out()); + break; -static bool IsMatch(Prog*, Prog::Inst*); + case kInstMatch: + return true; + } + } +} // Peep-hole optimizer. void Prog::Optimize() { @@ -258,32 +284,6 @@ void Prog::Optimize() { } } -// Is ip a guaranteed match at end of text, perhaps after some capturing? -static bool IsMatch(Prog* prog, Prog::Inst* ip) { - for (;;) { - switch (ip->opcode()) { - default: - LOG(DFATAL) << "Unexpected opcode in IsMatch: " << ip->opcode(); - return false; - - case kInstAlt: - case kInstAltMatch: - case kInstByteRange: - case kInstFail: - case kInstEmptyWidth: - return false; - - case kInstCapture: - case kInstNop: - ip = prog->inst(ip->out()); - break; - - case kInstMatch: - return true; - } - } -} - uint32_t Prog::EmptyFlags(const StringPiece& text, const char* p) { int flags = 0; @@ -641,6 +641,11 @@ void Prog::Flatten() { for (int i = 0; i < list_count_; ++i) list_heads_[flatmap[i]] = i; } + + // BitState allocates a bitmap of size list_count_ * (text.size()+1) + // for tracking pairs of possibilities that it has already explored. + const size_t kBitStateBitmapMaxSize = 256*1024; // max size in bits + bit_state_text_max_size_ = kBitStateBitmapMaxSize / list_count_ - 1; } void Prog::MarkSuccessors(SparseArray* rootmap, @@ -918,4 +923,250 @@ void Prog::ComputeHints(std::vector* flat, int begin, int end) { } } +// The final state will always be this, which frees up a register for the hot +// loop and thus avoids the spilling that can occur when building with Clang. +static const size_t kShiftDFAFinal = 9; + +// This function takes the prefix as std::string (i.e. not const std::string& +// as normal) because it's going to clobber it, so a temporary is convenient. +static uint64_t* BuildShiftDFA(std::string prefix) { + // This constant is for convenience now and also for correctness later when + // we clobber the prefix, but still need to know how long it was initially. + const size_t size = prefix.size(); + + // Construct the NFA. + // The table is indexed by input byte; each element is a bitfield of states + // reachable by the input byte. Given a bitfield of the current states, the + // bitfield of states reachable from those is - for this specific purpose - + // always ((ncurr << 1) | 1). Intersecting the reachability bitfields gives + // the bitfield of the next states reached by stepping over the input byte. + // Credits for this technique: the Hyperscan paper by Geoff Langdale et al. + uint16_t nfa[256]{}; + for (size_t i = 0; i < size; ++i) { + uint8_t b = prefix[i]; + nfa[b] |= 1 << (i+1); + } + // This is the `\C*?` for unanchored search. + for (int b = 0; b < 256; ++b) + nfa[b] |= 1; + + // This maps from DFA state to NFA states; the reverse mapping is used when + // recording transitions and gets implemented with plain old linear search. + // The "Shift DFA" technique limits this to ten states when using uint64_t; + // to allow for the initial state, we use at most nine bytes of the prefix. + // That same limit is also why uint16_t is sufficient for the NFA bitfield. + uint16_t states[kShiftDFAFinal+1]{}; + states[0] = 1; + for (size_t dcurr = 0; dcurr < size; ++dcurr) { + uint8_t b = prefix[dcurr]; + uint16_t ncurr = states[dcurr]; + uint16_t nnext = nfa[b] & ((ncurr << 1) | 1); + size_t dnext = dcurr+1; + if (dnext == size) + dnext = kShiftDFAFinal; + states[dnext] = nnext; + } + + // Sort and unique the bytes of the prefix to avoid repeating work while we + // record transitions. This clobbers the prefix, but it's no longer needed. + std::sort(prefix.begin(), prefix.end()); + prefix.erase(std::unique(prefix.begin(), prefix.end()), prefix.end()); + + // Construct the DFA. + // The table is indexed by input byte; each element is effectively a packed + // array of uint6_t; each array value will be multiplied by six in order to + // avoid having to do so later in the hot loop as well as masking/shifting. + // Credits for this technique: "Shift-based DFAs" on GitHub by Per Vognsen. + uint64_t* dfa = new uint64_t[256]{}; + // Record a transition from each state for each of the bytes of the prefix. + // Note that all other input bytes go back to the initial state by default. + for (size_t dcurr = 0; dcurr < size; ++dcurr) { + for (uint8_t b : prefix) { + uint16_t ncurr = states[dcurr]; + uint16_t nnext = nfa[b] & ((ncurr << 1) | 1); + size_t dnext = 0; + while (states[dnext] != nnext) + ++dnext; + dfa[b] |= static_cast(dnext * 6) << (dcurr * 6); + // Convert ASCII letters to uppercase and record the extra transitions. + // Note that ASCII letters are guaranteed to be lowercase at this point + // because that's how the parser normalises them. #FunFact: 'k' and 's' + // match U+212A and U+017F, respectively, so they won't occur here when + // using UTF-8 encoding because the parser will emit character classes. + if ('a' <= b && b <= 'z') { + b -= 'a' - 'A'; + dfa[b] |= static_cast(dnext * 6) << (dcurr * 6); + } + } + } + // This lets the final state "saturate", which will matter for performance: + // in the hot loop, we check for a match only at the end of each iteration, + // so we must keep signalling the match until we get around to checking it. + for (int b = 0; b < 256; ++b) + dfa[b] |= static_cast(kShiftDFAFinal * 6) << (kShiftDFAFinal * 6); + + return dfa; +} + +void Prog::ConfigurePrefixAccel(const std::string& prefix, + bool prefix_foldcase) { + prefix_foldcase_ = prefix_foldcase; + prefix_size_ = prefix.size(); + if (prefix_foldcase_) { + // Use PrefixAccel_ShiftDFA(). + // ... and no more than nine bytes of the prefix. (See above for details.) + prefix_size_ = std::min(prefix_size_, kShiftDFAFinal); + prefix_dfa_ = BuildShiftDFA(prefix.substr(0, prefix_size_)); + } else if (prefix_size_ != 1) { + // Use PrefixAccel_FrontAndBack(). + prefix_front_ = prefix.front(); + prefix_back_ = prefix.back(); + } else { + // Use memchr(3). + prefix_front_ = prefix.front(); + } +} + +const void* Prog::PrefixAccel_ShiftDFA(const void* data, size_t size) { + if (size < prefix_size_) + return NULL; + + uint64_t curr = 0; + + // At the time of writing, rough benchmarks on a Broadwell machine showed + // that this unroll factor (i.e. eight) achieves a speedup factor of two. + if (size >= 8) { + const uint8_t* p = reinterpret_cast(data); + const uint8_t* endp = p + (size&~7); + do { + uint8_t b0 = p[0]; + uint8_t b1 = p[1]; + uint8_t b2 = p[2]; + uint8_t b3 = p[3]; + uint8_t b4 = p[4]; + uint8_t b5 = p[5]; + uint8_t b6 = p[6]; + uint8_t b7 = p[7]; + + uint64_t next0 = prefix_dfa_[b0]; + uint64_t next1 = prefix_dfa_[b1]; + uint64_t next2 = prefix_dfa_[b2]; + uint64_t next3 = prefix_dfa_[b3]; + uint64_t next4 = prefix_dfa_[b4]; + uint64_t next5 = prefix_dfa_[b5]; + uint64_t next6 = prefix_dfa_[b6]; + uint64_t next7 = prefix_dfa_[b7]; + + uint64_t curr0 = next0 >> (curr & 63); + uint64_t curr1 = next1 >> (curr0 & 63); + uint64_t curr2 = next2 >> (curr1 & 63); + uint64_t curr3 = next3 >> (curr2 & 63); + uint64_t curr4 = next4 >> (curr3 & 63); + uint64_t curr5 = next5 >> (curr4 & 63); + uint64_t curr6 = next6 >> (curr5 & 63); + uint64_t curr7 = next7 >> (curr6 & 63); + + if ((curr7 & 63) == kShiftDFAFinal * 6) { + // At the time of writing, using the same masking subexpressions from + // the preceding lines caused Clang to clutter the hot loop computing + // them - even though they aren't actually needed for shifting! Hence + // these rewritten conditions, which achieve a speedup factor of two. + if (((curr7-curr0) & 63) == 0) return p+1-prefix_size_; + if (((curr7-curr1) & 63) == 0) return p+2-prefix_size_; + if (((curr7-curr2) & 63) == 0) return p+3-prefix_size_; + if (((curr7-curr3) & 63) == 0) return p+4-prefix_size_; + if (((curr7-curr4) & 63) == 0) return p+5-prefix_size_; + if (((curr7-curr5) & 63) == 0) return p+6-prefix_size_; + if (((curr7-curr6) & 63) == 0) return p+7-prefix_size_; + if (((curr7-curr7) & 63) == 0) return p+8-prefix_size_; + } + + curr = curr7; + p += 8; + } while (p != endp); + data = p; + size = size&7; + } + + const uint8_t* p = reinterpret_cast(data); + const uint8_t* endp = p + size; + while (p != endp) { + uint8_t b = *p++; + uint64_t next = prefix_dfa_[b]; + curr = next >> (curr & 63); + if ((curr & 63) == kShiftDFAFinal * 6) + return p-prefix_size_; + } + return NULL; +} + +#if defined(__AVX2__) +// Finds the least significant non-zero bit in n. +static int FindLSBSet(uint32_t n) { + DCHECK_NE(n, 0); +#if defined(__GNUC__) + return __builtin_ctz(n); +#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) + unsigned long c; + _BitScanForward(&c, n); + return static_cast(c); +#else + int c = 31; + for (int shift = 1 << 4; shift != 0; shift >>= 1) { + uint32_t word = n << shift; + if (word != 0) { + n = word; + c -= shift; + } + } + return c; +#endif +} +#endif + +const void* Prog::PrefixAccel_FrontAndBack(const void* data, size_t size) { + DCHECK_GE(prefix_size_, 2); + if (size < prefix_size_) + return NULL; + // Don't bother searching the last prefix_size_-1 bytes for prefix_front_. + // This also means that probing for prefix_back_ doesn't go out of bounds. + size -= prefix_size_-1; + +#if defined(__AVX2__) + // Use AVX2 to look for prefix_front_ and prefix_back_ 32 bytes at a time. + if (size >= sizeof(__m256i)) { + const __m256i* fp = reinterpret_cast( + reinterpret_cast(data)); + const __m256i* bp = reinterpret_cast( + reinterpret_cast(data) + prefix_size_-1); + const __m256i* endfp = fp + size/sizeof(__m256i); + const __m256i f_set1 = _mm256_set1_epi8(prefix_front_); + const __m256i b_set1 = _mm256_set1_epi8(prefix_back_); + do { + const __m256i f_loadu = _mm256_loadu_si256(fp++); + const __m256i b_loadu = _mm256_loadu_si256(bp++); + const __m256i f_cmpeq = _mm256_cmpeq_epi8(f_set1, f_loadu); + const __m256i b_cmpeq = _mm256_cmpeq_epi8(b_set1, b_loadu); + const int fb_testz = _mm256_testz_si256(f_cmpeq, b_cmpeq); + if (fb_testz == 0) { // ZF: 1 means zero, 0 means non-zero. + const __m256i fb_and = _mm256_and_si256(f_cmpeq, b_cmpeq); + const int fb_movemask = _mm256_movemask_epi8(fb_and); + const int fb_ctz = FindLSBSet(fb_movemask); + return reinterpret_cast(fp-1) + fb_ctz; + } + } while (fp != endfp); + data = fp; + size = size%sizeof(__m256i); + } +#endif + + const char* p0 = reinterpret_cast(data); + for (const char* p = p0;; p++) { + DCHECK_GE(size, static_cast(p-p0)); + p = reinterpret_cast(memchr(p, prefix_front_, size - (p-p0))); + if (p == NULL || p[prefix_size_-1] == prefix_back_) + return p; + } +} + } // namespace re2 diff --git a/re2/prog.h b/re2/prog.h index 40a6ce4..4af012a 100644 --- a/re2/prog.h +++ b/re2/prog.h @@ -198,8 +198,8 @@ class Prog { Inst *inst(int id) { return &inst_[id]; } int start() { return start_; } - int start_unanchored() { return start_unanchored_; } void set_start(int start) { start_ = start; } + int start_unanchored() { return start_unanchored_; } void set_start_unanchored(int start) { start_unanchored_ = start; } int size() { return size_; } bool reversed() { return reversed_; } @@ -207,19 +207,40 @@ class Prog { int list_count() { return list_count_; } int inst_count(InstOp op) { return inst_count_[op]; } uint16_t* list_heads() { return list_heads_.data(); } - void set_dfa_mem(int64_t dfa_mem) { dfa_mem_ = dfa_mem; } + size_t bit_state_text_max_size() { return bit_state_text_max_size_; } int64_t dfa_mem() { return dfa_mem_; } - int flags() { return flags_; } - void set_flags(int flags) { flags_ = flags; } + void set_dfa_mem(int64_t dfa_mem) { dfa_mem_ = dfa_mem; } bool anchor_start() { return anchor_start_; } void set_anchor_start(bool b) { anchor_start_ = b; } bool anchor_end() { return anchor_end_; } void set_anchor_end(bool b) { anchor_end_ = b; } int bytemap_range() { return bytemap_range_; } const uint8_t* bytemap() { return bytemap_; } + bool can_prefix_accel() { return prefix_size_ != 0; } + + // Accelerates to the first likely occurrence of the prefix. + // Returns a pointer to the first byte or NULL if not found. + const void* PrefixAccel(const void* data, size_t size) { + DCHECK(can_prefix_accel()); + if (prefix_foldcase_) { + return PrefixAccel_ShiftDFA(data, size); + } else if (prefix_size_ != 1) { + return PrefixAccel_FrontAndBack(data, size); + } else { + return memchr(data, prefix_front_, size); + } + } + + // Configures prefix accel using the analysis performed during compilation. + void ConfigurePrefixAccel(const std::string& prefix, bool prefix_foldcase); + + // An implementation of prefix accel that uses prefix_dfa_ to perform + // case-insensitive search. + const void* PrefixAccel_ShiftDFA(const void* data, size_t size); - // Lazily computed. - int first_byte(); + // An implementation of prefix accel that looks for prefix_front_ and + // prefix_back_ to return fewer false positives than memchr(3) alone. + const void* PrefixAccel_FrontAndBack(const void* data, size_t size); // Returns string representation of program for debugging. std::string Dump(); @@ -290,17 +311,9 @@ class Prog { // FOR TESTING OR EXPERIMENTAL PURPOSES ONLY. int BuildEntireDFA(MatchKind kind, const DFAStateCallback& cb); - // Controls whether the DFA should bail out early if the NFA would be faster. - // FOR TESTING ONLY. - static void TEST_dfa_should_bail_when_slow(bool b); - // Compute bytemap. void ComputeByteMap(); - // Computes whether all matches must begin with the same first - // byte, and if so, returns that byte. If not, returns -1. - int ComputeFirstByte(); - // Run peep-hole optimizer on program. void Optimize(); @@ -386,6 +399,10 @@ class Prog { // Computes hints for ByteRange instructions in [begin, end). void ComputeHints(std::vector* flat, int begin, int end); + // Controls whether the DFA should bail out early if the NFA would be faster. + // FOR TESTING ONLY. + static void TESTING_ONLY_set_dfa_should_bail_when_slow(bool b); + private: friend class Compiler; @@ -402,13 +419,22 @@ class Prog { int start_unanchored_; // unanchored entry point for program int size_; // number of instructions int bytemap_range_; // bytemap_[x] < bytemap_range_ - int first_byte_; // required first byte for match, or -1 if none - int flags_; // regexp parse flags - int list_count_; // count of lists (see above) - int inst_count_[kNumInst]; // count of instructions by opcode - PODArray list_heads_; // sparse array enumerating list heads - // not populated if size_ is overly large + bool prefix_foldcase_; // whether prefix is case-insensitive + size_t prefix_size_; // size of prefix (0 if no prefix) + union { + uint64_t* prefix_dfa_; // "Shift DFA" for prefix + struct { + int prefix_front_; // first byte of prefix + int prefix_back_; // last byte of prefix + }; + }; + + int list_count_; // count of lists (see above) + int inst_count_[kNumInst]; // count of instructions by opcode + PODArray list_heads_; // sparse array enumerating list heads + // not populated if size_ is overly large + size_t bit_state_text_max_size_; // upper bound (inclusive) on text.size() PODArray inst_; // pointer to instruction array PODArray onepass_nodes_; // data for OnePass nodes @@ -419,7 +445,6 @@ class Prog { uint8_t bytemap_[256]; // map from input bytes to byte classes - std::once_flag first_byte_once_; std::once_flag dfa_first_once_; std::once_flag dfa_longest_once_; @@ -427,6 +452,17 @@ class Prog { Prog& operator=(const Prog&) = delete; }; +// std::string_view in MSVC has iterators that aren't just pointers and +// that don't allow comparisons between different objects - not even if +// those objects are views into the same string! Thus, we provide these +// conversion functions for convenience. +static inline const char* BeginPtr(const StringPiece& s) { + return s.data(); +} +static inline const char* EndPtr(const StringPiece& s) { + return s.data() + s.size(); +} + } // namespace re2 #endif // RE2_PROG_H_ diff --git a/re2/re2.cc b/re2/re2.cc index a8dd24b..c027133 100644 --- a/re2/re2.cc +++ b/re2/re2.cc @@ -12,10 +12,14 @@ #include #include #include +#ifdef _MSC_VER +#include +#endif #include #include #include #include +#include #include #include #include @@ -79,6 +83,8 @@ static RE2::ErrorCode RegexpErrorToRE2(re2::RegexpStatusCode code) { return RE2::ErrorMissingBracket; case re2::kRegexpMissingParen: return RE2::ErrorMissingParen; + case re2::kRegexpUnexpectedParen: + return RE2::ErrorUnexpectedParen; case re2::kRegexpTrailingBackslash: return RE2::ErrorTrailingBackslash; case re2::kRegexpRepeatArgument: @@ -172,15 +178,20 @@ void RE2::Init(const StringPiece& pattern, const Options& options) { empty_group_names = new std::map; }); - pattern_ = std::string(pattern); + pattern_.assign(pattern.data(), pattern.size()); options_.Copy(options); entire_regexp_ = NULL; + error_ = empty_string; + error_code_ = NoError; + error_arg_.clear(); + prefix_.clear(); + prefix_foldcase_ = false; suffix_regexp_ = NULL; prog_ = NULL; num_captures_ = -1; + is_one_pass_ = false; + rprog_ = NULL; - error_ = empty_string; - error_code_ = NoError; named_groups_ = NULL; group_names_ = NULL; @@ -239,9 +250,11 @@ re2::Prog* RE2::ReverseProg() const { if (re->rprog_ == NULL) { if (re->options_.log_errors()) LOG(ERROR) << "Error reverse compiling '" << trunc(re->pattern_) << "'"; - re->error_ = - new std::string("pattern too large - reverse compile failed"); - re->error_code_ = RE2::ErrorPatternTooLarge; + // We no longer touch error_ and error_code_ because failing to compile + // the reverse Prog is not a showstopper: falling back to NFA execution + // is fine. More importantly, an RE2 object is supposed to be logically + // immutable: whatever ok() would have returned after Init() completed, + // it should continue to return that no matter what ReverseProg() does. } }, this); return rprog_; @@ -277,28 +290,54 @@ int RE2::ReverseProgramSize() const { return prog->size(); } -static int Fanout(Prog* prog, std::map* histogram) { +// Finds the most significant non-zero bit in n. +static int FindMSBSet(uint32_t n) { + DCHECK_NE(n, 0); +#if defined(__GNUC__) + return 31 ^ __builtin_clz(n); +#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) + unsigned long c; + _BitScanReverse(&c, n); + return static_cast(c); +#else + int c = 0; + for (int shift = 1 << 4; shift != 0; shift >>= 1) { + uint32_t word = n >> shift; + if (word != 0) { + n = word; + c += shift; + } + } + return c; +#endif +} + +static int Fanout(Prog* prog, std::vector* histogram) { SparseArray fanout(prog->size()); prog->Fanout(&fanout); - histogram->clear(); + int data[32] = {}; + int size = 0; for (SparseArray::iterator i = fanout.begin(); i != fanout.end(); ++i) { - // TODO(junyer): Optimise this? - int bucket = 0; - while (1 << bucket < i->value()) { - bucket++; - } - (*histogram)[bucket]++; + if (i->value() == 0) + continue; + uint32_t value = i->value(); + int bucket = FindMSBSet(value); + bucket += value & (value-1) ? 1 : 0; + ++data[bucket]; + size = std::max(size, bucket+1); } - return histogram->rbegin()->first; + if (histogram != NULL) + histogram->assign(data, data+size); + return size-1; } -int RE2::ProgramFanout(std::map* histogram) const { +int RE2::ProgramFanout(std::vector* histogram) const { if (prog_ == NULL) return -1; return Fanout(prog_, histogram); } -int RE2::ReverseProgramFanout(std::map* histogram) const { +int RE2::ReverseProgramFanout(std::vector* histogram) const { if (prog_ == NULL) return -1; Prog* prog = ReverseProg(); @@ -368,6 +407,8 @@ bool RE2::Replace(std::string* str, const StringPiece& rewrite) { StringPiece vec[kVecSize]; int nvec = 1 + MaxSubmatch(rewrite); + if (nvec > 1 + re.NumberOfCapturingGroups()) + return false; if (nvec > static_cast(arraysize(vec))) return false; if (!re.Match(*str, 0, str->size(), UNANCHORED, vec, nvec)) @@ -388,6 +429,8 @@ int RE2::GlobalReplace(std::string* str, const StringPiece& rewrite) { StringPiece vec[kVecSize]; int nvec = 1 + MaxSubmatch(rewrite); + if (nvec > 1 + re.NumberOfCapturingGroups()) + return false; if (nvec > static_cast(arraysize(vec))) return false; @@ -460,9 +503,10 @@ bool RE2::Extract(const StringPiece& text, std::string* out) { StringPiece vec[kVecSize]; int nvec = 1 + MaxSubmatch(rewrite); + if (nvec > 1 + re.NumberOfCapturingGroups()) + return false; if (nvec > static_cast(arraysize(vec))) return false; - if (!re.Match(text, 0, text.size(), UNANCHORED, vec, nvec)) return false; @@ -610,6 +654,8 @@ bool RE2::Match(const StringPiece& text, // If the regexp is anchored explicitly, must not be in middle of text. if (prog_->anchor_start() && startpos != 0) return false; + if (prog_->anchor_end() && endpos != text.size()) + return false; // If the regexp is anchored explicitly, update re_anchor // so that we can potentially fall into a faster case below. @@ -643,50 +689,87 @@ bool RE2::Match(const StringPiece& text, Prog::MatchKind kind = Prog::kFirstMatch; if (options_.longest_match()) kind = Prog::kLongestMatch; - bool skipped_test = false; - bool can_one_pass = (is_one_pass_ && ncap <= Prog::kMaxOnePassCapture); - - // BitState allocates a bitmap of size prog_->list_count() * text.size(). - // It also allocates a stack of 3-word structures which could potentially - // grow as large as prog_->list_count() * text.size(), but in practice is - // much smaller. - const int kMaxBitStateBitmapSize = 256*1024; // bitmap size <= max (bits) + bool can_one_pass = is_one_pass_ && ncap <= Prog::kMaxOnePassCapture; bool can_bit_state = prog_->CanBitState(); - size_t bit_state_text_max = kMaxBitStateBitmapSize / prog_->list_count(); + size_t bit_state_text_max_size = prog_->bit_state_text_max_size(); +#ifdef RE2_HAVE_THREAD_LOCAL + hooks::context = this; +#endif bool dfa_failed = false; + bool skipped_test = false; switch (re_anchor) { default: + LOG(DFATAL) << "Unexpected re_anchor value: " << re_anchor; + return false; + case UNANCHORED: { + if (prog_->anchor_end()) { + // This is a very special case: we don't need the forward DFA because + // we already know where the match must end! Instead, the reverse DFA + // can say whether there is a match and (optionally) where it starts. + Prog* prog = ReverseProg(); + if (prog == NULL) { + // Fall back to NFA below. + skipped_test = true; + break; + } + if (!prog->SearchDFA(subtext, text, Prog::kAnchored, + Prog::kLongestMatch, matchp, &dfa_failed, NULL)) { + if (dfa_failed) { + if (options_.log_errors()) + LOG(ERROR) << "DFA out of memory: " + << "pattern length " << pattern_.size() << ", " + << "program size " << prog->size() << ", " + << "list count " << prog->list_count() << ", " + << "bytemap range " << prog->bytemap_range(); + // Fall back to NFA below. + skipped_test = true; + break; + } + return false; + } + if (matchp == NULL) // Matched. Don't care where. + return true; + break; + } + if (!prog_->SearchDFA(subtext, text, anchor, kind, matchp, &dfa_failed, NULL)) { if (dfa_failed) { if (options_.log_errors()) - LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", " - << "bytemap range " << prog_->bytemap_range() << ", " - << "list count " << prog_->list_count(); + LOG(ERROR) << "DFA out of memory: " + << "pattern length " << pattern_.size() << ", " + << "program size " << prog_->size() << ", " + << "list count " << prog_->list_count() << ", " + << "bytemap range " << prog_->bytemap_range(); // Fall back to NFA below. skipped_test = true; break; } return false; } - if (matchp == NULL) // Matched. Don't care where + if (matchp == NULL) // Matched. Don't care where. return true; - // SearchDFA set match[0].end() but didn't know where the - // match started. Run the regexp backward from match[0].end() + // SearchDFA set match.end() but didn't know where the + // match started. Run the regexp backward from match.end() // to find the longest possible match -- that's where it started. Prog* prog = ReverseProg(); - if (prog == NULL) - return false; + if (prog == NULL) { + // Fall back to NFA below. + skipped_test = true; + break; + } if (!prog->SearchDFA(match, text, Prog::kAnchored, Prog::kLongestMatch, &match, &dfa_failed, NULL)) { if (dfa_failed) { if (options_.log_errors()) - LOG(ERROR) << "DFA out of memory: size " << prog->size() << ", " - << "bytemap range " << prog->bytemap_range() << ", " - << "list count " << prog->list_count(); + LOG(ERROR) << "DFA out of memory: " + << "pattern length " << pattern_.size() << ", " + << "program size " << prog->size() << ", " + << "list count " << prog->list_count() << ", " + << "bytemap range " << prog->bytemap_range(); // Fall back to NFA below. skipped_test = true; break; @@ -712,11 +795,12 @@ bool RE2::Match(const StringPiece& text, // it doesn't have the shared state and occasional mutex that // the DFA does. if (can_one_pass && text.size() <= 4096 && - (ncap > 1 || text.size() <= 8)) { + (ncap > 1 || text.size() <= 16)) { skipped_test = true; break; } - if (can_bit_state && text.size() <= bit_state_text_max && ncap > 1) { + if (can_bit_state && text.size() <= bit_state_text_max_size && + ncap > 1) { skipped_test = true; break; } @@ -724,9 +808,11 @@ bool RE2::Match(const StringPiece& text, &match, &dfa_failed, NULL)) { if (dfa_failed) { if (options_.log_errors()) - LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", " - << "bytemap range " << prog_->bytemap_range() << ", " - << "list count " << prog_->list_count(); + LOG(ERROR) << "DFA out of memory: " + << "pattern length " << pattern_.size() << ", " + << "program size " << prog_->size() << ", " + << "list count " << prog_->list_count() << ", " + << "bytemap range " << prog_->bytemap_range(); // Fall back to NFA below. skipped_test = true; break; @@ -761,7 +847,7 @@ bool RE2::Match(const StringPiece& text, LOG(ERROR) << "SearchOnePass inconsistency"; return false; } - } else if (can_bit_state && subtext1.size() <= bit_state_text_max) { + } else if (can_bit_state && subtext1.size() <= bit_state_text_max_size) { if (!prog_->SearchBitState(subtext1, text, anchor, kind, submatch, ncap)) { if (!skipped_test && options_.log_errors()) @@ -829,7 +915,7 @@ bool RE2::DoMatch(const StringPiece& text, } if (consumed != NULL) - *consumed = static_cast(vec[0].end() - text.begin()); + *consumed = static_cast(EndPtr(vec[0]) - BeginPtr(text)); if (n == 0 || args == NULL) { // We are not interested in results @@ -928,8 +1014,8 @@ bool RE2::Rewrite(std::string* out, int n = (c - '0'); if (n >= veclen) { if (options_.log_errors()) { - LOG(ERROR) << "requested group " << n - << " in regexp " << rewrite.data(); + LOG(ERROR) << "invalid substitution \\" << n + << " from " << veclen << " groups"; } return false; } @@ -949,41 +1035,49 @@ bool RE2::Rewrite(std::string* out, /***** Parsers for various types *****/ -bool RE2::Arg::parse_null(const char* str, size_t n, void* dest) { +namespace re2_internal { + +template <> +bool Parse(const char* str, size_t n, void* dest) { // We fail if somebody asked us to store into a non-NULL void* pointer return (dest == NULL); } -bool RE2::Arg::parse_string(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, std::string* dest) { if (dest == NULL) return true; - reinterpret_cast(dest)->assign(str, n); + dest->assign(str, n); return true; } -bool RE2::Arg::parse_stringpiece(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, StringPiece* dest) { if (dest == NULL) return true; - *(reinterpret_cast(dest)) = StringPiece(str, n); + *dest = StringPiece(str, n); return true; } -bool RE2::Arg::parse_char(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, char* dest) { if (n != 1) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = str[0]; + *dest = str[0]; return true; } -bool RE2::Arg::parse_schar(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, signed char* dest) { if (n != 1) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = str[0]; + *dest = str[0]; return true; } -bool RE2::Arg::parse_uchar(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, unsigned char* dest) { if (n != 1) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = str[0]; + *dest = str[0]; return true; } @@ -1047,10 +1141,40 @@ static const char* TerminateNumber(char* buf, size_t nbuf, const char* str, return buf; } -bool RE2::Arg::parse_long_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, float* dest) { + if (n == 0) return false; + static const int kMaxLength = 200; + char buf[kMaxLength+1]; + str = TerminateNumber(buf, sizeof buf, str, &n, true); + char* end; + errno = 0; + float r = strtof(str, &end); + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *dest = r; + return true; +} + +template <> +bool Parse(const char* str, size_t n, double* dest) { + if (n == 0) return false; + static const int kMaxLength = 200; + char buf[kMaxLength+1]; + str = TerminateNumber(buf, sizeof buf, str, &n, true); + char* end; + errno = 0; + double r = strtod(str, &end); + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *dest = r; + return true; +} + +template <> +bool Parse(const char* str, size_t n, long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1060,14 +1184,12 @@ bool RE2::Arg::parse_long_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = r; + *dest = r; return true; } -bool RE2::Arg::parse_ulong_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1083,62 +1205,52 @@ bool RE2::Arg::parse_ulong_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = r; + *dest = r; return true; } -bool RE2::Arg::parse_short_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, short* dest, int radix) { long r; - if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse - if ((short)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((short)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast(dest)) = (short)r; + *dest = (short)r; return true; } -bool RE2::Arg::parse_ushort_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned short* dest, int radix) { unsigned long r; - if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse - if ((unsigned short)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((unsigned short)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast(dest)) = (unsigned short)r; + *dest = (unsigned short)r; return true; } -bool RE2::Arg::parse_int_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, int* dest, int radix) { long r; - if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse - if ((int)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((int)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast(dest)) = (int)r; + *dest = (int)r; return true; } -bool RE2::Arg::parse_uint_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned int* dest, int radix) { unsigned long r; - if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse - if ((unsigned int)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((unsigned int)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast(dest)) = (unsigned int)r; + *dest = (unsigned int)r; return true; } -bool RE2::Arg::parse_longlong_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, long long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1148,14 +1260,12 @@ bool RE2::Arg::parse_longlong_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = r; + *dest = r; return true; } -bool RE2::Arg::parse_ulonglong_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned long long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1170,67 +1280,47 @@ bool RE2::Arg::parse_ulonglong_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast(dest)) = r; + *dest = r; return true; } -static bool parse_double_float(const char* str, size_t n, bool isfloat, - void* dest) { - if (n == 0) return false; - static const int kMaxLength = 200; - char buf[kMaxLength+1]; - str = TerminateNumber(buf, sizeof buf, str, &n, true); - char* end; - errno = 0; - double r; - if (isfloat) { - r = strtof(str, &end); - } else { - r = strtod(str, &end); - } - if (end != str + n) return false; // Leftover junk - if (errno) return false; - if (dest == NULL) return true; - if (isfloat) { - *(reinterpret_cast(dest)) = (float)r; - } else { - *(reinterpret_cast(dest)) = r; - } - return true; -} +} // namespace re2_internal -bool RE2::Arg::parse_double(const char* str, size_t n, void* dest) { - return parse_double_float(str, n, false, dest); -} +namespace hooks { -bool RE2::Arg::parse_float(const char* str, size_t n, void* dest) { - return parse_double_float(str, n, true, dest); -} +#ifdef RE2_HAVE_THREAD_LOCAL +thread_local const RE2* context = NULL; +#endif -#define DEFINE_INTEGER_PARSER(name) \ - bool RE2::Arg::parse_##name(const char* str, size_t n, void* dest) { \ - return parse_##name##_radix(str, n, dest, 10); \ - } \ - bool RE2::Arg::parse_##name##_hex(const char* str, size_t n, void* dest) { \ - return parse_##name##_radix(str, n, dest, 16); \ - } \ - bool RE2::Arg::parse_##name##_octal(const char* str, size_t n, void* dest) { \ - return parse_##name##_radix(str, n, dest, 8); \ - } \ - bool RE2::Arg::parse_##name##_cradix(const char* str, size_t n, \ - void* dest) { \ - return parse_##name##_radix(str, n, dest, 0); \ - } +template +union Hook { + void Store(T* cb) { cb_.store(cb, std::memory_order_release); } + T* Load() const { return cb_.load(std::memory_order_acquire); } + +#if !defined(__clang__) && defined(_MSC_VER) + // Citing https://github.com/protocolbuffers/protobuf/pull/4777 as precedent, + // this is a gross hack to make std::atomic constant-initialized on MSVC. + static_assert(ATOMIC_POINTER_LOCK_FREE == 2, + "std::atomic must be always lock-free"); + T* cb_for_constinit_; +#endif + + std::atomic cb_; +}; + +template +static void DoNothing(const T&) {} + +#define DEFINE_HOOK(type, name) \ + static Hook name##_hook = {{&DoNothing}}; \ + void Set##type##Hook(type##Callback* cb) { name##_hook.Store(cb); } \ + type##Callback* Get##type##Hook() { return name##_hook.Load(); } + +DEFINE_HOOK(DFAStateCacheReset, dfa_state_cache_reset) +DEFINE_HOOK(DFASearchFailure, dfa_search_failure) -DEFINE_INTEGER_PARSER(short); -DEFINE_INTEGER_PARSER(ushort); -DEFINE_INTEGER_PARSER(int); -DEFINE_INTEGER_PARSER(uint); -DEFINE_INTEGER_PARSER(long); -DEFINE_INTEGER_PARSER(ulong); -DEFINE_INTEGER_PARSER(longlong); -DEFINE_INTEGER_PARSER(ulonglong); +#undef DEFINE_HOOK -#undef DEFINE_INTEGER_PARSER +} // namespace hooks } // namespace re2 diff --git a/re2/re2.h b/re2/re2.h index c39589d..7fd2245 100644 --- a/re2/re2.h +++ b/re2/re2.h @@ -30,6 +30,19 @@ // "(?i)hello" -- (?i) turns on case-insensitive matching // "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible // +// The double backslashes are needed when writing C++ string literals. +// However, they should NOT be used when writing C++11 raw string literals: +// +// R"(hello (\w+) world)" -- \w matches a "word" character +// R"(version (\d+))" -- \d matches a digit +// R"(hello\s+world)" -- \s matches any whitespace character +// R"(\b(\w+)\b)" -- \b matches non-empty string at word boundary +// R"((?i)hello)" -- (?i) turns on case-insensitive matching +// R"(/\*(.*?)\*/)" -- .*? matches . minimum no. of times possible +// +// When using UTF-8 encoding, case-insensitive matching will perform +// simple case folding, not full case folding. +// // ----------------------------------------------------------------------- // MATCHING INTERFACE: // @@ -195,6 +208,12 @@ #include #include #include +#include +#include + +#if defined(__APPLE__) +#include +#endif #include "re2/stringpiece.h" @@ -229,6 +248,7 @@ class RE2 { ErrorBadCharRange, // bad character class range ErrorMissingBracket, // missing closing ] ErrorMissingParen, // missing closing ) + ErrorUnexpectedParen, // unexpected closing ) ErrorTrailingBackslash, // trailing \ at end of regexp ErrorRepeatArgument, // repeat argument missing, e.g. "*" ErrorRepeatSize, // bad repetition argument @@ -287,11 +307,11 @@ class RE2 { int ProgramSize() const; int ReverseProgramSize() const; - // EXPERIMENTAL! SUBJECT TO CHANGE! - // Outputs the program fanout as a histogram bucketed by powers of 2. + // If histogram is not null, outputs the program fanout + // as a histogram bucketed by powers of 2. // Returns the number of the largest non-empty bucket. - int ProgramFanout(std::map* histogram) const; - int ReverseProgramFanout(std::map* histogram) const; + int ProgramFanout(std::vector* histogram) const; + int ReverseProgramFanout(std::vector* histogram) const; // Returns the underlying Regexp; not for general use. // Returns entire_regexp_ so that callers don't need @@ -349,12 +369,12 @@ class RE2 { // (void*)NULL (the corresponding matched sub-pattern is not copied) // // Returns true iff all of the following conditions are satisfied: - // a. "text" matches "re" exactly - // b. The number of matched sub-patterns is >= number of supplied pointers + // a. "text" matches "re" fully - from the beginning to the end of "text". + // b. The number of matched sub-patterns is >= number of supplied pointers. // c. The "i"th argument has a suitable type for holding the // string captured as the "i"th sub-pattern. If you pass in // NULL for the "i"th argument, or pass fewer arguments than - // number of sub-patterns, "i"th captured sub-pattern is + // number of sub-patterns, the "i"th captured sub-pattern is // ignored. // // CAVEAT: An optional sub-pattern that does not exist in the @@ -368,8 +388,17 @@ class RE2 { return Apply(FullMatchN, text, re, Arg(std::forward(a))...); } - // Exactly like FullMatch(), except that "re" is allowed to match - // a substring of "text". + // Like FullMatch(), except that "re" is allowed to match a substring + // of "text". + // + // Returns true iff all of the following conditions are satisfied: + // a. "text" matches "re" partially - for some substring of "text". + // b. The number of matched sub-patterns is >= number of supplied pointers. + // c. The "i"th argument has a suitable type for holding the + // string captured as the "i"th sub-pattern. If you pass in + // NULL for the "i"th argument, or pass fewer arguments than + // number of sub-patterns, the "i"th captured sub-pattern is + // ignored. template static bool PartialMatch(const StringPiece& text, const RE2& re, A&&... a) { return Apply(PartialMatchN, text, re, Arg(std::forward(a))...); @@ -378,7 +407,16 @@ class RE2 { // Like FullMatch() and PartialMatch(), except that "re" has to match // a prefix of the text, and "input" is advanced past the matched // text. Note: "input" is modified iff this routine returns true - // and "re" matched a non-empty substring of "text". + // and "re" matched a non-empty substring of "input". + // + // Returns true iff all of the following conditions are satisfied: + // a. "input" matches "re" partially - for some prefix of "input". + // b. The number of matched sub-patterns is >= number of supplied pointers. + // c. The "i"th argument has a suitable type for holding the + // string captured as the "i"th sub-pattern. If you pass in + // NULL for the "i"th argument, or pass fewer arguments than + // number of sub-patterns, the "i"th captured sub-pattern is + // ignored. template static bool Consume(StringPiece* input, const RE2& re, A&&... a) { return Apply(ConsumeN, input, re, Arg(std::forward(a))...); @@ -388,6 +426,15 @@ class RE2 { // the text. That is, "re" need not start its match at the beginning // of "input". For example, "FindAndConsume(s, "(\\w+)", &word)" finds // the next word in "s" and stores it in "word". + // + // Returns true iff all of the following conditions are satisfied: + // a. "input" matches "re" partially - for some substring of "input". + // b. The number of matched sub-patterns is >= number of supplied pointers. + // c. The "i"th argument has a suitable type for holding the + // string captured as the "i"th sub-pattern. If you pass in + // NULL for the "i"th argument, or pass fewer arguments than + // number of sub-patterns, the "i"th captured sub-pattern is + // ignored. template static bool FindAndConsume(StringPiece* input, const RE2& re, A&&... a) { return Apply(FindAndConsumeN, input, re, Arg(std::forward(a))...); @@ -443,7 +490,7 @@ class RE2 { // Escapes all potentially meaningful regexp characters in // 'unquoted'. The returned string, used as a regular expression, - // will exactly match the original string. For example, + // will match exactly the original string. For example, // 1.5-2.0? // may become: // 1\.5\-2\.0\? @@ -626,17 +673,6 @@ class RE2 { Encoding encoding() const { return encoding_; } void set_encoding(Encoding encoding) { encoding_ = encoding; } - // Legacy interface to encoding. - // TODO(rsc): Remove once clients have been converted. - bool utf8() const { return encoding_ == EncodingUTF8; } - void set_utf8(bool b) { - if (b) { - encoding_ = EncodingUTF8; - } else { - encoding_ = EncodingLatin1; - } - } - bool posix_syntax() const { return posix_syntax_; } void set_posix_syntax(bool b) { posix_syntax_ = b; } @@ -699,32 +735,12 @@ class RE2 { const Options& options() const { return options_; } // Argument converters; see below. - static inline Arg CRadix(short* x); - static inline Arg CRadix(unsigned short* x); - static inline Arg CRadix(int* x); - static inline Arg CRadix(unsigned int* x); - static inline Arg CRadix(long* x); - static inline Arg CRadix(unsigned long* x); - static inline Arg CRadix(long long* x); - static inline Arg CRadix(unsigned long long* x); - - static inline Arg Hex(short* x); - static inline Arg Hex(unsigned short* x); - static inline Arg Hex(int* x); - static inline Arg Hex(unsigned int* x); - static inline Arg Hex(long* x); - static inline Arg Hex(unsigned long* x); - static inline Arg Hex(long long* x); - static inline Arg Hex(unsigned long long* x); - - static inline Arg Octal(short* x); - static inline Arg Octal(unsigned short* x); - static inline Arg Octal(int* x); - static inline Arg Octal(unsigned int* x); - static inline Arg Octal(long* x); - static inline Arg Octal(unsigned long* x); - static inline Arg Octal(long long* x); - static inline Arg Octal(unsigned long long* x); + template + static Arg CRadix(T* ptr); + template + static Arg Hex(T* ptr); + template + static Arg Octal(T* ptr); private: void Init(const StringPiece& pattern, const Options& options); @@ -737,29 +753,26 @@ class RE2 { re2::Prog* ReverseProg() const; - std::string pattern_; // string regular expression - Options options_; // option flags - std::string prefix_; // required prefix (before regexp_) - bool prefix_foldcase_; // prefix is ASCII case-insensitive - re2::Regexp* entire_regexp_; // parsed regular expression - re2::Regexp* suffix_regexp_; // parsed regular expression, prefix removed - re2::Prog* prog_; // compiled program for regexp - int num_captures_; // Number of capturing groups - bool is_one_pass_; // can use prog_->SearchOnePass? - - mutable re2::Prog* rprog_; // reverse program for regexp - mutable const std::string* error_; // Error indicator - // (or points to empty string) - mutable ErrorCode error_code_; // Error code - mutable std::string error_arg_; // Fragment of regexp showing error - + std::string pattern_; // string regular expression + Options options_; // option flags + re2::Regexp* entire_regexp_; // parsed regular expression + const std::string* error_; // error indicator (or points to empty string) + ErrorCode error_code_; // error code + std::string error_arg_; // fragment of regexp showing error + std::string prefix_; // required prefix (before suffix_regexp_) + bool prefix_foldcase_; // prefix_ is ASCII case-insensitive + re2::Regexp* suffix_regexp_; // parsed regular expression, prefix_ removed + re2::Prog* prog_; // compiled program for regexp + int num_captures_; // number of capturing groups + bool is_one_pass_; // can use prog_->SearchOnePass? + + // Reverse Prog for DFA execution only + mutable re2::Prog* rprog_; // Map from capture names to indices mutable const std::map* named_groups_; - // Map from capture indices to names mutable const std::map* group_names_; - // Onces for lazy computations. mutable std::once_flag rprog_once_; mutable std::once_flag named_groups_once_; mutable std::once_flag group_names_once_; @@ -770,137 +783,134 @@ class RE2 { /***** Implementation details *****/ -// Hex/Octal/Binary? - -// Special class for parsing into objects that define a ParseFrom() method -template -class _RE2_MatchObject { - public: - static inline bool Parse(const char* str, size_t n, void* dest) { - if (dest == NULL) return true; - T* object = reinterpret_cast(dest); - return object->ParseFrom(str, n); - } -}; +namespace re2_internal { + +// Types for which the 3-ary Parse() function template has specializations. +template struct Parse3ary : public std::false_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; +template <> struct Parse3ary : public std::true_type {}; + +template +bool Parse(const char* str, size_t n, T* dest); + +// Types for which the 4-ary Parse() function template has specializations. +template struct Parse4ary : public std::false_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; +template <> struct Parse4ary : public std::true_type {}; + +template +bool Parse(const char* str, size_t n, T* dest, int radix); + +} // namespace re2_internal class RE2::Arg { + private: + template + using CanParse3ary = typename std::enable_if< + re2_internal::Parse3ary::value, + int>::type; + + template + using CanParse4ary = typename std::enable_if< + re2_internal::Parse4ary::value, + int>::type; + +#if !defined(_MSC_VER) + template + using CanParseFrom = typename std::enable_if< + std::is_member_function_pointer< + decltype(static_cast( + &T::ParseFrom))>::value, + int>::type; +#endif + public: - // Empty constructor so we can declare arrays of RE2::Arg - Arg(); + Arg() : Arg(nullptr) {} + Arg(std::nullptr_t ptr) : arg_(ptr), parser_(DoNothing) {} - // Constructor specially designed for NULL arguments - Arg(void*); - Arg(std::nullptr_t); + template = 0> + Arg(T* ptr) : arg_(ptr), parser_(DoParse3ary) {} + + template = 0> + Arg(T* ptr) : arg_(ptr), parser_(DoParse4ary) {} + +#if !defined(_MSC_VER) + template = 0> + Arg(T* ptr) : arg_(ptr), parser_(DoParseFrom) {} +#endif typedef bool (*Parser)(const char* str, size_t n, void* dest); -// Type-specific parsers -#define MAKE_PARSER(type, name) \ - Arg(type* p) : arg_(p), parser_(name) {} \ - Arg(type* p, Parser parser) : arg_(p), parser_(parser) {} - - MAKE_PARSER(char, parse_char) - MAKE_PARSER(signed char, parse_schar) - MAKE_PARSER(unsigned char, parse_uchar) - MAKE_PARSER(float, parse_float) - MAKE_PARSER(double, parse_double) - MAKE_PARSER(std::string, parse_string) - MAKE_PARSER(StringPiece, parse_stringpiece) - - MAKE_PARSER(short, parse_short) - MAKE_PARSER(unsigned short, parse_ushort) - MAKE_PARSER(int, parse_int) - MAKE_PARSER(unsigned int, parse_uint) - MAKE_PARSER(long, parse_long) - MAKE_PARSER(unsigned long, parse_ulong) - MAKE_PARSER(long long, parse_longlong) - MAKE_PARSER(unsigned long long, parse_ulonglong) - -#undef MAKE_PARSER - - // Generic constructor templates - template Arg(T* p) - : arg_(p), parser_(_RE2_MatchObject::Parse) { } - template Arg(T* p, Parser parser) - : arg_(p), parser_(parser) { } - - // Parse the data - bool Parse(const char* str, size_t n) const; + template + Arg(T* ptr, Parser parser) : arg_(ptr), parser_(parser) {} + + bool Parse(const char* str, size_t n) const { + return (*parser_)(str, n, arg_); + } private: - void* arg_; - Parser parser_; + static bool DoNothing(const char* /*str*/, size_t /*n*/, void* /*dest*/) { + return true; + } - static bool parse_null (const char* str, size_t n, void* dest); - static bool parse_char (const char* str, size_t n, void* dest); - static bool parse_schar (const char* str, size_t n, void* dest); - static bool parse_uchar (const char* str, size_t n, void* dest); - static bool parse_float (const char* str, size_t n, void* dest); - static bool parse_double (const char* str, size_t n, void* dest); - static bool parse_string (const char* str, size_t n, void* dest); - static bool parse_stringpiece (const char* str, size_t n, void* dest); - -#define DECLARE_INTEGER_PARSER(name) \ - private: \ - static bool parse_##name(const char* str, size_t n, void* dest); \ - static bool parse_##name##_radix(const char* str, size_t n, void* dest, \ - int radix); \ - \ - public: \ - static bool parse_##name##_hex(const char* str, size_t n, void* dest); \ - static bool parse_##name##_octal(const char* str, size_t n, void* dest); \ - static bool parse_##name##_cradix(const char* str, size_t n, void* dest); - - DECLARE_INTEGER_PARSER(short) - DECLARE_INTEGER_PARSER(ushort) - DECLARE_INTEGER_PARSER(int) - DECLARE_INTEGER_PARSER(uint) - DECLARE_INTEGER_PARSER(long) - DECLARE_INTEGER_PARSER(ulong) - DECLARE_INTEGER_PARSER(longlong) - DECLARE_INTEGER_PARSER(ulonglong) - -#undef DECLARE_INTEGER_PARSER + template + static bool DoParse3ary(const char* str, size_t n, void* dest) { + return re2_internal::Parse(str, n, reinterpret_cast(dest)); + } -}; + template + static bool DoParse4ary(const char* str, size_t n, void* dest) { + return re2_internal::Parse(str, n, reinterpret_cast(dest), 10); + } -inline RE2::Arg::Arg() : arg_(NULL), parser_(parse_null) { } -inline RE2::Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } -inline RE2::Arg::Arg(std::nullptr_t p) : arg_(p), parser_(parse_null) { } +#if !defined(_MSC_VER) + template + static bool DoParseFrom(const char* str, size_t n, void* dest) { + if (dest == NULL) return true; + return reinterpret_cast(dest)->ParseFrom(str, n); + } +#endif -inline bool RE2::Arg::Parse(const char* str, size_t n) const { - return (*parser_)(str, n, arg_); -} + void* arg_; + Parser parser_; +}; -// This part of the parser, appropriate only for ints, deals with bases -#define MAKE_INTEGER_PARSER(type, name) \ - inline RE2::Arg RE2::Hex(type* ptr) { \ - return RE2::Arg(ptr, RE2::Arg::parse_##name##_hex); \ - } \ - inline RE2::Arg RE2::Octal(type* ptr) { \ - return RE2::Arg(ptr, RE2::Arg::parse_##name##_octal); \ - } \ - inline RE2::Arg RE2::CRadix(type* ptr) { \ - return RE2::Arg(ptr, RE2::Arg::parse_##name##_cradix); \ - } +template +inline RE2::Arg RE2::CRadix(T* ptr) { + return RE2::Arg(ptr, [](const char* str, size_t n, void* dest) -> bool { + return re2_internal::Parse(str, n, reinterpret_cast(dest), 0); + }); +} -MAKE_INTEGER_PARSER(short, short) -MAKE_INTEGER_PARSER(unsigned short, ushort) -MAKE_INTEGER_PARSER(int, int) -MAKE_INTEGER_PARSER(unsigned int, uint) -MAKE_INTEGER_PARSER(long, long) -MAKE_INTEGER_PARSER(unsigned long, ulong) -MAKE_INTEGER_PARSER(long long, longlong) -MAKE_INTEGER_PARSER(unsigned long long, ulonglong) +template +inline RE2::Arg RE2::Hex(T* ptr) { + return RE2::Arg(ptr, [](const char* str, size_t n, void* dest) -> bool { + return re2_internal::Parse(str, n, reinterpret_cast(dest), 16); + }); +} -#undef MAKE_INTEGER_PARSER +template +inline RE2::Arg RE2::Octal(T* ptr) { + return RE2::Arg(ptr, [](const char* str, size_t n, void* dest) -> bool { + return re2_internal::Parse(str, n, reinterpret_cast(dest), 8); + }); +} #ifndef SWIG - // Silence warnings about missing initializers for members of LazyRE2. -// Note that we test for Clang first because it defines __GNUC__ as well. -#if defined(__clang__) -#elif defined(__GNUC__) && __GNUC__ >= 6 +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 6 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif @@ -949,7 +959,55 @@ class LazyRE2 { void operator=(const LazyRE2&); // disallowed }; -#endif // SWIG +#endif + +namespace hooks { + +// Most platforms support thread_local. Older versions of iOS don't support +// thread_local, but for the sake of brevity, we lump together all versions +// of Apple platforms that aren't macOS. If an iOS application really needs +// the context pointee someday, we can get more specific then... +// +// As per https://github.com/google/re2/issues/325, thread_local support in +// MinGW seems to be buggy. (FWIW, Abseil folks also avoid it.) +#define RE2_HAVE_THREAD_LOCAL +#if (defined(__APPLE__) && !TARGET_OS_OSX) || defined(__MINGW32__) +#undef RE2_HAVE_THREAD_LOCAL +#endif + +// A hook must not make any assumptions regarding the lifetime of the context +// pointee beyond the current invocation of the hook. Pointers and references +// obtained via the context pointee should be considered invalidated when the +// hook returns. Hence, any data about the context pointee (e.g. its pattern) +// would have to be copied in order for it to be kept for an indefinite time. +// +// A hook must not use RE2 for matching. Control flow reentering RE2::Match() +// could result in infinite mutual recursion. To discourage that possibility, +// RE2 will not maintain the context pointer correctly when used in that way. +#ifdef RE2_HAVE_THREAD_LOCAL +extern thread_local const RE2* context; +#endif + +struct DFAStateCacheReset { + int64_t state_budget; + size_t state_cache_size; +}; + +struct DFASearchFailure { + // Nothing yet... +}; + +#define DECLARE_HOOK(type) \ + using type##Callback = void(const type&); \ + void Set##type##Hook(type##Callback* cb); \ + type##Callback* Get##type##Hook(); + +DECLARE_HOOK(DFAStateCacheReset) +DECLARE_HOOK(DFASearchFailure) + +#undef DECLARE_HOOK + +} // namespace hooks } // namespace re2 diff --git a/re2/regexp.cc b/re2/regexp.cc index 7995ffc..2e1bfac 100644 --- a/re2/regexp.cc +++ b/re2/regexp.cc @@ -20,6 +20,7 @@ #include "util/logging.h" #include "util/mutex.h" #include "util/utf.h" +#include "re2/pod_array.h" #include "re2/stringpiece.h" #include "re2/walker-inl.h" @@ -243,16 +244,15 @@ Regexp* Regexp::ConcatOrAlternate(RegexpOp op, Regexp** sub, int nsub, return new Regexp(kRegexpEmptyMatch, flags); } - Regexp** subcopy = NULL; + PODArray subcopy; if (op == kRegexpAlternate && can_factor) { // Going to edit sub; make a copy so we don't step on caller. - subcopy = new Regexp*[nsub]; - memmove(subcopy, sub, nsub * sizeof sub[0]); - sub = subcopy; + subcopy = PODArray(nsub); + memmove(subcopy.data(), sub, nsub * sizeof sub[0]); + sub = subcopy.data(); nsub = FactorAlternation(sub, nsub, flags); if (nsub == 1) { Regexp* re = sub[0]; - delete[] subcopy; return re; } } @@ -269,7 +269,6 @@ Regexp* Regexp::ConcatOrAlternate(RegexpOp op, Regexp** sub, int nsub, subs[nbigsub - 1] = ConcatOrAlternate(op, sub+(nbigsub-1)*kMaxNsub, nsub - (nbigsub-1)*kMaxNsub, flags, false); - delete[] subcopy; return re; } @@ -278,8 +277,6 @@ Regexp* Regexp::ConcatOrAlternate(RegexpOp op, Regexp** sub, int nsub, Regexp** subs = re->sub(); for (int i = 0; i < nsub; i++) subs[i] = sub[i]; - - delete[] subcopy; return re; } @@ -501,6 +498,7 @@ static const char *kErrorStrings[] = { "invalid character class range", "missing ]", "missing )", + "unexpected )", "trailing \\", "no argument for repetition operator", "invalid repetition size", @@ -544,9 +542,12 @@ class NumCapturesWalker : public Regexp::Walker { ncapture_++; return ignored; } + virtual Ignored ShortVisit(Regexp* re, Ignored ignored) { - // Should never be called: we use Walk not WalkExponential. + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "NumCapturesWalker::ShortVisit called"; +#endif return ignored; } @@ -575,7 +576,7 @@ class NamedCapturesWalker : public Regexp::Walker { return m; } - Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) { + virtual Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) { if (re->op() == kRegexpCapture && re->name() != NULL) { // Allocate map once we find a name. if (map_ == NULL) @@ -591,8 +592,10 @@ class NamedCapturesWalker : public Regexp::Walker { } virtual Ignored ShortVisit(Regexp* re, Ignored ignored) { - // Should never be called: we use Walk not WalkExponential. + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "NamedCapturesWalker::ShortVisit called"; +#endif return ignored; } @@ -621,7 +624,7 @@ class CaptureNamesWalker : public Regexp::Walker { return m; } - Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) { + virtual Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) { if (re->op() == kRegexpCapture && re->name() != NULL) { // Allocate map once we find a name. if (map_ == NULL) @@ -633,8 +636,10 @@ class CaptureNamesWalker : public Regexp::Walker { } virtual Ignored ShortVisit(Regexp* re, Ignored ignored) { - // Should never be called: we use Walk not WalkExponential. + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "CaptureNamesWalker::ShortVisit called"; +#endif return ignored; } @@ -651,78 +656,89 @@ std::map* Regexp::CaptureNames() { return w.TakeMap(); } +void ConvertRunesToBytes(bool latin1, Rune* runes, int nrunes, + std::string* bytes) { + if (latin1) { + bytes->resize(nrunes); + for (int i = 0; i < nrunes; i++) + (*bytes)[i] = static_cast(runes[i]); + } else { + bytes->resize(nrunes * UTFmax); // worst case + char* p = &(*bytes)[0]; + for (int i = 0; i < nrunes; i++) + p += runetochar(p, &runes[i]); + bytes->resize(p - &(*bytes)[0]); + bytes->shrink_to_fit(); + } +} + // Determines whether regexp matches must be anchored // with a fixed string prefix. If so, returns the prefix and // the regexp that remains after the prefix. The prefix might // be ASCII case-insensitive. bool Regexp::RequiredPrefix(std::string* prefix, bool* foldcase, Regexp** suffix) { + prefix->clear(); + *foldcase = false; + *suffix = NULL; + // No need for a walker: the regexp must be of the form // 1. some number of ^ anchors // 2. a literal char or string // 3. the rest - prefix->clear(); - *foldcase = false; - *suffix = NULL; if (op_ != kRegexpConcat) return false; - - // Some number of anchors, then a literal or concatenation. int i = 0; - Regexp** sub = this->sub(); - while (i < nsub_ && sub[i]->op_ == kRegexpBeginText) + while (i < nsub_ && sub()[i]->op_ == kRegexpBeginText) i++; if (i == 0 || i >= nsub_) return false; - - Regexp* re = sub[i]; - switch (re->op_) { - default: - return false; - - case kRegexpLiteralString: - // Convert to string in proper encoding. - if (re->parse_flags() & Latin1) { - prefix->resize(re->nrunes_); - for (int j = 0; j < re->nrunes_; j++) - (*prefix)[j] = static_cast(re->runes_[j]); - } else { - // Convert to UTF-8 in place. - // Assume worst-case space and then trim. - prefix->resize(re->nrunes_ * UTFmax); - char *p = &(*prefix)[0]; - for (int j = 0; j < re->nrunes_; j++) { - Rune r = re->runes_[j]; - if (r < Runeself) - *p++ = static_cast(r); - else - p += runetochar(p, &r); - } - prefix->resize(p - &(*prefix)[0]); - } - break; - - case kRegexpLiteral: - if ((re->parse_flags() & Latin1) || re->rune_ < Runeself) { - prefix->append(1, static_cast(re->rune_)); - } else { - char buf[UTFmax]; - prefix->append(buf, runetochar(buf, &re->rune_)); - } - break; - } - *foldcase = (sub[i]->parse_flags() & FoldCase) != 0; + Regexp* re = sub()[i]; + if (re->op_ != kRegexpLiteral && + re->op_ != kRegexpLiteralString) + return false; i++; - - // The rest. if (i < nsub_) { for (int j = i; j < nsub_; j++) - sub[j]->Incref(); - re = Concat(sub + i, nsub_ - i, parse_flags()); + sub()[j]->Incref(); + *suffix = Concat(sub() + i, nsub_ - i, parse_flags()); } else { - re = new Regexp(kRegexpEmptyMatch, parse_flags()); + *suffix = new Regexp(kRegexpEmptyMatch, parse_flags()); } - *suffix = re; + + bool latin1 = (re->parse_flags() & Latin1) != 0; + Rune* runes = re->op_ == kRegexpLiteral ? &re->rune_ : re->runes_; + int nrunes = re->op_ == kRegexpLiteral ? 1 : re->nrunes_; + ConvertRunesToBytes(latin1, runes, nrunes, prefix); + *foldcase = (re->parse_flags() & FoldCase) != 0; + return true; +} + +// Determines whether regexp matches must be unanchored +// with a fixed string prefix. If so, returns the prefix. +// The prefix might be ASCII case-insensitive. +bool Regexp::RequiredPrefixForAccel(std::string* prefix, bool* foldcase) { + prefix->clear(); + *foldcase = false; + + // No need for a walker: the regexp must either begin with or be + // a literal char or string. We "see through" capturing groups, + // but make no effort to glue multiple prefix fragments together. + Regexp* re = op_ == kRegexpConcat && nsub_ > 0 ? sub()[0] : this; + while (re->op_ == kRegexpCapture) { + re = re->sub()[0]; + if (re->op_ == kRegexpConcat && re->nsub_ > 0) + re = re->sub()[0]; + } + if (re->op_ != kRegexpLiteral && + re->op_ != kRegexpLiteralString) + return false; + + bool latin1 = (re->parse_flags() & Latin1) != 0; + Rune* runes = re->op_ == kRegexpLiteral ? &re->rune_ : re->runes_; + int nrunes = re->op_ == kRegexpLiteral ? 1 : re->nrunes_; + ConvertRunesToBytes(latin1, runes, nrunes, prefix); + *foldcase = (re->parse_flags() & FoldCase) != 0; return true; } @@ -903,7 +919,7 @@ void CharClassBuilder::Negate() { // The ranges are allocated in the same block as the header, // necessitating a special allocator and Delete method. -CharClass* CharClass::New(int maxranges) { +CharClass* CharClass::New(size_t maxranges) { CharClass* cc; uint8_t* data = new uint8_t[sizeof *cc + maxranges*sizeof cc->ranges_[0]]; cc = reinterpret_cast(data); @@ -920,7 +936,7 @@ void CharClass::Delete() { } CharClass* CharClass::Negate() { - CharClass* cc = CharClass::New(nranges_+1); + CharClass* cc = CharClass::New(static_cast(nranges_+1)); cc->folds_ascii_ = folds_ascii_; cc->nrunes_ = Runemax + 1 - nrunes_; int n = 0; @@ -939,7 +955,7 @@ CharClass* CharClass::Negate() { return cc; } -bool CharClass::Contains(Rune r) { +bool CharClass::Contains(Rune r) const { RuneRange* rr = ranges_; int n = nranges_; while (n > 0) { @@ -957,7 +973,7 @@ bool CharClass::Contains(Rune r) { } CharClass* CharClassBuilder::GetCharClass() { - CharClass* cc = CharClass::New(static_cast(ranges_.size())); + CharClass* cc = CharClass::New(ranges_.size()); int n = 0; for (iterator it = begin(); it != end(); ++it) cc->ranges_[n++] = *it; diff --git a/re2/regexp.h b/re2/regexp.h index a5d85c8..b6446f9 100644 --- a/re2/regexp.h +++ b/re2/regexp.h @@ -86,6 +86,7 @@ // form accessible to clients, so that client code can analyze the // parsed regular expressions. +#include #include #include #include @@ -177,6 +178,7 @@ enum RegexpStatusCode { kRegexpBadCharRange, // bad character class range kRegexpMissingBracket, // missing closing ] kRegexpMissingParen, // missing closing ) + kRegexpUnexpectedParen, // unexpected closing ) kRegexpTrailingBackslash, // at end of regexp kRegexpRepeatArgument, // repeat argument missing, e.g. "*" kRegexpRepeatSize, // bad repetition argument @@ -252,13 +254,13 @@ class CharClass { bool full() { return nrunes_ == Runemax+1; } bool FoldsASCII() { return folds_ascii_; } - bool Contains(Rune r); + bool Contains(Rune r) const; CharClass* Negate(); private: CharClass(); // not implemented ~CharClass(); // not implemented - static CharClass* New(int maxranges); + static CharClass* New(size_t maxranges); friend class CharClassBuilder; @@ -440,6 +442,17 @@ class Regexp { bool RequiredPrefix(std::string* prefix, bool* foldcase, Regexp** suffix); + // Whether every match of this regexp must be unanchored and + // begin with a non-empty fixed string (perhaps after ASCII + // case-folding). If so, returns the prefix. + // Callers should expect *prefix and *foldcase to be "zeroed" + // regardless of the return value. + bool RequiredPrefixForAccel(std::string* prefix, bool* foldcase); + + // Controls the maximum repeat count permitted by the parser. + // FOR FUZZING ONLY. + static void FUZZING_ONLY_set_maximum_repeat_count(int i); + private: // Constructor allocates vectors as appropriate for operator. explicit Regexp(RegexpOp op, ParseFlags parse_flags); diff --git a/re2/set.cc b/re2/set.cc index 69af666..1870566 100644 --- a/re2/set.cc +++ b/re2/set.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include "util/util.h" #include "util/logging.h" @@ -18,19 +19,37 @@ namespace re2 { -RE2::Set::Set(const RE2::Options& options, RE2::Anchor anchor) { - options_.Copy(options); +RE2::Set::Set(const RE2::Options& options, RE2::Anchor anchor) + : options_(options), + anchor_(anchor), + compiled_(false), + size_(0) { options_.set_never_capture(true); // might unblock some optimisations - anchor_ = anchor; - prog_ = NULL; - compiled_ = false; - size_ = 0; } RE2::Set::~Set() { for (size_t i = 0; i < elem_.size(); i++) elem_[i].second->Decref(); - delete prog_; +} + +RE2::Set::Set(Set&& other) + : options_(other.options_), + anchor_(other.anchor_), + elem_(std::move(other.elem_)), + compiled_(other.compiled_), + size_(other.size_), + prog_(std::move(other.prog_)) { + other.elem_.clear(); + other.elem_.shrink_to_fit(); + other.compiled_ = false; + other.size_ = 0; + other.prog_.reset(); +} + +RE2::Set& RE2::Set::operator=(Set&& other) { + this->~Set(); + (void) new (this) Set(std::move(other)); + return *this; } int RE2::Set::Add(const StringPiece& pattern, std::string* error) { @@ -97,9 +116,9 @@ bool RE2::Set::Compile() { options_.ParseFlags()); re2::Regexp* re = re2::Regexp::Alternate(sub.data(), size_, pf); - prog_ = Prog::CompileSet(re, anchor_, options_.max_mem()); + prog_.reset(Prog::CompileSet(re, anchor_, options_.max_mem())); re->Decref(); - return prog_ != NULL; + return prog_ != nullptr; } bool RE2::Set::Match(const StringPiece& text, std::vector* v) const { @@ -114,6 +133,9 @@ bool RE2::Set::Match(const StringPiece& text, std::vector* v, error_info->kind = kNotCompiled; return false; } +#ifdef RE2_HAVE_THREAD_LOCAL + hooks::context = NULL; +#endif bool dfa_failed = false; std::unique_ptr matches; if (v != NULL) { @@ -124,9 +146,10 @@ bool RE2::Set::Match(const StringPiece& text, std::vector* v, NULL, &dfa_failed, matches.get()); if (dfa_failed) { if (options_.log_errors()) - LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", " - << "bytemap range " << prog_->bytemap_range() << ", " - << "list count " << prog_->list_count(); + LOG(ERROR) << "DFA out of memory: " + << "program size " << prog_->size() << ", " + << "list count " << prog_->list_count() << ", " + << "bytemap range " << prog_->bytemap_range(); if (error_info != NULL) error_info->kind = kOutOfMemory; return false; diff --git a/re2/set.h b/re2/set.h index 59733fd..8d64f30 100644 --- a/re2/set.h +++ b/re2/set.h @@ -5,6 +5,7 @@ #ifndef RE2_SET_H_ #define RE2_SET_H_ +#include #include #include #include @@ -36,6 +37,13 @@ class RE2::Set { Set(const RE2::Options& options, RE2::Anchor anchor); ~Set(); + // Not copyable. + Set(const Set&) = delete; + Set& operator=(const Set&) = delete; + // Movable. + Set(Set&& other); + Set& operator=(Set&& other); + // Adds pattern to the set using the options passed to the constructor. // Returns the index that will identify the regexp in the output of Match(), // or -1 if the regexp cannot be parsed. @@ -67,12 +75,9 @@ class RE2::Set { RE2::Options options_; RE2::Anchor anchor_; std::vector elem_; - re2::Prog* prog_; bool compiled_; int size_; - - Set(const Set&) = delete; - Set& operator=(const Set&) = delete; + std::unique_ptr prog_; }; } // namespace re2 diff --git a/re2/simplify.cc b/re2/simplify.cc index c6eb4a7..663d5fc 100644 --- a/re2/simplify.cc +++ b/re2/simplify.cc @@ -28,8 +28,6 @@ bool Regexp::SimplifyRegexp(const StringPiece& src, ParseFlags flags, Regexp* sre = re->Simplify(); re->Decref(); if (sre == NULL) { - // Should not happen, since Simplify never fails. - LOG(ERROR) << "Simplify failed on " << src; if (status) { status->set_code(kRegexpInternalError); status->set_error_arg(src); @@ -180,10 +178,20 @@ Regexp* Regexp::Simplify() { CoalesceWalker cw; Regexp* cre = cw.Walk(this, NULL); if (cre == NULL) - return cre; + return NULL; + if (cw.stopped_early()) { + cre->Decref(); + return NULL; + } SimplifyWalker sw; Regexp* sre = sw.Walk(cre, NULL); cre->Decref(); + if (sre == NULL) + return NULL; + if (sw.stopped_early()) { + sre->Decref(); + return NULL; + } return sre; } @@ -212,9 +220,10 @@ Regexp* CoalesceWalker::Copy(Regexp* re) { } Regexp* CoalesceWalker::ShortVisit(Regexp* re, Regexp* parent_arg) { - // This should never be called, since we use Walk and not - // WalkExponential. + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "CoalesceWalker::ShortVisit called"; +#endif return re->Incref(); } @@ -437,9 +446,10 @@ Regexp* SimplifyWalker::Copy(Regexp* re) { } Regexp* SimplifyWalker::ShortVisit(Regexp* re, Regexp* parent_arg) { - // This should never be called, since we use Walk and not - // WalkExponential. + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "SimplifyWalker::ShortVisit called"; +#endif return re->Incref(); } diff --git a/re2/testing/backtrack.cc b/re2/testing/backtrack.cc index 1e888da..920a453 100644 --- a/re2/testing/backtrack.cc +++ b/re2/testing/backtrack.cc @@ -29,6 +29,7 @@ #include "util/util.h" #include "util/logging.h" +#include "re2/pod_array.h" #include "re2/prog.h" #include "re2/regexp.h" @@ -53,7 +54,6 @@ namespace re2 { class Backtracker { public: explicit Backtracker(Prog* prog); - ~Backtracker(); bool Search(const StringPiece& text, const StringPiece& context, bool anchored, bool longest, @@ -79,9 +79,11 @@ class Backtracker { int nsubmatch_; // # of submatches to fill in // Search state - const char* cap_[64]; // capture registers - uint32_t *visited_; // bitmap: (Inst*, char*) pairs already backtracked - size_t nvisited_; // # of words in bitmap + const char* cap_[64]; // capture registers + PODArray visited_; // bitmap: (Inst*, char*) pairs visited + + Backtracker(const Backtracker&) = delete; + Backtracker& operator=(const Backtracker&) = delete; }; Backtracker::Backtracker(Prog* prog) @@ -90,13 +92,7 @@ Backtracker::Backtracker(Prog* prog) longest_(false), endmatch_(false), submatch_(NULL), - nsubmatch_(0), - visited_(NULL), - nvisited_(0) { -} - -Backtracker::~Backtracker() { - delete[] visited_; + nsubmatch_(0) { } // Runs a backtracking search. @@ -107,9 +103,9 @@ bool Backtracker::Search(const StringPiece& text, const StringPiece& context, context_ = context; if (context_.data() == NULL) context_ = text; - if (prog_->anchor_start() && text.begin() > context_.begin()) + if (prog_->anchor_start() && BeginPtr(text) > BeginPtr(context_)) return false; - if (prog_->anchor_end() && text.end() < context_.end()) + if (prog_->anchor_end() && EndPtr(text) < EndPtr(context_)) return false; anchored_ = anchored | prog_->anchor_start(); longest_ = longest | prog_->anchor_end(); @@ -130,10 +126,10 @@ bool Backtracker::Search(const StringPiece& text, const StringPiece& context, // Allocate new visited_ bitmap -- size is proportional // to text, so have to reallocate on each call to Search. - delete[] visited_; - nvisited_ = (prog_->size()*(text.size()+1) + 31)/32; - visited_ = new uint32_t[nvisited_]; - memset(visited_, 0, nvisited_*sizeof visited_[0]); + int nvisited = prog_->size() * static_cast(text.size()+1); + nvisited = (nvisited + 31) / 32; + visited_ = PODArray(nvisited); + memset(visited_.data(), 0, nvisited*sizeof visited_[0]); // Anchored search must start at text.begin(). if (anchored_) { @@ -163,8 +159,9 @@ bool Backtracker::Visit(int id, const char* p) { // either it didn't match or it did but we're hoping for a better match. // Either way, don't go down that road again. CHECK(p <= text_.data() + text_.size()); - size_t n = id*(text_.size()+1) + (p - text_.data()); - CHECK_LT(n/32, nvisited_); + int n = id * static_cast(text_.size()+1) + + static_cast(p-text_.data()); + CHECK_LT(n/32, visited_.size()); if (visited_[n/32] & (1 << (n&31))) return false; visited_[n/32] |= 1 << (n&31); @@ -270,7 +267,7 @@ bool Prog::UnsafeSearchBacktrack(const StringPiece& text, bool longest = kind != kFirstMatch; if (!b.Search(text, context, anchored, longest, match, nmatch)) return false; - if (kind == kFullMatch && match[0].end() != text.end()) + if (kind == kFullMatch && EndPtr(match[0]) != EndPtr(text)) return false; return true; } diff --git a/re2/testing/charclass_test.cc b/re2/testing/charclass_test.cc index a2837a6..9c2a32f 100644 --- a/re2/testing/charclass_test.cc +++ b/re2/testing/charclass_test.cc @@ -85,7 +85,7 @@ static CCTest tests[] = { { {-1} } }, }; -template +template static void Broke(const char *desc, const CCTest* t, CharClass* cc) { if (t == NULL) { printf("\t%s:", desc); @@ -136,7 +136,7 @@ void Delete(CharClassBuilder* cc) { delete cc; } -template +template bool CorrectCC(CharClass *cc, CCTest *t, const char *desc) { typename CharClass::iterator it = cc->begin(); int size = 0; diff --git a/re2/testing/compile_test.cc b/re2/testing/compile_test.cc index 6b77cf9..4718830 100644 --- a/re2/testing/compile_test.cc +++ b/re2/testing/compile_test.cc @@ -109,6 +109,20 @@ static Test tests[] = { { "[[-`]", "3. byte [5b-60] 0 -> 4\n" "4. match! 0\n" }, + // Issue 310 + { "(?:|a)*", + "3+ nop -> 7\n" + "4. nop -> 9\n" + "5+ nop -> 7\n" + "6. nop -> 9\n" + "7+ nop -> 5\n" + "8. byte [61-61] 0 -> 5\n" + "9. match! 0\n" }, + { "(?:|a)+", + "3+ nop -> 5\n" + "4. byte [61-61] 0 -> 5\n" + "5+ nop -> 3\n" + "6. match! 0\n" }, }; TEST(TestRegexpCompileToProg, Simple) { @@ -147,10 +161,19 @@ static void DumpByteMap(StringPiece pattern, Regexp::ParseFlags flags, Regexp* re = Regexp::Parse(pattern, flags, NULL); EXPECT_TRUE(re != NULL); - Prog* prog = re->CompileToProg(0); - EXPECT_TRUE(prog != NULL); - *bytemap = prog->DumpByteMap(); - delete prog; + { + Prog* prog = re->CompileToProg(0); + EXPECT_TRUE(prog != NULL); + *bytemap = prog->DumpByteMap(); + delete prog; + } + + { + Prog* prog = re->CompileToReverseProg(0); + EXPECT_TRUE(prog != NULL); + EXPECT_EQ(*bytemap, prog->DumpByteMap()); + delete prog; + } re->Decref(); } @@ -213,16 +236,11 @@ TEST(TestCompile, UTF8Ranges) { EXPECT_EQ("[00-09] -> 0\n" "[0a-0a] -> 1\n" "[0b-7f] -> 0\n" - "[80-8f] -> 2\n" - "[90-9f] -> 3\n" - "[a0-bf] -> 4\n" + "[80-bf] -> 2\n" "[c0-c1] -> 1\n" - "[c2-df] -> 5\n" - "[e0-e0] -> 6\n" - "[e1-ef] -> 7\n" - "[f0-f0] -> 8\n" - "[f1-f3] -> 9\n" - "[f4-f4] -> 10\n" + "[c2-df] -> 3\n" + "[e0-ef] -> 4\n" + "[f0-f4] -> 5\n" "[f5-ff] -> 1\n", bytemap); } @@ -232,7 +250,7 @@ TEST(TestCompile, InsufficientMemory) { "^(?P[^\\s]+)\\s+(?P[^\\s]+)\\s+(?P.+)$", Regexp::LikePerl, NULL); EXPECT_TRUE(re != NULL); - Prog* prog = re->CompileToProg(920); + Prog* prog = re->CompileToProg(850); // If the memory budget has been exhausted, compilation should fail // and return NULL instead of trying to do anything with NoMatch(). EXPECT_TRUE(prog == NULL); @@ -299,20 +317,22 @@ TEST(TestCompile, Bug26705922) { "8. byte [f0-f0] 0 -> 7\n", reverse); - Dump("[\\x{80}-\\x{10FFFF}]", Regexp::LikePerl, NULL, &reverse); - EXPECT_EQ("3. byte [80-bf] 0 -> 4\n" - "4+ byte [c2-df] 0 -> 7\n" - "5+ byte [a0-bf] 1 -> 8\n" - "6. byte [80-bf] 0 -> 9\n" + Dump("[\\x{80}-\\x{10FFFF}]", Regexp::LikePerl, &forward, &reverse); + EXPECT_EQ("3+ byte [c2-df] 0 -> 6\n" + "4+ byte [e0-ef] 0 -> 8\n" + "5. byte [f0-f4] 0 -> 9\n" + "6. byte [80-bf] 0 -> 7\n" "7. match! 0\n" - "8. byte [e0-e0] 0 -> 7\n" - "9+ byte [e1-ef] 0 -> 7\n" - "10+ byte [90-bf] 1 -> 13\n" - "11+ byte [80-bf] 1 -> 14\n" - "12. byte [80-8f] 0 -> 15\n" - "13. byte [f0-f0] 0 -> 7\n" - "14. byte [f1-f3] 0 -> 7\n" - "15. byte [f4-f4] 0 -> 7\n", + "8. byte [80-bf] 0 -> 6\n" + "9. byte [80-bf] 0 -> 8\n", + forward); + EXPECT_EQ("3. byte [80-bf] 0 -> 4\n" + "4+ byte [c2-df] 0 -> 6\n" + "5. byte [80-bf] 0 -> 7\n" + "6. match! 0\n" + "7+ byte [e0-ef] 0 -> 6\n" + "8. byte [80-bf] 0 -> 9\n" + "9. byte [f0-f4] 0 -> 6\n", reverse); } @@ -332,27 +352,37 @@ TEST(TestCompile, Bug35237384) { forward); Dump("(a*|b*)*{3,}", Regexp::Latin1|Regexp::NeverCapture, &forward, NULL); - EXPECT_EQ("3+ nop -> 6\n" - "4+ nop -> 8\n" - "5. nop -> 21\n" - "6+ byte [61-61] 1 -> 6\n" - "7. nop -> 3\n" - "8+ byte [62-62] 1 -> 8\n" - "9. nop -> 3\n" - "10+ byte [61-61] 1 -> 10\n" - "11. nop -> 21\n" - "12+ byte [62-62] 1 -> 12\n" - "13. nop -> 21\n" - "14+ byte [61-61] 1 -> 14\n" - "15. nop -> 18\n" - "16+ byte [62-62] 1 -> 16\n" - "17. nop -> 18\n" - "18+ nop -> 14\n" - "19+ nop -> 16\n" - "20. match! 0\n" - "21+ nop -> 10\n" - "22+ nop -> 12\n" - "23. nop -> 18\n", + EXPECT_EQ("3+ nop -> 28\n" + "4. nop -> 30\n" + "5+ byte [61-61] 1 -> 5\n" + "6. nop -> 32\n" + "7+ byte [61-61] 1 -> 7\n" + "8. nop -> 26\n" + "9+ byte [61-61] 1 -> 9\n" + "10. nop -> 20\n" + "11+ byte [62-62] 1 -> 11\n" + "12. nop -> 20\n" + "13+ byte [62-62] 1 -> 13\n" + "14. nop -> 26\n" + "15+ byte [62-62] 1 -> 15\n" + "16. nop -> 32\n" + "17+ nop -> 9\n" + "18. nop -> 11\n" + "19. match! 0\n" + "20+ nop -> 17\n" + "21. nop -> 19\n" + "22+ nop -> 7\n" + "23. nop -> 13\n" + "24+ nop -> 17\n" + "25. nop -> 19\n" + "26+ nop -> 22\n" + "27. nop -> 24\n" + "28+ nop -> 5\n" + "29. nop -> 15\n" + "30+ nop -> 22\n" + "31. nop -> 24\n" + "32+ nop -> 28\n" + "33. nop -> 30\n", forward); Dump("((|S.+)+|(|S.+)+|){2}", Regexp::Latin1|Regexp::NeverCapture, &forward, NULL); diff --git a/re2/testing/dfa_test.cc b/re2/testing/dfa_test.cc index 25f2311..842daaf 100644 --- a/re2/testing/dfa_test.cc +++ b/re2/testing/dfa_test.cc @@ -26,6 +26,20 @@ DEFINE_FLAG(int, threads, 4, "number of threads"); namespace re2 { +static int state_cache_resets = 0; +static int search_failures = 0; + +struct SetHooks { + SetHooks() { + hooks::SetDFAStateCacheResetHook([](const hooks::DFAStateCacheReset&) { + ++state_cache_resets; + }); + hooks::SetDFASearchFailureHook([](const hooks::DFASearchFailure&) { + ++search_failures; + }); + } +} set_hooks; + // Check that multithreaded access to DFA class works. // Helper function: builds entire DFA for prog. @@ -108,44 +122,6 @@ TEST(SingleThreaded, BuildEntireDFA) { re->Decref(); } -// Generates and returns a string over binary alphabet {0,1} that contains -// all possible binary sequences of length n as subsequences. The obvious -// brute force method would generate a string of length n * 2^n, but this -// generates a string of length n + 2^n - 1 called a De Bruijn cycle. -// See Knuth, The Art of Computer Programming, Vol 2, Exercise 3.2.2 #17. -// Such a string is useful for testing a DFA. If you have a DFA -// where distinct last n bytes implies distinct states, then running on a -// DeBruijn string causes the DFA to need to create a new state at every -// position in the input, never reusing any states until it gets to the -// end of the string. This is the worst possible case for DFA execution. -static std::string DeBruijnString(int n) { - CHECK_LT(n, static_cast(8*sizeof(int))); - CHECK_GT(n, 0); - - std::vector did(size_t{1}<Decref(); // Reset to original behaviour. - Prog::TEST_dfa_should_bail_when_slow(true); + Prog::TESTING_ONLY_set_dfa_should_bail_when_slow(true); + ASSERT_GT(state_cache_resets, 0); + ASSERT_EQ(search_failures, 0); } // Helper function: searches for match, which should match, @@ -238,7 +218,9 @@ static void DoSearch(Prog* prog, const StringPiece& match, } TEST(Multithreaded, SearchDFA) { - Prog::TEST_dfa_should_bail_when_slow(false); + Prog::TESTING_ONLY_set_dfa_should_bail_when_slow(false); + state_cache_resets = 0; + search_failures = 0; // Same as single-threaded test above. const int n = 18; @@ -277,7 +259,9 @@ TEST(Multithreaded, SearchDFA) { re->Decref(); // Reset to original behaviour. - Prog::TEST_dfa_should_bail_when_slow(true); + Prog::TESTING_ONLY_set_dfa_should_bail_when_slow(true); + ASSERT_GT(state_cache_resets, 0); + ASSERT_EQ(search_failures, 0); } struct ReverseTest { diff --git a/re2/testing/exhaustive_tester.cc b/re2/testing/exhaustive_tester.cc index bdac381..b0409c3 100644 --- a/re2/testing/exhaustive_tester.cc +++ b/re2/testing/exhaustive_tester.cc @@ -67,8 +67,8 @@ static void PrintResult(const RE2& re, const StringPiece& input, RE2::Anchor anc printf("-"); else printf("%td-%td", - m[i].begin() - input.begin(), - m[i].end() - input.begin()); + BeginPtr(m[i]) - BeginPtr(input), + EndPtr(m[i]) - BeginPtr(input)); } } diff --git a/re2/testing/filtered_re2_test.cc b/re2/testing/filtered_re2_test.cc index deef2f8..c788fda 100644 --- a/re2/testing/filtered_re2_test.cc +++ b/re2/testing/filtered_re2_test.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include "util/test.h" #include "util/logging.h" @@ -291,4 +292,49 @@ TEST(FilteredRE2Test, EmptyStringInStringSetBug) { "EmptyStringInStringSetBug", &v)); } +TEST(FilteredRE2Test, MoveSemantics) { + FilterTestVars v1; + int id; + v1.f.Add("foo\\d+", v1.opts, &id); + EXPECT_EQ(0, id); + v1.f.Compile(&v1.atoms); + EXPECT_EQ(1, v1.atoms.size()); + EXPECT_EQ("foo", v1.atoms[0]); + v1.f.AllMatches("abc foo1 xyz", {0}, &v1.matches); + EXPECT_EQ(1, v1.matches.size()); + EXPECT_EQ(0, v1.matches[0]); + v1.f.AllMatches("abc bar2 xyz", {0}, &v1.matches); + EXPECT_EQ(0, v1.matches.size()); + + // The moved-to object should do what the moved-from object did. + FilterTestVars v2; + v2.f = std::move(v1.f); + v2.f.AllMatches("abc foo1 xyz", {0}, &v2.matches); + EXPECT_EQ(1, v2.matches.size()); + EXPECT_EQ(0, v2.matches[0]); + v2.f.AllMatches("abc bar2 xyz", {0}, &v2.matches); + EXPECT_EQ(0, v2.matches.size()); + + // The moved-from object should have been reset and be reusable. + v1.f.Add("bar\\d+", v1.opts, &id); + EXPECT_EQ(0, id); + v1.f.Compile(&v1.atoms); + EXPECT_EQ(1, v1.atoms.size()); + EXPECT_EQ("bar", v1.atoms[0]); + v1.f.AllMatches("abc foo1 xyz", {0}, &v1.matches); + EXPECT_EQ(0, v1.matches.size()); + v1.f.AllMatches("abc bar2 xyz", {0}, &v1.matches); + EXPECT_EQ(1, v1.matches.size()); + EXPECT_EQ(0, v1.matches[0]); + + // Verify that "overwriting" works and also doesn't leak memory. + // (The latter will need a leak detector such as LeakSanitizer.) + v1.f = std::move(v2.f); + v1.f.AllMatches("abc foo1 xyz", {0}, &v1.matches); + EXPECT_EQ(1, v1.matches.size()); + EXPECT_EQ(0, v1.matches[0]); + v1.f.AllMatches("abc bar2 xyz", {0}, &v1.matches); + EXPECT_EQ(0, v1.matches.size()); +} + } // namespace re2 diff --git a/re2/testing/null_walker.cc b/re2/testing/null_walker.cc index 77fa723..2bdea02 100644 --- a/re2/testing/null_walker.cc +++ b/re2/testing/null_walker.cc @@ -13,13 +13,16 @@ namespace re2 { class NullWalker : public Regexp::Walker { public: - NullWalker() { } - bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, - bool* child_args, int nchild_args); + NullWalker() {} - bool ShortVisit(Regexp* re, bool a) { - // Should never be called: we use Walk not WalkExponential. + virtual bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, + bool* child_args, int nchild_args); + + virtual bool ShortVisit(Regexp* re, bool a) { + // Should never be called: we use Walk(), not WalkExponential(). +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION LOG(DFATAL) << "NullWalker::ShortVisit called"; +#endif return a; } diff --git a/re2/testing/parse_test.cc b/re2/testing/parse_test.cc index 3446526..e571127 100644 --- a/re2/testing/parse_test.cc +++ b/re2/testing/parse_test.cc @@ -164,6 +164,7 @@ static Test tests[] = { // Test named captures { "(?Pa)", "cap{name:lit{a}}" }, + { "(?P<中文>a)", "cap{中文:lit{a}}" }, // Case-folded literals { "[Aa]", "litfold{a}" }, diff --git a/re2/testing/re2_arg_test.cc b/re2/testing/re2_arg_test.cc index 7a38de7..f62e17c 100644 --- a/re2/testing/re2_arg_test.cc +++ b/re2/testing/re2_arg_test.cc @@ -11,6 +11,7 @@ #include #include "util/test.h" +#include "util/logging.h" #include "re2/re2.h" namespace re2 { @@ -132,4 +133,28 @@ TEST(RE2ArgTest, Uint64Test) { PARSE_FOR_TYPE(uint64_t, 5); } +TEST(RE2ArgTest, ParseFromTest) { +#if !defined(_MSC_VER) + struct { + bool ParseFrom(const char* str, size_t n) { + LOG(INFO) << "str = " << str << ", n = " << n; + return true; + } + } obj1; + RE2::Arg arg1(&obj1); + EXPECT_TRUE(arg1.Parse("one", 3)); + + struct { + bool ParseFrom(const char* str, size_t n) { + LOG(INFO) << "str = " << str << ", n = " << n; + return false; + } + // Ensure that RE2::Arg works even with overloaded ParseFrom(). + void ParseFrom(const char* str) {} + } obj2; + RE2::Arg arg2(&obj2); + EXPECT_FALSE(arg2.Parse("two", 3)); +#endif +} + } // namespace re2 diff --git a/re2/testing/re2_test.cc b/re2/testing/re2_test.cc index 2f4b90c..b1f7d73 100644 --- a/re2/testing/re2_test.cc +++ b/re2/testing/re2_test.cc @@ -12,6 +12,7 @@ #include #include #include +#include #if !defined(_MSC_VER) && !defined(__CYGWIN__) && !defined(__MINGW32__) #include #include /* for sysconf */ @@ -223,6 +224,15 @@ TEST(RE2, Extract) { ASSERT_EQ(s, "'foo'"); } +TEST(RE2, MaxSubmatchTooLarge) { + std::string s; + ASSERT_FALSE(RE2::Extract("foo", "f(o+)", "\\1\\2", &s)); + s = "foo"; + ASSERT_FALSE(RE2::Replace(&s, "f(o+)", "\\1\\2")); + s = "foo"; + ASSERT_FALSE(RE2::GlobalReplace(&s, "f(o+)", "\\1\\2")); +} + TEST(RE2, Consume) { RE2 r("\\s*(\\w+)"); // matches a word, possibly proceeded by whitespace std::string word; @@ -473,40 +483,39 @@ TEST(ProgramFanout, BigProgram) { RE2 re100("(?:(?:(?:(?:(?:.)?){100})*)+)"); RE2 re1000("(?:(?:(?:(?:(?:.)?){1000})*)+)"); - std::map histogram; + std::vector histogram; - // 3 is the largest non-empty bucket and has 1 element. + // 3 is the largest non-empty bucket and has 2 element. ASSERT_EQ(3, re1.ProgramFanout(&histogram)); - ASSERT_EQ(1, histogram[3]); + ASSERT_EQ(2, histogram[3]); - // 7 is the largest non-empty bucket and has 10 elements. - ASSERT_EQ(7, re10.ProgramFanout(&histogram)); - ASSERT_EQ(10, histogram[7]); + // 6 is the largest non-empty bucket and has 11 elements. + ASSERT_EQ(6, re10.ProgramFanout(&histogram)); + ASSERT_EQ(11, histogram[6]); - // 10 is the largest non-empty bucket and has 100 elements. - ASSERT_EQ(10, re100.ProgramFanout(&histogram)); - ASSERT_EQ(100, histogram[10]); + // 9 is the largest non-empty bucket and has 101 elements. + ASSERT_EQ(9, re100.ProgramFanout(&histogram)); + ASSERT_EQ(101, histogram[9]); - // 13 is the largest non-empty bucket and has 1000 elements. + // 13 is the largest non-empty bucket and has 1001 elements. ASSERT_EQ(13, re1000.ProgramFanout(&histogram)); - ASSERT_EQ(1000, histogram[13]); + ASSERT_EQ(1001, histogram[13]); - // 2 is the largest non-empty bucket and has 3 elements. - // This differs from the others due to how reverse `.' works. + // 2 is the largest non-empty bucket and has 2 element. ASSERT_EQ(2, re1.ReverseProgramFanout(&histogram)); - ASSERT_EQ(3, histogram[2]); + ASSERT_EQ(2, histogram[2]); - // 5 is the largest non-empty bucket and has 10 elements. + // 5 is the largest non-empty bucket and has 11 elements. ASSERT_EQ(5, re10.ReverseProgramFanout(&histogram)); - ASSERT_EQ(10, histogram[5]); + ASSERT_EQ(11, histogram[5]); - // 9 is the largest non-empty bucket and has 100 elements. + // 9 is the largest non-empty bucket and has 101 elements. ASSERT_EQ(9, re100.ReverseProgramFanout(&histogram)); - ASSERT_EQ(100, histogram[9]); + ASSERT_EQ(101, histogram[9]); - // 12 is the largest non-empty bucket and has 1000 elements. + // 12 is the largest non-empty bucket and has 1001 elements. ASSERT_EQ(12, re1000.ReverseProgramFanout(&histogram)); - ASSERT_EQ(1000, histogram[12]); + ASSERT_EQ(1001, histogram[12]); } // Issue 956519: handling empty character sets was @@ -1232,11 +1241,10 @@ TEST(RE2, DeepRecursion) { // Suggested by Josh Hyman. Failed when SearchOnePass was // not implementing case-folding. TEST(CaseInsensitive, MatchAndConsume) { - std::string result; std::string text = "A fish named *Wanda*"; StringPiece sp(text); - - EXPECT_TRUE(RE2::PartialMatch(sp, "(?i)([wand]{5})", &result)); + StringPiece result; + EXPECT_TRUE(RE2::PartialMatch(text, "(?i)([wand]{5})", &result)); EXPECT_TRUE(RE2::FindAndConsume(&sp, "(?i)([wand]{5})", &result)); } @@ -1269,38 +1277,43 @@ TEST(RE2, CL8622304) { EXPECT_EQ(val, "1,0x2F,030,4,5"); } - // Check that RE2 returns correct regexp pieces on error. // In particular, make sure it returns whole runes // and that it always reports invalid UTF-8. // Also check that Perl error flag piece is big enough. static struct ErrorTest { const char *regexp; - const char *error; + RE2::ErrorCode error_code; + const char *error_arg; } error_tests[] = { - { "ab\\αcd", "\\α" }, - { "ef\\x☺01", "\\x☺0" }, - { "gh\\x1☺01", "\\x1☺" }, - { "ij\\x1", "\\x1" }, - { "kl\\x", "\\x" }, - { "uv\\x{0000☺}", "\\x{0000☺" }, - { "wx\\p{ABC", "\\p{ABC" }, - { "yz(?smiUX:abc)", "(?smiUX" }, // used to return (?s but the error is X - { "aa(?sm☺i", "(?sm☺" }, - { "bb[abc", "[abc" }, - - { "mn\\x1\377", "" }, // no argument string returned for invalid UTF-8 - { "op\377qr", "" }, - { "st\\x{00000\377", "" }, - { "zz\\p{\377}", "" }, - { "zz\\x{00\377}", "" }, - { "zz(?Pabc)", "" }, + { "ab\\αcd", RE2::ErrorBadEscape, "\\α" }, + { "ef\\x☺01", RE2::ErrorBadEscape, "\\x☺0" }, + { "gh\\x1☺01", RE2::ErrorBadEscape, "\\x1☺" }, + { "ij\\x1", RE2::ErrorBadEscape, "\\x1" }, + { "kl\\x", RE2::ErrorBadEscape, "\\x" }, + { "uv\\x{0000☺}", RE2::ErrorBadEscape, "\\x{0000☺" }, + { "wx\\p{ABC", RE2::ErrorBadCharRange, "\\p{ABC" }, + // used to return (?s but the error is X + { "yz(?smiUX:abc)", RE2::ErrorBadPerlOp, "(?smiUX" }, + { "aa(?sm☺i", RE2::ErrorBadPerlOp, "(?sm☺" }, + { "bb[abc", RE2::ErrorMissingBracket, "[abc" }, + { "abc(def", RE2::ErrorMissingParen, "abc(def" }, + { "abc)def", RE2::ErrorUnexpectedParen, "abc)def" }, + + // no argument string returned for invalid UTF-8 + { "mn\\x1\377", RE2::ErrorBadUTF8, "" }, + { "op\377qr", RE2::ErrorBadUTF8, "" }, + { "st\\x{00000\377", RE2::ErrorBadUTF8, "" }, + { "zz\\p{\377}", RE2::ErrorBadUTF8, "" }, + { "zz\\x{00\377}", RE2::ErrorBadUTF8, "" }, + { "zz(?Pabc)", RE2::ErrorBadUTF8, "" }, }; -TEST(RE2, ErrorArgs) { +TEST(RE2, ErrorCodeAndArg) { for (size_t i = 0; i < arraysize(error_tests); i++) { RE2 re(error_tests[i].regexp, RE2::Quiet); EXPECT_FALSE(re.ok()); - EXPECT_EQ(re.error_arg(), error_tests[i].error) << re.error(); + EXPECT_EQ(re.error_code(), error_tests[i].error_code) << re.error(); + EXPECT_EQ(re.error_arg(), error_tests[i].error_arg) << re.error(); } } @@ -1628,4 +1641,19 @@ TEST(RE2, Issue104) { ASSERT_EQ("小人小类小", s); } +TEST(RE2, Issue310) { + // (?:|a)* matched more text than (?:|a)+ did. + + std::string s = "aaa"; + StringPiece m; + + RE2 star("(?:|a)*"); + ASSERT_TRUE(star.Match(s, 0, s.size(), RE2::UNANCHORED, &m, 1)); + ASSERT_EQ(m, "") << " got m='" << m << "', want ''"; + + RE2 plus("(?:|a)+"); + ASSERT_TRUE(plus.Match(s, 0, s.size(), RE2::UNANCHORED, &m, 1)); + ASSERT_EQ(m, "") << " got m='" << m << "', want ''"; +} + } // namespace re2 diff --git a/re2/testing/regexp_benchmark.cc b/re2/testing/regexp_benchmark.cc index 089d822..3eeb098 100644 --- a/re2/testing/regexp_benchmark.cc +++ b/re2/testing/regexp_benchmark.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "util/benchmark.h" @@ -20,6 +21,7 @@ #include "re2/prog.h" #include "re2/re2.h" #include "re2/regexp.h" +#include "util/mutex.h" #include "util/pcre.h" namespace re2 { @@ -152,32 +154,38 @@ ParseImpl SearchParse1CachedPCRE, SearchParse1CachedRE2; // Generate random text that won't contain the search string, // to test worst-case search behavior. -void MakeText(std::string* text, int64_t nbytes) { - srand(1); - text->resize(nbytes); - for (int64_t i = 0; i < nbytes; i++) { - // Generate a one-byte rune that isn't a control character (e.g. '\n'). - // Clipping to 0x20 introduces some bias, but we don't need uniformity. - int byte = rand() & 0x7F; - if (byte < 0x20) - byte = 0x20; - (*text)[i] = byte; - } +std::string RandomText(int64_t nbytes) { + static const std::string* const text = []() { + std::string* text = new std::string; + srand(1); + text->resize(16<<20); + for (int64_t i = 0; i < 16<<20; i++) { + // Generate a one-byte rune that isn't a control character (e.g. '\n'). + // Clipping to 0x20 introduces some bias, but we don't need uniformity. + int byte = rand() & 0x7F; + if (byte < 0x20) + byte = 0x20; + (*text)[i] = byte; + } + return text; + }(); + CHECK_LE(nbytes, 16<<20); + return text->substr(0, nbytes); } // Makes text of size nbytes, then calls run to search // the text for regexp iters times. void Search(benchmark::State& state, const char* regexp, SearchImpl* search) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); search(state, regexp, s, Prog::kUnanchored, false); state.SetBytesProcessed(state.iterations() * state.range(0)); } -// These two are easy because they start with an A, -// giving the search loop something to memchr for. +// These three are easy because they have prefixes, +// giving the search loop something to prefix accel. #define EASY0 "ABCDEFGHIJKLMNOPQRSTUVWXYZ$" #define EASY1 "A[AB]B[BC]C[CD]D[DE]E[EF]F[FG]G[GH]H[HI]I[IJ]J$" +#define EASY2 "(?i)" EASY0 // This is a little harder, since it starts with a character class // and thus can't be memchr'ed. Could look for ABC and work backward, @@ -221,6 +229,18 @@ BENCHMARK_RANGE(Search_Easy1_CachedPCRE, 8, 16<<20)->ThreadRange(1, NumCPUs() #endif BENCHMARK_RANGE(Search_Easy1_CachedRE2, 8, 16<<20)->ThreadRange(1, NumCPUs()); +void Search_Easy2_CachedDFA(benchmark::State& state) { Search(state, EASY2, SearchCachedDFA); } +void Search_Easy2_CachedNFA(benchmark::State& state) { Search(state, EASY2, SearchCachedNFA); } +void Search_Easy2_CachedPCRE(benchmark::State& state) { Search(state, EASY2, SearchCachedPCRE); } +void Search_Easy2_CachedRE2(benchmark::State& state) { Search(state, EASY2, SearchCachedRE2); } + +BENCHMARK_RANGE(Search_Easy2_CachedDFA, 8, 16<<20)->ThreadRange(1, NumCPUs()); +BENCHMARK_RANGE(Search_Easy2_CachedNFA, 8, 256<<10)->ThreadRange(1, NumCPUs()); +#ifdef USEPCRE +BENCHMARK_RANGE(Search_Easy2_CachedPCRE, 8, 16<<20)->ThreadRange(1, NumCPUs()); +#endif +BENCHMARK_RANGE(Search_Easy2_CachedRE2, 8, 16<<20)->ThreadRange(1, NumCPUs()); + void Search_Medium_CachedDFA(benchmark::State& state) { Search(state, MEDIUM, SearchCachedDFA); } void Search_Medium_CachedNFA(benchmark::State& state) { Search(state, MEDIUM, SearchCachedNFA); } void Search_Medium_CachedPCRE(benchmark::State& state) { Search(state, MEDIUM, SearchCachedPCRE); } @@ -273,8 +293,7 @@ void SearchBigFixed(benchmark::State& state, SearchImpl* search) { std::string s; s.append(state.range(0)/2, 'x'); std::string regexp = "^" + s + ".*$"; - std::string t; - MakeText(&t, state.range(0)/2); + std::string t = RandomText(state.range(0)/2); s += t; search(state, regexp.c_str(), s, Prog::kUnanchored, true); state.SetBytesProcessed(state.iterations() * state.range(0)); @@ -295,8 +314,7 @@ BENCHMARK_RANGE(Search_BigFixed_CachedRE2, 8, 1<<20)->ThreadRange(1, NumCPUs // Benchmark: FindAndConsume void FindAndConsume(benchmark::State& state) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); s.append("Hello World"); RE2 re("((Hello World))"); for (auto _ : state) { @@ -314,8 +332,7 @@ BENCHMARK_RANGE(FindAndConsume, 8, 16<<20)->ThreadRange(1, NumCPUs()); void SearchSuccess(benchmark::State& state, const char* regexp, SearchImpl* search) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); search(state, regexp, s, Prog::kAnchored, true); state.SetBytesProcessed(state.iterations() * state.range(0)); } @@ -385,8 +402,7 @@ BENCHMARK_RANGE(Search_Success1_CachedBitState, 8, 2<<20)->ThreadRange(1, NumCPU // Note that OnePass doesn't implement it! void SearchAltMatch(benchmark::State& state, SearchImpl* search) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); search(state, "\\C*", s, Prog::kAnchored, true); state.SetBytesProcessed(state.iterations() * state.range(0)); } @@ -770,8 +786,7 @@ BENCHMARK(BM_RE2_Compile)->ThreadRange(1, NumCPUs()); // Makes text of size nbytes, then calls run to search // the text for regexp iters times. void SearchPhone(benchmark::State& state, ParseImpl* search) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); s.append("(650) 253-0001"); search(state, "(\\d{3}-|\\(\\d{3}\\)\\s+)(\\d{3}-\\d{4})", s); state.SetBytesProcessed(state.iterations() * state.range(0)); @@ -792,40 +807,6 @@ BENCHMARK_RANGE(SearchPhone_CachedRE2, 8, 16<<20)->ThreadRange(1, NumCPUs()); /* TODO(rsc): Make this work again. - -// Generates and returns a string over binary alphabet {0,1} that contains -// all possible binary sequences of length n as subsequences. The obvious -// brute force method would generate a string of length n * 2^n, but this -// generates a string of length n + 2^n - 1 called a De Bruijn cycle. -// See Knuth, The Art of Computer Programming, Vol 2, Exercise 3.2.2 #17. -static std::string DeBruijnString(int n) { - CHECK_LT(n, 8*sizeof(int)); - CHECK_GT(n, 0); - - std::vector did(1<; + Prog* prog = cache[regexp]; + if (prog == NULL) { + Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); + CHECK(re); + prog = re->CompileToProg(int64_t{1}<<31); // mostly for the DFA + CHECK(prog); + cache[regexp] = prog; + re->Decref(); + // We must call this here - while we have exclusive access. + prog->IsOnePass(); + } + return prog; +} + +PCRE* GetCachedPCRE(const char* regexp) { + static auto& mutex = *new Mutex; + MutexLock lock(&mutex); + static auto& cache = *new std::unordered_map; + PCRE* re = cache[regexp]; + if (re == NULL) { + re = new PCRE(regexp, PCRE::UTF8); + CHECK_EQ(re->error(), ""); + cache[regexp] = re; + } + return re; +} + +RE2* GetCachedRE2(const char* regexp) { + static auto& mutex = *new Mutex; + MutexLock lock(&mutex); + static auto& cache = *new std::unordered_map; + RE2* re = cache[regexp]; + if (re == NULL) { + re = new RE2(regexp); + CHECK_EQ(re->error(), ""); + cache[regexp] = re; + } + return re; +} + void SearchCachedDFA(benchmark::State& state, const char* regexp, const StringPiece& text, Prog::Anchor anchor, bool expect_match) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(1LL<<31); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); for (auto _ : state) { bool failed = false; CHECK_EQ(prog->SearchDFA(text, StringPiece(), anchor, Prog::kFirstMatch, @@ -987,63 +1009,45 @@ void SearchCachedDFA(benchmark::State& state, const char* regexp, expect_match); CHECK(!failed); } - delete prog; - re->Decref(); } void SearchCachedNFA(benchmark::State& state, const char* regexp, const StringPiece& text, Prog::Anchor anchor, bool expect_match) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); for (auto _ : state) { CHECK_EQ(prog->SearchNFA(text, StringPiece(), anchor, Prog::kFirstMatch, NULL, 0), expect_match); } - delete prog; - re->Decref(); } void SearchCachedOnePass(benchmark::State& state, const char* regexp, const StringPiece& text, Prog::Anchor anchor, bool expect_match) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); CHECK(prog->IsOnePass()); for (auto _ : state) { CHECK_EQ(prog->SearchOnePass(text, text, anchor, Prog::kFirstMatch, NULL, 0), expect_match); } - delete prog; - re->Decref(); } void SearchCachedBitState(benchmark::State& state, const char* regexp, const StringPiece& text, Prog::Anchor anchor, bool expect_match) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); CHECK(prog->CanBitState()); for (auto _ : state) { CHECK_EQ(prog->SearchBitState(text, text, anchor, Prog::kFirstMatch, NULL, 0), expect_match); } - delete prog; - re->Decref(); } void SearchCachedPCRE(benchmark::State& state, const char* regexp, const StringPiece& text, Prog::Anchor anchor, bool expect_match) { - PCRE re(regexp, PCRE::UTF8); - CHECK_EQ(re.error(), ""); + PCRE& re = *GetCachedPCRE(regexp); for (auto _ : state) { if (anchor == Prog::kAnchored) CHECK_EQ(PCRE::FullMatch(text, re), expect_match); @@ -1055,8 +1059,7 @@ void SearchCachedPCRE(benchmark::State& state, const char* regexp, void SearchCachedRE2(benchmark::State& state, const char* regexp, const StringPiece& text, Prog::Anchor anchor, bool expect_match) { - RE2 re(regexp); - CHECK_EQ(re.error(), ""); + RE2& re = *GetCachedRE2(regexp); for (auto _ : state) { if (anchor == Prog::kAnchored) CHECK_EQ(RE2::FullMatch(text, re), expect_match); @@ -1149,67 +1152,46 @@ void Parse3RE2(benchmark::State& state, const char* regexp, void Parse3CachedNFA(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); StringPiece sp[4]; // 4 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->SearchNFA(text, StringPiece(), Prog::kAnchored, Prog::kFullMatch, sp, 4)); } - delete prog; - re->Decref(); } void Parse3CachedOnePass(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); CHECK(prog->IsOnePass()); StringPiece sp[4]; // 4 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->SearchOnePass(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 4)); } - delete prog; - re->Decref(); } void Parse3CachedBitState(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); CHECK(prog->CanBitState()); StringPiece sp[4]; // 4 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->SearchBitState(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 4)); } - delete prog; - re->Decref(); } void Parse3CachedBacktrack(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); StringPiece sp[4]; // 4 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->UnsafeSearchBacktrack(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 4)); } - delete prog; - re->Decref(); } void Parse3CachedPCRE(benchmark::State& state, const char* regexp, const StringPiece& text) { - PCRE re(regexp, PCRE::UTF8); - CHECK_EQ(re.error(), ""); + PCRE& re = *GetCachedPCRE(regexp); StringPiece sp1, sp2, sp3; for (auto _ : state) { CHECK(PCRE::FullMatch(text, re, &sp1, &sp2, &sp3)); @@ -1218,8 +1200,7 @@ void Parse3CachedPCRE(benchmark::State& state, const char* regexp, void Parse3CachedRE2(benchmark::State& state, const char* regexp, const StringPiece& text) { - RE2 re(regexp); - CHECK_EQ(re.error(), ""); + RE2& re = *GetCachedRE2(regexp); StringPiece sp1, sp2, sp3; for (auto _ : state) { CHECK(RE2::FullMatch(text, re, &sp1, &sp2, &sp3)); @@ -1296,67 +1277,46 @@ void Parse1RE2(benchmark::State& state, const char* regexp, void Parse1CachedNFA(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); StringPiece sp[2]; // 2 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->SearchNFA(text, StringPiece(), Prog::kAnchored, Prog::kFullMatch, sp, 2)); } - delete prog; - re->Decref(); } void Parse1CachedOnePass(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); CHECK(prog->IsOnePass()); StringPiece sp[2]; // 2 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->SearchOnePass(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 2)); } - delete prog; - re->Decref(); } void Parse1CachedBitState(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); CHECK(prog->CanBitState()); StringPiece sp[2]; // 2 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->SearchBitState(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 2)); } - delete prog; - re->Decref(); } void Parse1CachedBacktrack(benchmark::State& state, const char* regexp, const StringPiece& text) { - Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL); - CHECK(re); - Prog* prog = re->CompileToProg(0); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); StringPiece sp[2]; // 2 because sp[0] is whole match. for (auto _ : state) { CHECK(prog->UnsafeSearchBacktrack(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 2)); } - delete prog; - re->Decref(); } void Parse1CachedPCRE(benchmark::State& state, const char* regexp, const StringPiece& text) { - PCRE re(regexp, PCRE::UTF8); - CHECK_EQ(re.error(), ""); + PCRE& re = *GetCachedPCRE(regexp); StringPiece sp1; for (auto _ : state) { CHECK(PCRE::FullMatch(text, re, &sp1)); @@ -1365,8 +1325,7 @@ void Parse1CachedPCRE(benchmark::State& state, const char* regexp, void Parse1CachedRE2(benchmark::State& state, const char* regexp, const StringPiece& text) { - RE2 re(regexp); - CHECK_EQ(re.error(), ""); + RE2& re = *GetCachedRE2(regexp); StringPiece sp1; for (auto _ : state) { CHECK(RE2::FullMatch(text, re, &sp1)); @@ -1375,8 +1334,7 @@ void Parse1CachedRE2(benchmark::State& state, const char* regexp, void SearchParse2CachedPCRE(benchmark::State& state, const char* regexp, const StringPiece& text) { - PCRE re(regexp, PCRE::UTF8); - CHECK_EQ(re.error(), ""); + PCRE& re = *GetCachedPCRE(regexp); for (auto _ : state) { StringPiece sp1, sp2; CHECK(PCRE::PartialMatch(text, re, &sp1, &sp2)); @@ -1385,8 +1343,7 @@ void SearchParse2CachedPCRE(benchmark::State& state, const char* regexp, void SearchParse2CachedRE2(benchmark::State& state, const char* regexp, const StringPiece& text) { - RE2 re(regexp); - CHECK_EQ(re.error(), ""); + RE2& re = *GetCachedRE2(regexp); for (auto _ : state) { StringPiece sp1, sp2; CHECK(RE2::PartialMatch(text, re, &sp1, &sp2)); @@ -1395,8 +1352,7 @@ void SearchParse2CachedRE2(benchmark::State& state, const char* regexp, void SearchParse1CachedPCRE(benchmark::State& state, const char* regexp, const StringPiece& text) { - PCRE re(regexp, PCRE::UTF8); - CHECK_EQ(re.error(), ""); + PCRE& re = *GetCachedPCRE(regexp); for (auto _ : state) { StringPiece sp1; CHECK(PCRE::PartialMatch(text, re, &sp1)); @@ -1405,8 +1361,7 @@ void SearchParse1CachedPCRE(benchmark::State& state, const char* regexp, void SearchParse1CachedRE2(benchmark::State& state, const char* regexp, const StringPiece& text) { - RE2 re(regexp); - CHECK_EQ(re.error(), ""); + RE2& re = *GetCachedRE2(regexp); for (auto _ : state) { StringPiece sp1; CHECK(RE2::PartialMatch(text, re, &sp1)); @@ -1541,8 +1496,7 @@ BENCHMARK(ASCIIMatchPCRE)->ThreadRange(1, NumCPUs()); BENCHMARK(ASCIIMatchRE2)->ThreadRange(1, NumCPUs()); void FullMatchPCRE(benchmark::State& state, const char *regexp) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); s += "ABCDEFGHIJ"; PCRE re(regexp); for (auto _ : state) { @@ -1552,8 +1506,7 @@ void FullMatchPCRE(benchmark::State& state, const char *regexp) { } void FullMatchRE2(benchmark::State& state, const char *regexp) { - std::string s; - MakeText(&s, state.range(0)); + std::string s = RandomText(state.range(0)); s += "ABCDEFGHIJ"; RE2 re(regexp, RE2::Latin1); for (auto _ : state) { diff --git a/re2/testing/required_prefix_test.cc b/re2/testing/required_prefix_test.cc index 5460045..60a11f8 100644 --- a/re2/testing/required_prefix_test.cc +++ b/re2/testing/required_prefix_test.cc @@ -6,6 +6,7 @@ #include "util/test.h" #include "util/logging.h" +#include "re2/prog.h" #include "re2/regexp.h" namespace re2 { @@ -19,15 +20,18 @@ struct PrefixTest { }; static PrefixTest tests[] = { - // If the regexp is missing a ^, there's no required prefix. - { "abc", false }, + // Empty cases. { "", false }, { "(?m)^", false }, + { "(?-m)^", false }, + + // If the regexp has no ^, there's no required prefix. + { "abc", false }, // If the regexp immediately goes into // something not a literal match, there's no required prefix. - { "^(abc)", false }, { "^a*", false }, + { "^(abc)", false }, // Otherwise, it should work. { "^abc$", true, "abc", false, "(?-m:$)" }, @@ -53,15 +57,15 @@ TEST(RequiredPrefix, SimpleTests) { bool f; Regexp* s; ASSERT_EQ(t.return_value, re->RequiredPrefix(&p, &f, &s)) - << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf") + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8") << " " << re->Dump(); if (t.return_value) { ASSERT_EQ(p, std::string(t.prefix)) - << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf"); + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8"); ASSERT_EQ(f, t.foldcase) - << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf"); + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8"); ASSERT_EQ(s->ToString(), std::string(t.suffix)) - << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf"); + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8"); s->Decref(); } re->Decref(); @@ -69,4 +73,127 @@ TEST(RequiredPrefix, SimpleTests) { } } +static PrefixTest for_accel_tests[] = { + // Empty cases. + { "", false }, + { "(?m)^", false }, + { "(?-m)^", false }, + + // If the regexp has a ^, there's no required prefix. + { "^abc", false }, + + // If the regexp immediately goes into + // something not a literal match, there's no required prefix. + { "a*", false }, + + // Unlike RequiredPrefix(), RequiredPrefixForAccel() can "see through" + // capturing groups, but doesn't try to glue prefix fragments together. + { "(a?)def", false }, + { "(ab?)def", true, "a", false }, + { "(abc?)def", true, "ab", false }, + { "(()a)def", false }, + { "((a)b)def", true, "a", false }, + { "((ab)c)def", true, "ab", false }, + + // Otherwise, it should work. + { "abc$", true, "abc", false }, + { "abc", true, "abc", false }, + { "(?i)abc", true, "abc", true }, + { "abcd*", true, "abc", false }, + { "[Aa][Bb]cd*", true, "ab", true }, + { "ab[Cc]d*", true, "ab", false }, + { "☺abc", true, "☺abc", false }, +}; + +TEST(RequiredPrefixForAccel, SimpleTests) { + for (size_t i = 0; i < arraysize(for_accel_tests); i++) { + const PrefixTest& t = for_accel_tests[i]; + for (size_t j = 0; j < 2; j++) { + Regexp::ParseFlags flags = Regexp::LikePerl; + if (j == 0) + flags = flags | Regexp::Latin1; + Regexp* re = Regexp::Parse(t.regexp, flags, NULL); + ASSERT_TRUE(re != NULL) << " " << t.regexp; + + std::string p; + bool f; + ASSERT_EQ(t.return_value, re->RequiredPrefixForAccel(&p, &f)) + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8") + << " " << re->Dump(); + if (t.return_value) { + ASSERT_EQ(p, std::string(t.prefix)) + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8"); + ASSERT_EQ(f, t.foldcase) + << " " << t.regexp << " " << (j == 0 ? "latin1" : "utf8"); + } + re->Decref(); + } + } +} + +TEST(RequiredPrefixForAccel, CaseFoldingForKAndS) { + Regexp* re; + std::string p; + bool f; + + // With Latin-1 encoding, `(?i)` prefixes can include 'k' and 's'. + re = Regexp::Parse("(?i)KLM", Regexp::LikePerl|Regexp::Latin1, NULL); + ASSERT_TRUE(re != NULL); + ASSERT_TRUE(re->RequiredPrefixForAccel(&p, &f)); + ASSERT_EQ(p, "klm"); + ASSERT_EQ(f, true); + re->Decref(); + + re = Regexp::Parse("(?i)STU", Regexp::LikePerl|Regexp::Latin1, NULL); + ASSERT_TRUE(re != NULL); + ASSERT_TRUE(re->RequiredPrefixForAccel(&p, &f)); + ASSERT_EQ(p, "stu"); + ASSERT_EQ(f, true); + re->Decref(); + + // With UTF-8 encoding, `(?i)` prefixes can't include 'k' and 's'. + // This is because they match U+212A and U+017F, respectively, and + // so the parser ends up emitting character classes, not literals. + re = Regexp::Parse("(?i)KLM", Regexp::LikePerl, NULL); + ASSERT_TRUE(re != NULL); + ASSERT_FALSE(re->RequiredPrefixForAccel(&p, &f)); + re->Decref(); + + re = Regexp::Parse("(?i)STU", Regexp::LikePerl, NULL); + ASSERT_TRUE(re != NULL); + ASSERT_FALSE(re->RequiredPrefixForAccel(&p, &f)); + re->Decref(); +} + +static const char* prefix_accel_tests[] = { + "aababc\\d+", + "(?i)AABABC\\d+", +}; + +TEST(PrefixAccel, SimpleTests) { + for (size_t i = 0; i < arraysize(prefix_accel_tests); i++) { + const char* pattern = prefix_accel_tests[i]; + Regexp* re = Regexp::Parse(pattern, Regexp::LikePerl, NULL); + ASSERT_TRUE(re != NULL); + Prog* prog = re->CompileToProg(0); + ASSERT_TRUE(prog != NULL); + ASSERT_TRUE(prog->can_prefix_accel()); + for (int j = 0; j < 100; j++) { + std::string text(j, 'a'); + const char* p = reinterpret_cast( + prog->PrefixAccel(text.data(), text.size())); + EXPECT_TRUE(p == NULL); + text.append("aababc"); + for (int k = 0; k < 100; k++) { + text.append(k, 'a'); + p = reinterpret_cast( + prog->PrefixAccel(text.data(), text.size())); + EXPECT_EQ(j, p - text.data()); + } + } + delete prog; + re->Decref(); + } +} + } // namespace re2 diff --git a/re2/testing/search_test.cc b/re2/testing/search_test.cc index c20f501..5d86dbf 100644 --- a/re2/testing/search_test.cc +++ b/re2/testing/search_test.cc @@ -308,6 +308,8 @@ RegexpTest simple_tests[] = { // Former bugs. { "a\\C*|ba\\C", "baba" }, { "\\w*I\\w*", "Inc." }, + { "(?:|a)*", "aaa" }, + { "(?:|a)+", "aaa" }, }; TEST(Regexp, SearchTests) { diff --git a/re2/testing/set_test.cc b/re2/testing/set_test.cc index 61d1cf2..5a760c4 100644 --- a/re2/testing/set_test.cc +++ b/re2/testing/set_test.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include "util/test.h" #include "util/logging.h" @@ -201,4 +202,29 @@ TEST(Set, Prefix) { ASSERT_EQ(v[0], 0); } +TEST(Set, MoveSemantics) { + RE2::Set s1(RE2::DefaultOptions, RE2::UNANCHORED); + ASSERT_EQ(s1.Add("foo\\d+", NULL), 0); + ASSERT_EQ(s1.Compile(), true); + ASSERT_EQ(s1.Match("abc foo1 xyz", NULL), true); + ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), false); + + // The moved-to object should do what the moved-from object did. + RE2::Set s2 = std::move(s1); + ASSERT_EQ(s2.Match("abc foo1 xyz", NULL), true); + ASSERT_EQ(s2.Match("abc bar2 xyz", NULL), false); + + // The moved-from object should have been reset and be reusable. + ASSERT_EQ(s1.Add("bar\\d+", NULL), 0); + ASSERT_EQ(s1.Compile(), true); + ASSERT_EQ(s1.Match("abc foo1 xyz", NULL), false); + ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), true); + + // Verify that "overwriting" works and also doesn't leak memory. + // (The latter will need a leak detector such as LeakSanitizer.) + s1 = std::move(s2); + ASSERT_EQ(s1.Match("abc foo1 xyz", NULL), true); + ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), false); +} + } // namespace re2 diff --git a/re2/testing/string_generator.cc b/re2/testing/string_generator.cc index 030cc45..44837fe 100644 --- a/re2/testing/string_generator.cc +++ b/re2/testing/string_generator.cc @@ -111,4 +111,31 @@ void StringGenerator::GenerateNULL() { hasnext_ = true; } +std::string DeBruijnString(int n) { + CHECK_GE(n, 1); + CHECK_LE(n, 29); + const size_t size = size_t{1} << static_cast(n); + const size_t mask = size - 1; + std::vector did(size, false); + std::string s; + s.reserve(static_cast(n) + size); + for (size_t i = 0; i < static_cast(n - 1); i++) + s += '0'; + size_t bits = 0; + for (size_t i = 0; i < size; i++) { + bits <<= 1; + bits &= mask; + if (!did[bits | 1]) { + bits |= 1; + s += '1'; + } else { + s += '0'; + } + CHECK(!did[bits]); + did[bits] = true; + } + CHECK_EQ(s.size(), static_cast(n - 1) + size); + return s; +} + } // namespace re2 diff --git a/re2/testing/string_generator.h b/re2/testing/string_generator.h index 6184176..73fbb51 100644 --- a/re2/testing/string_generator.h +++ b/re2/testing/string_generator.h @@ -58,6 +58,19 @@ class StringGenerator { StringGenerator& operator=(const StringGenerator&) = delete; }; +// Generates and returns a string over binary alphabet {0,1} that contains +// all possible binary sequences of length n as subsequences. The obvious +// brute force method would generate a string of length n * 2^n, but this +// generates a string of length n-1 + 2^n called a De Bruijn cycle. +// See Knuth, The Art of Computer Programming, Vol 2, Exercise 3.2.2 #17. +// +// Such a string is useful for testing a DFA. If you have a DFA +// where distinct last n bytes implies distinct states, then running on a +// DeBruijn string causes the DFA to need to create a new state at every +// position in the input, never reusing any states until it gets to the +// end of the string. This is the worst possible case for DFA execution. +std::string DeBruijnString(int n); + } // namespace re2 #endif // RE2_TESTING_STRING_GENERATOR_H_ diff --git a/re2/testing/tester.cc b/re2/testing/tester.cc index 67d262c..b0c22f2 100644 --- a/re2/testing/tester.cc +++ b/re2/testing/tester.cc @@ -86,6 +86,20 @@ static uint32_t Engines() { // The result of running a match. struct TestInstance::Result { + Result() + : skipped(false), + matched(false), + untrusted(false), + have_submatch(false), + have_submatch0(false) { + ClearSubmatch(); + } + + void ClearSubmatch() { + for (int i = 0; i < kMaxSubmatch; i++) + submatch[i] = StringPiece(); + } + bool skipped; // test skipped: wasn't applicable bool matched; // found a match bool untrusted; // don't really trust the answer @@ -103,8 +117,8 @@ static std::string FormatCapture(const StringPiece& text, if (s.data() == NULL) return "(?,?)"; return StringPrintf("(%td,%td)", - s.begin() - text.begin(), - s.end() - text.begin()); + BeginPtr(s) - BeginPtr(text), + EndPtr(s) - BeginPtr(text)); } // Returns whether text contains non-ASCII (>= 0x80) bytes. @@ -292,9 +306,6 @@ void TestInstance::RunSearch(Engine type, const StringPiece& orig_context, Prog::Anchor anchor, Result* result) { - // Result is not trivial, so we cannot freely clear it with memset(3), - // but zeroing objects like so is safe and expedient for our purposes. - memset(reinterpret_cast(result), 0, sizeof *result); if (regexp_ == NULL) { result->skipped = true; return; @@ -392,7 +403,7 @@ void TestInstance::RunSearch(Engine type, case kEngineRE2: case kEngineRE2a: case kEngineRE2b: { - if (!re2_ || text.end() != context.end()) { + if (!re2_ || EndPtr(text) != EndPtr(context)) { result->skipped = true; break; } @@ -407,8 +418,8 @@ void TestInstance::RunSearch(Engine type, result->matched = re2_->Match( context, - static_cast(text.begin() - context.begin()), - static_cast(text.end() - context.begin()), + static_cast(BeginPtr(text) - BeginPtr(context)), + static_cast(EndPtr(text) - BeginPtr(context)), re_anchor, result->submatch, nsubmatch); @@ -417,8 +428,8 @@ void TestInstance::RunSearch(Engine type, } case kEnginePCRE: { - if (!re_ || text.begin() != context.begin() || - text.end() != context.end()) { + if (!re_ || BeginPtr(text) != BeginPtr(context) || + EndPtr(text) != EndPtr(context)) { result->skipped = true; break; } @@ -478,7 +489,7 @@ void TestInstance::RunSearch(Engine type, } if (!result->matched) - memset(result->submatch, 0, sizeof result->submatch); + result->ClearSubmatch(); } // Checks whether r is okay given that correct is the right answer. @@ -595,9 +606,9 @@ void TestInstance::LogMatch(const char* prefix, Engine e, << " text " << CEscape(text) << " (" - << text.begin() - context.begin() + << BeginPtr(text) - BeginPtr(context) << "," - << text.end() - context.begin() + << EndPtr(text) - BeginPtr(context) << ") of context " << CEscape(context) << " (" << FormatKind(kind_) diff --git a/re2/tostring.cc b/re2/tostring.cc index 4545a92..9c1c038 100644 --- a/re2/tostring.cc +++ b/re2/tostring.cc @@ -291,7 +291,7 @@ int ToStringWalker::PostVisit(Regexp* re, int parent_arg, int pre_arg, // There's no syntax accepted by the parser to generate // this node (it is generated by RE2::Set) so make something // up that is readable but won't compile. - t_->append("(?HaveMatch:%d)", re->match_id()); + t_->append(StringPrintf("(?HaveMatch:%d)", re->match_id())); break; } diff --git a/re2/unicode.py b/re2/unicode.py index 56ca811..727bea5 100644 --- a/re2/unicode.py +++ b/re2/unicode.py @@ -13,7 +13,7 @@ import re from six.moves import urllib # Directory or URL where Unicode tables reside. -_UNICODE_DIR = "https://www.unicode.org/Public/12.1.0/ucd" +_UNICODE_DIR = "https://www.unicode.org/Public/14.0.0/ucd" # Largest valid Unicode code value. _RUNE_MAX = 0x10FFFF diff --git a/re2/unicode_casefold.cc b/re2/unicode_casefold.cc index 4ea2533..d9de282 100644 --- a/re2/unicode_casefold.cc +++ b/re2/unicode_casefold.cc @@ -7,7 +7,7 @@ namespace re2 { -// 1381 groups, 2792 pairs, 356 ranges +// 1424 groups, 2878 pairs, 367 ranges const CaseFold unicode_casefold[] = { { 65, 90, 32 }, { 97, 106, -32 }, @@ -299,8 +299,8 @@ const CaseFold unicode_casefold[] = { { 8579, 8580, OddEven }, { 9398, 9423, 26 }, { 9424, 9449, -26 }, - { 11264, 11310, 48 }, - { 11312, 11358, -48 }, + { 11264, 11311, 48 }, + { 11312, 11359, -48 }, { 11360, 11361, EvenOdd }, { 11362, 11362, -10743 }, { 11363, 11363, -3814 }, @@ -344,11 +344,14 @@ const CaseFold unicode_casefold[] = { { 42929, 42929, -42282 }, { 42930, 42930, -42261 }, { 42931, 42931, 928 }, - { 42932, 42943, EvenOdd }, - { 42946, 42947, EvenOdd }, + { 42932, 42947, EvenOdd }, { 42948, 42948, -48 }, { 42949, 42949, -42307 }, { 42950, 42950, -35384 }, + { 42951, 42954, OddEven }, + { 42960, 42961, EvenOdd }, + { 42966, 42969, EvenOdd }, + { 42997, 42998, OddEven }, { 43859, 43859, -928 }, { 43888, 43967, -38864 }, { 65313, 65338, 32 }, @@ -357,6 +360,14 @@ const CaseFold unicode_casefold[] = { { 66600, 66639, -40 }, { 66736, 66771, 40 }, { 66776, 66811, -40 }, + { 66928, 66938, 39 }, + { 66940, 66954, 39 }, + { 66956, 66962, 39 }, + { 66964, 66965, 39 }, + { 66967, 66977, -39 }, + { 66979, 66993, -39 }, + { 66995, 67001, -39 }, + { 67003, 67004, -39 }, { 68736, 68786, 64 }, { 68800, 68850, -64 }, { 71840, 71871, 32 }, @@ -366,9 +377,9 @@ const CaseFold unicode_casefold[] = { { 125184, 125217, 34 }, { 125218, 125251, -34 }, }; -const int num_unicode_casefold = 356; +const int num_unicode_casefold = 367; -// 1381 groups, 1411 pairs, 198 ranges +// 1424 groups, 1454 pairs, 205 ranges const CaseFold unicode_tolower[] = { { 65, 90, 32 }, { 181, 181, 775 }, @@ -519,7 +530,7 @@ const CaseFold unicode_tolower[] = { { 8544, 8559, 16 }, { 8579, 8579, OddEven }, { 9398, 9423, 26 }, - { 11264, 11310, 48 }, + { 11264, 11311, 48 }, { 11360, 11360, EvenOdd }, { 11362, 11362, -10743 }, { 11363, 11363, -3814 }, @@ -555,21 +566,28 @@ const CaseFold unicode_tolower[] = { { 42929, 42929, -42282 }, { 42930, 42930, -42261 }, { 42931, 42931, 928 }, - { 42932, 42942, EvenOddSkip }, - { 42946, 42946, EvenOdd }, + { 42932, 42946, EvenOddSkip }, { 42948, 42948, -48 }, { 42949, 42949, -42307 }, { 42950, 42950, -35384 }, + { 42951, 42953, OddEvenSkip }, + { 42960, 42960, EvenOdd }, + { 42966, 42968, EvenOddSkip }, + { 42997, 42997, OddEven }, { 43888, 43967, -38864 }, { 65313, 65338, 32 }, { 66560, 66599, 40 }, { 66736, 66771, 40 }, + { 66928, 66938, 39 }, + { 66940, 66954, 39 }, + { 66956, 66962, 39 }, + { 66964, 66965, 39 }, { 68736, 68786, 64 }, { 71840, 71871, 32 }, { 93760, 93791, 32 }, { 125184, 125217, 34 }, }; -const int num_unicode_tolower = 198; +const int num_unicode_tolower = 205; diff --git a/re2/unicode_groups.cc b/re2/unicode_groups.cc index 63e6116..2a8d7da 100644 --- a/re2/unicode_groups.cc +++ b/re2/unicode_groups.cc @@ -15,6 +15,7 @@ static const URange16 C_range16[] = { { 1564, 1564 }, { 1757, 1757 }, { 1807, 1807 }, + { 2192, 2193 }, { 2274, 2274 }, { 6158, 6158 }, { 8203, 8207 }, @@ -46,6 +47,7 @@ static const URange16 Cf_range16[] = { { 1564, 1564 }, { 1757, 1757 }, { 1807, 1807 }, + { 2192, 2193 }, { 2274, 2274 }, { 6158, 6158 }, { 8203, 8207 }, @@ -124,8 +126,9 @@ static const URange16 L_range16[] = { { 2088, 2088 }, { 2112, 2136 }, { 2144, 2154 }, - { 2208, 2228 }, - { 2230, 2237 }, + { 2160, 2183 }, + { 2185, 2190 }, + { 2208, 2249 }, { 2308, 2361 }, { 2365, 2365 }, { 2384, 2384 }, @@ -190,6 +193,7 @@ static const URange16 L_range16[] = { { 3114, 3129 }, { 3133, 3133 }, { 3160, 3162 }, + { 3165, 3165 }, { 3168, 3169 }, { 3200, 3200 }, { 3205, 3212 }, @@ -198,10 +202,10 @@ static const URange16 L_range16[] = { { 3242, 3251 }, { 3253, 3257 }, { 3261, 3261 }, - { 3294, 3294 }, + { 3293, 3294 }, { 3296, 3297 }, { 3313, 3314 }, - { 3333, 3340 }, + { 3332, 3340 }, { 3342, 3344 }, { 3346, 3386 }, { 3389, 3389 }, @@ -269,9 +273,8 @@ static const URange16 L_range16[] = { { 5761, 5786 }, { 5792, 5866 }, { 5873, 5880 }, - { 5888, 5900 }, - { 5902, 5905 }, - { 5920, 5937 }, + { 5888, 5905 }, + { 5919, 5937 }, { 5952, 5969 }, { 5984, 5996 }, { 5998, 6000 }, @@ -292,7 +295,7 @@ static const URange16 L_range16[] = { { 6688, 6740 }, { 6823, 6823 }, { 6917, 6963 }, - { 6981, 6987 }, + { 6981, 6988 }, { 7043, 7072 }, { 7086, 7087 }, { 7098, 7141 }, @@ -343,9 +346,7 @@ static const URange16 L_range16[] = { { 8517, 8521 }, { 8526, 8526 }, { 8579, 8580 }, - { 11264, 11310 }, - { 11312, 11358 }, - { 11360, 11492 }, + { 11264, 11492 }, { 11499, 11502 }, { 11506, 11507 }, { 11520, 11557 }, @@ -372,11 +373,10 @@ static const URange16 L_range16[] = { { 12540, 12543 }, { 12549, 12591 }, { 12593, 12686 }, - { 12704, 12730 }, + { 12704, 12735 }, { 12784, 12799 }, - { 13312, 19893 }, - { 19968, 40943 }, - { 40960, 42124 }, + { 13312, 19903 }, + { 19968, 42124 }, { 42192, 42237 }, { 42240, 42508 }, { 42512, 42527 }, @@ -386,9 +386,11 @@ static const URange16 L_range16[] = { { 42656, 42725 }, { 42775, 42783 }, { 42786, 42888 }, - { 42891, 42943 }, - { 42946, 42950 }, - { 42999, 43009 }, + { 42891, 42954 }, + { 42960, 42961 }, + { 42963, 42963 }, + { 42965, 42969 }, + { 42994, 43009 }, { 43011, 43013 }, { 43015, 43018 }, { 43020, 43042 }, @@ -425,7 +427,7 @@ static const URange16 L_range16[] = { { 43808, 43814 }, { 43816, 43822 }, { 43824, 43866 }, - { 43868, 43879 }, + { 43868, 43881 }, { 43888, 44002 }, { 44032, 55203 }, { 55216, 55238 }, @@ -478,9 +480,20 @@ static const URange32 L_range32[] = { { 66776, 66811 }, { 66816, 66855 }, { 66864, 66915 }, + { 66928, 66938 }, + { 66940, 66954 }, + { 66956, 66962 }, + { 66964, 66965 }, + { 66967, 66977 }, + { 66979, 66993 }, + { 66995, 67001 }, + { 67003, 67004 }, { 67072, 67382 }, { 67392, 67413 }, { 67424, 67431 }, + { 67456, 67461 }, + { 67463, 67504 }, + { 67506, 67514 }, { 67584, 67589 }, { 67592, 67592 }, { 67594, 67637 }, @@ -511,15 +524,22 @@ static const URange32 L_range32[] = { { 68736, 68786 }, { 68800, 68850 }, { 68864, 68899 }, + { 69248, 69289 }, + { 69296, 69297 }, { 69376, 69404 }, { 69415, 69415 }, { 69424, 69445 }, + { 69488, 69505 }, + { 69552, 69572 }, { 69600, 69622 }, { 69635, 69687 }, + { 69745, 69746 }, + { 69749, 69749 }, { 69763, 69807 }, { 69840, 69864 }, { 69891, 69926 }, { 69956, 69956 }, + { 69959, 69959 }, { 69968, 70002 }, { 70006, 70006 }, { 70019, 70066 }, @@ -545,7 +565,7 @@ static const URange32 L_range32[] = { { 70493, 70497 }, { 70656, 70708 }, { 70727, 70730 }, - { 70751, 70751 }, + { 70751, 70753 }, { 70784, 70831 }, { 70852, 70853 }, { 70855, 70855 }, @@ -556,9 +576,16 @@ static const URange32 L_range32[] = { { 71296, 71338 }, { 71352, 71352 }, { 71424, 71450 }, + { 71488, 71494 }, { 71680, 71723 }, { 71840, 71903 }, - { 71935, 71935 }, + { 71935, 71942 }, + { 71945, 71945 }, + { 71948, 71955 }, + { 71957, 71958 }, + { 71960, 71983 }, + { 71999, 71999 }, + { 72001, 72001 }, { 72096, 72103 }, { 72106, 72144 }, { 72161, 72161 }, @@ -569,7 +596,7 @@ static const URange32 L_range32[] = { { 72272, 72272 }, { 72284, 72329 }, { 72349, 72349 }, - { 72384, 72440 }, + { 72368, 72440 }, { 72704, 72712 }, { 72714, 72750 }, { 72768, 72768 }, @@ -583,12 +610,15 @@ static const URange32 L_range32[] = { { 73066, 73097 }, { 73112, 73112 }, { 73440, 73458 }, + { 73648, 73648 }, { 73728, 74649 }, { 74880, 75075 }, + { 77712, 77808 }, { 77824, 78894 }, { 82944, 83526 }, { 92160, 92728 }, { 92736, 92766 }, + { 92784, 92862 }, { 92880, 92909 }, { 92928, 92975 }, { 92992, 92995 }, @@ -601,8 +631,12 @@ static const URange32 L_range32[] = { { 94176, 94177 }, { 94179, 94179 }, { 94208, 100343 }, - { 100352, 101106 }, - { 110592, 110878 }, + { 100352, 101589 }, + { 101632, 101640 }, + { 110576, 110579 }, + { 110581, 110587 }, + { 110589, 110590 }, + { 110592, 110882 }, { 110928, 110930 }, { 110948, 110951 }, { 110960, 111355 }, @@ -640,10 +674,16 @@ static const URange32 L_range32[] = { { 120714, 120744 }, { 120746, 120770 }, { 120772, 120779 }, + { 122624, 122654 }, { 123136, 123180 }, { 123191, 123197 }, { 123214, 123214 }, + { 123536, 123565 }, { 123584, 123627 }, + { 124896, 124902 }, + { 124904, 124907 }, + { 124909, 124910 }, + { 124912, 124926 }, { 124928, 125124 }, { 125184, 125251 }, { 125259, 125259 }, @@ -680,12 +720,13 @@ static const URange32 L_range32[] = { { 126625, 126627 }, { 126629, 126633 }, { 126635, 126651 }, - { 131072, 173782 }, - { 173824, 177972 }, + { 131072, 173791 }, + { 173824, 177976 }, { 177984, 178205 }, { 178208, 183969 }, { 183984, 191456 }, { 194560, 195101 }, + { 196608, 201546 }, }; static const URange16 Ll_range16[] = { { 97, 122 }, @@ -1119,7 +1160,7 @@ static const URange16 Ll_range16[] = { { 8518, 8521 }, { 8526, 8526 }, { 8580, 8580 }, - { 11312, 11358 }, + { 11312, 11359 }, { 11361, 11361 }, { 11365, 11366 }, { 11368, 11368 }, @@ -1288,10 +1329,19 @@ static const URange16 Ll_range16[] = { { 42939, 42939 }, { 42941, 42941 }, { 42943, 42943 }, + { 42945, 42945 }, { 42947, 42947 }, + { 42952, 42952 }, + { 42954, 42954 }, + { 42961, 42961 }, + { 42963, 42963 }, + { 42965, 42965 }, + { 42967, 42967 }, + { 42969, 42969 }, + { 42998, 42998 }, { 43002, 43002 }, { 43824, 43866 }, - { 43872, 43879 }, + { 43872, 43880 }, { 43888, 43967 }, { 64256, 64262 }, { 64275, 64279 }, @@ -1300,6 +1350,10 @@ static const URange16 Ll_range16[] = { static const URange32 Ll_range32[] = { { 66600, 66639 }, { 66776, 66811 }, + { 66967, 66977 }, + { 66979, 66993 }, + { 66995, 67001 }, + { 67003, 67004 }, { 68800, 68850 }, { 71872, 71903 }, { 93792, 93823 }, @@ -1331,6 +1385,8 @@ static const URange32 Ll_range32[] = { { 120746, 120770 }, { 120772, 120777 }, { 120779, 120779 }, + { 122624, 122633 }, + { 122635, 122654 }, { 125218, 125251 }, }; static const URange16 Lm_range16[] = { @@ -1349,6 +1405,7 @@ static const URange16 Lm_range16[] = { { 2074, 2074 }, { 2084, 2084 }, { 2088, 2088 }, + { 2249, 2249 }, { 2417, 2417 }, { 3654, 3654 }, { 3782, 3782 }, @@ -1379,6 +1436,7 @@ static const URange16 Lm_range16[] = { { 42775, 42783 }, { 42864, 42864 }, { 42888, 42888 }, + { 42994, 42996 }, { 43000, 43001 }, { 43471, 43471 }, { 43494, 43494 }, @@ -1386,14 +1444,21 @@ static const URange16 Lm_range16[] = { { 43741, 43741 }, { 43763, 43764 }, { 43868, 43871 }, + { 43881, 43881 }, { 65392, 65392 }, { 65438, 65439 }, }; static const URange32 Lm_range32[] = { + { 67456, 67461 }, + { 67463, 67504 }, + { 67506, 67514 }, { 92992, 92995 }, { 94099, 94111 }, { 94176, 94177 }, { 94179, 94179 }, + { 110576, 110579 }, + { 110581, 110587 }, + { 110589, 110590 }, { 123191, 123197 }, { 125259, 125259 }, }; @@ -1421,8 +1486,9 @@ static const URange16 Lo_range16[] = { { 2048, 2069 }, { 2112, 2136 }, { 2144, 2154 }, - { 2208, 2228 }, - { 2230, 2237 }, + { 2160, 2183 }, + { 2185, 2190 }, + { 2208, 2248 }, { 2308, 2361 }, { 2365, 2365 }, { 2384, 2384 }, @@ -1487,6 +1553,7 @@ static const URange16 Lo_range16[] = { { 3114, 3129 }, { 3133, 3133 }, { 3160, 3162 }, + { 3165, 3165 }, { 3168, 3169 }, { 3200, 3200 }, { 3205, 3212 }, @@ -1495,10 +1562,10 @@ static const URange16 Lo_range16[] = { { 3242, 3251 }, { 3253, 3257 }, { 3261, 3261 }, - { 3294, 3294 }, + { 3293, 3294 }, { 3296, 3297 }, { 3313, 3314 }, - { 3333, 3340 }, + { 3332, 3340 }, { 3342, 3344 }, { 3346, 3386 }, { 3389, 3389 }, @@ -1559,9 +1626,8 @@ static const URange16 Lo_range16[] = { { 5761, 5786 }, { 5792, 5866 }, { 5873, 5880 }, - { 5888, 5900 }, - { 5902, 5905 }, - { 5920, 5937 }, + { 5888, 5905 }, + { 5919, 5937 }, { 5952, 5969 }, { 5984, 5996 }, { 5998, 6000 }, @@ -1581,7 +1647,7 @@ static const URange16 Lo_range16[] = { { 6656, 6678 }, { 6688, 6740 }, { 6917, 6963 }, - { 6981, 6987 }, + { 6981, 6988 }, { 7043, 7072 }, { 7086, 7087 }, { 7098, 7141 }, @@ -1611,11 +1677,10 @@ static const URange16 Lo_range16[] = { { 12543, 12543 }, { 12549, 12591 }, { 12593, 12686 }, - { 12704, 12730 }, + { 12704, 12735 }, { 12784, 12799 }, - { 13312, 19893 }, - { 19968, 40943 }, - { 40960, 40980 }, + { 13312, 19903 }, + { 19968, 40980 }, { 40982, 42124 }, { 42192, 42231 }, { 42240, 42507 }, @@ -1740,15 +1805,22 @@ static const URange32 Lo_range32[] = { { 68480, 68497 }, { 68608, 68680 }, { 68864, 68899 }, + { 69248, 69289 }, + { 69296, 69297 }, { 69376, 69404 }, { 69415, 69415 }, { 69424, 69445 }, + { 69488, 69505 }, + { 69552, 69572 }, { 69600, 69622 }, { 69635, 69687 }, + { 69745, 69746 }, + { 69749, 69749 }, { 69763, 69807 }, { 69840, 69864 }, { 69891, 69926 }, { 69956, 69956 }, + { 69959, 69959 }, { 69968, 70002 }, { 70006, 70006 }, { 70019, 70066 }, @@ -1774,7 +1846,7 @@ static const URange32 Lo_range32[] = { { 70493, 70497 }, { 70656, 70708 }, { 70727, 70730 }, - { 70751, 70751 }, + { 70751, 70753 }, { 70784, 70831 }, { 70852, 70853 }, { 70855, 70855 }, @@ -1785,8 +1857,15 @@ static const URange32 Lo_range32[] = { { 71296, 71338 }, { 71352, 71352 }, { 71424, 71450 }, + { 71488, 71494 }, { 71680, 71723 }, - { 71935, 71935 }, + { 71935, 71942 }, + { 71945, 71945 }, + { 71948, 71955 }, + { 71957, 71958 }, + { 71960, 71983 }, + { 71999, 71999 }, + { 72001, 72001 }, { 72096, 72103 }, { 72106, 72144 }, { 72161, 72161 }, @@ -1797,7 +1876,7 @@ static const URange32 Lo_range32[] = { { 72272, 72272 }, { 72284, 72329 }, { 72349, 72349 }, - { 72384, 72440 }, + { 72368, 72440 }, { 72704, 72712 }, { 72714, 72750 }, { 72768, 72768 }, @@ -1811,12 +1890,15 @@ static const URange32 Lo_range32[] = { { 73066, 73097 }, { 73112, 73112 }, { 73440, 73458 }, + { 73648, 73648 }, { 73728, 74649 }, { 74880, 75075 }, + { 77712, 77808 }, { 77824, 78894 }, { 82944, 83526 }, { 92160, 92728 }, { 92736, 92766 }, + { 92784, 92862 }, { 92880, 92909 }, { 92928, 92975 }, { 93027, 93047 }, @@ -1824,8 +1906,9 @@ static const URange32 Lo_range32[] = { { 93952, 94026 }, { 94032, 94032 }, { 94208, 100343 }, - { 100352, 101106 }, - { 110592, 110878 }, + { 100352, 101589 }, + { 101632, 101640 }, + { 110592, 110882 }, { 110928, 110930 }, { 110948, 110951 }, { 110960, 111355 }, @@ -1833,9 +1916,15 @@ static const URange32 Lo_range32[] = { { 113776, 113788 }, { 113792, 113800 }, { 113808, 113817 }, + { 122634, 122634 }, { 123136, 123180 }, { 123214, 123214 }, + { 123536, 123565 }, { 123584, 123627 }, + { 124896, 124902 }, + { 124904, 124907 }, + { 124909, 124910 }, + { 124912, 124926 }, { 124928, 125124 }, { 126464, 126467 }, { 126469, 126495 }, @@ -1870,12 +1959,13 @@ static const URange32 Lo_range32[] = { { 126625, 126627 }, { 126629, 126633 }, { 126635, 126651 }, - { 131072, 173782 }, - { 173824, 177972 }, + { 131072, 173791 }, + { 173824, 177976 }, { 177984, 178205 }, { 178208, 183969 }, { 183984, 191456 }, { 194560, 195101 }, + { 196608, 201546 }, }; static const URange16 Lt_range16[] = { { 453, 453 }, @@ -2321,7 +2411,7 @@ static const URange16 Lu_range16[] = { { 8510, 8511 }, { 8517, 8517 }, { 8579, 8579 }, - { 11264, 11310 }, + { 11264, 11311 }, { 11360, 11360 }, { 11362, 11364 }, { 11367, 11367 }, @@ -2486,13 +2576,23 @@ static const URange16 Lu_range16[] = { { 42938, 42938 }, { 42940, 42940 }, { 42942, 42942 }, + { 42944, 42944 }, { 42946, 42946 }, - { 42948, 42950 }, + { 42948, 42951 }, + { 42953, 42953 }, + { 42960, 42960 }, + { 42966, 42966 }, + { 42968, 42968 }, + { 42997, 42997 }, { 65313, 65338 }, }; static const URange32 Lu_range32[] = { { 66560, 66599 }, { 66736, 66771 }, + { 66928, 66938 }, + { 66940, 66954 }, + { 66956, 66962 }, + { 66964, 66965 }, { 68736, 68786 }, { 71840, 71871 }, { 93760, 93791 }, @@ -2554,7 +2654,8 @@ static const URange16 M_range16[] = { { 2085, 2087 }, { 2089, 2093 }, { 2137, 2139 }, - { 2259, 2273 }, + { 2200, 2207 }, + { 2250, 2273 }, { 2275, 2307 }, { 2362, 2364 }, { 2366, 2383 }, @@ -2588,7 +2689,7 @@ static const URange16 M_range16[] = { { 2878, 2884 }, { 2887, 2888 }, { 2891, 2893 }, - { 2902, 2903 }, + { 2901, 2903 }, { 2914, 2915 }, { 2946, 2946 }, { 3006, 3010 }, @@ -2596,6 +2697,7 @@ static const URange16 M_range16[] = { { 3018, 3021 }, { 3031, 3031 }, { 3072, 3076 }, + { 3132, 3132 }, { 3134, 3140 }, { 3142, 3144 }, { 3146, 3149 }, @@ -2615,7 +2717,7 @@ static const URange16 M_range16[] = { { 3402, 3405 }, { 3415, 3415 }, { 3426, 3427 }, - { 3458, 3459 }, + { 3457, 3459 }, { 3530, 3530 }, { 3535, 3540 }, { 3542, 3542 }, @@ -2647,13 +2749,14 @@ static const URange16 M_range16[] = { { 4239, 4239 }, { 4250, 4253 }, { 4957, 4959 }, - { 5906, 5908 }, + { 5906, 5909 }, { 5938, 5940 }, { 5970, 5971 }, { 6002, 6003 }, { 6068, 6099 }, { 6109, 6109 }, { 6155, 6157 }, + { 6159, 6159 }, { 6277, 6278 }, { 6313, 6313 }, { 6432, 6443 }, @@ -2662,7 +2765,7 @@ static const URange16 M_range16[] = { { 6741, 6750 }, { 6752, 6780 }, { 6783, 6783 }, - { 6832, 6846 }, + { 6832, 6862 }, { 6912, 6916 }, { 6964, 6980 }, { 7019, 7027 }, @@ -2675,8 +2778,7 @@ static const URange16 M_range16[] = { { 7405, 7405 }, { 7412, 7412 }, { 7415, 7417 }, - { 7616, 7673 }, - { 7675, 7679 }, + { 7616, 7679 }, { 8400, 8432 }, { 11503, 11505 }, { 11647, 11647 }, @@ -2691,6 +2793,7 @@ static const URange16 M_range16[] = { { 43014, 43014 }, { 43019, 43019 }, { 43043, 43047 }, + { 43052, 43052 }, { 43136, 43137 }, { 43188, 43205 }, { 43232, 43249 }, @@ -2728,11 +2831,16 @@ static const URange32 M_range32[] = { { 68159, 68159 }, { 68325, 68326 }, { 68900, 68903 }, + { 69291, 69292 }, { 69446, 69456 }, + { 69506, 69509 }, { 69632, 69634 }, { 69688, 69702 }, + { 69744, 69744 }, + { 69747, 69748 }, { 69759, 69762 }, { 69808, 69818 }, + { 69826, 69826 }, { 69888, 69890 }, { 69927, 69940 }, { 69957, 69958 }, @@ -2740,6 +2848,7 @@ static const URange32 M_range32[] = { { 70016, 70018 }, { 70067, 70080 }, { 70089, 70092 }, + { 70094, 70095 }, { 70188, 70199 }, { 70206, 70206 }, { 70367, 70378 }, @@ -2762,6 +2871,11 @@ static const URange32 M_range32[] = { { 71339, 71351 }, { 71453, 71467 }, { 71724, 71738 }, + { 71984, 71989 }, + { 71991, 71992 }, + { 71995, 71998 }, + { 72000, 72000 }, + { 72002, 72003 }, { 72145, 72151 }, { 72154, 72160 }, { 72164, 72164 }, @@ -2789,7 +2903,11 @@ static const URange32 M_range32[] = { { 94031, 94031 }, { 94033, 94087 }, { 94095, 94098 }, + { 94180, 94180 }, + { 94192, 94193 }, { 113821, 113822 }, + { 118528, 118573 }, + { 118576, 118598 }, { 119141, 119145 }, { 119149, 119154 }, { 119163, 119170 }, @@ -2808,6 +2926,7 @@ static const URange32 M_range32[] = { { 122915, 122916 }, { 122918, 122922 }, { 123184, 123190 }, + { 123566, 123566 }, { 123628, 123631 }, { 125136, 125142 }, { 125252, 125258 }, @@ -2871,6 +2990,8 @@ static const URange16 Mc_range16[] = { { 4231, 4236 }, { 4239, 4239 }, { 4250, 4252 }, + { 5909, 5909 }, + { 5940, 5940 }, { 6070, 6070 }, { 6078, 6085 }, { 6087, 6088 }, @@ -2935,6 +3056,7 @@ static const URange32 Mc_range32[] = { { 70018, 70018 }, { 70067, 70069 }, { 70079, 70080 }, + { 70094, 70094 }, { 70188, 70190 }, { 70194, 70195 }, { 70197, 70197 }, @@ -2966,6 +3088,11 @@ static const URange32 Mc_range32[] = { { 71462, 71462 }, { 71724, 71726 }, { 71736, 71736 }, + { 71984, 71989 }, + { 71991, 71992 }, + { 71997, 71997 }, + { 72000, 72000 }, + { 72002, 72002 }, { 72145, 72147 }, { 72156, 72159 }, { 72164, 72164 }, @@ -2982,6 +3109,7 @@ static const URange32 Mc_range32[] = { { 73110, 73110 }, { 73461, 73462 }, { 94033, 94087 }, + { 94192, 94193 }, { 119141, 119142 }, { 119149, 119154 }, }; @@ -3017,7 +3145,8 @@ static const URange16 Mn_range16[] = { { 2085, 2087 }, { 2089, 2093 }, { 2137, 2139 }, - { 2259, 2273 }, + { 2200, 2207 }, + { 2250, 2273 }, { 2275, 2306 }, { 2362, 2362 }, { 2364, 2364 }, @@ -3051,13 +3180,14 @@ static const URange16 Mn_range16[] = { { 2879, 2879 }, { 2881, 2884 }, { 2893, 2893 }, - { 2902, 2902 }, + { 2901, 2902 }, { 2914, 2915 }, { 2946, 2946 }, { 3008, 3008 }, { 3021, 3021 }, { 3072, 3072 }, { 3076, 3076 }, + { 3132, 3132 }, { 3134, 3136 }, { 3142, 3144 }, { 3146, 3149 }, @@ -3074,6 +3204,7 @@ static const URange16 Mn_range16[] = { { 3393, 3396 }, { 3405, 3405 }, { 3426, 3427 }, + { 3457, 3457 }, { 3530, 3530 }, { 3538, 3540 }, { 3542, 3542 }, @@ -3106,7 +3237,7 @@ static const URange16 Mn_range16[] = { { 4253, 4253 }, { 4957, 4959 }, { 5906, 5908 }, - { 5938, 5940 }, + { 5938, 5939 }, { 5970, 5971 }, { 6002, 6003 }, { 6068, 6069 }, @@ -3115,6 +3246,7 @@ static const URange16 Mn_range16[] = { { 6089, 6099 }, { 6109, 6109 }, { 6155, 6157 }, + { 6159, 6159 }, { 6277, 6278 }, { 6313, 6313 }, { 6432, 6434 }, @@ -3131,6 +3263,7 @@ static const URange16 Mn_range16[] = { { 6771, 6780 }, { 6783, 6783 }, { 6832, 6845 }, + { 6847, 6862 }, { 6912, 6915 }, { 6964, 6964 }, { 6966, 6970 }, @@ -3153,8 +3286,7 @@ static const URange16 Mn_range16[] = { { 7405, 7405 }, { 7412, 7412 }, { 7416, 7417 }, - { 7616, 7673 }, - { 7675, 7679 }, + { 7616, 7679 }, { 8400, 8412 }, { 8417, 8417 }, { 8421, 8432 }, @@ -3171,6 +3303,7 @@ static const URange16 Mn_range16[] = { { 43014, 43014 }, { 43019, 43019 }, { 43045, 43046 }, + { 43052, 43052 }, { 43204, 43205 }, { 43232, 43249 }, { 43263, 43263 }, @@ -3212,12 +3345,17 @@ static const URange32 Mn_range32[] = { { 68159, 68159 }, { 68325, 68326 }, { 68900, 68903 }, + { 69291, 69292 }, { 69446, 69456 }, + { 69506, 69509 }, { 69633, 69633 }, { 69688, 69702 }, + { 69744, 69744 }, + { 69747, 69748 }, { 69759, 69761 }, { 69811, 69814 }, { 69817, 69818 }, + { 69826, 69826 }, { 69888, 69890 }, { 69927, 69931 }, { 69933, 69940 }, @@ -3225,6 +3363,7 @@ static const URange32 Mn_range32[] = { { 70016, 70017 }, { 70070, 70078 }, { 70089, 70092 }, + { 70095, 70095 }, { 70191, 70193 }, { 70196, 70196 }, { 70198, 70199 }, @@ -3260,6 +3399,9 @@ static const URange32 Mn_range32[] = { { 71463, 71467 }, { 71727, 71735 }, { 71737, 71738 }, + { 71995, 71996 }, + { 71998, 71998 }, + { 72003, 72003 }, { 72148, 72151 }, { 72154, 72155 }, { 72160, 72160 }, @@ -3291,7 +3433,10 @@ static const URange32 Mn_range32[] = { { 92976, 92982 }, { 94031, 94031 }, { 94095, 94098 }, + { 94180, 94180 }, { 113821, 113822 }, + { 118528, 118573 }, + { 118576, 118598 }, { 119143, 119145 }, { 119163, 119170 }, { 119173, 119179 }, @@ -3309,6 +3454,7 @@ static const URange32 Mn_range32[] = { { 122915, 122916 }, { 122918, 122922 }, { 123184, 123190 }, + { 123566, 123566 }, { 123628, 123631 }, { 125136, 125142 }, { 125252, 125258 }, @@ -3413,6 +3559,7 @@ static const URange32 N_range32[] = { { 69216, 69246 }, { 69405, 69414 }, { 69457, 69460 }, + { 69573, 69579 }, { 69714, 69743 }, { 69872, 69881 }, { 69942, 69951 }, @@ -3425,12 +3572,14 @@ static const URange32 N_range32[] = { { 71360, 71369 }, { 71472, 71483 }, { 71904, 71922 }, + { 72016, 72025 }, { 72784, 72812 }, { 73040, 73049 }, { 73120, 73129 }, { 73664, 73684 }, { 74752, 74862 }, { 92768, 92777 }, + { 92864, 92873 }, { 93008, 93017 }, { 93019, 93025 }, { 93824, 93846 }, @@ -3447,6 +3596,7 @@ static const URange32 N_range32[] = { { 126209, 126253 }, { 126255, 126269 }, { 127232, 127244 }, + { 130032, 130041 }, }; static const URange16 Nd_range16[] = { { 48, 57 }, @@ -3501,15 +3651,18 @@ static const URange32 Nd_range32[] = { { 71360, 71369 }, { 71472, 71481 }, { 71904, 71913 }, + { 72016, 72025 }, { 72784, 72793 }, { 73040, 73049 }, { 73120, 73129 }, { 92768, 92777 }, + { 92864, 92873 }, { 93008, 93017 }, { 120782, 120831 }, { 123200, 123209 }, { 123632, 123641 }, { 125264, 125273 }, + { 130032, 130041 }, }; static const URange16 Nl_range16[] = { { 5870, 5872 }, @@ -3583,6 +3736,7 @@ static const URange32 No_range32[] = { { 69216, 69246 }, { 69405, 69414 }, { 69457, 69460 }, + { 69573, 69579 }, { 69714, 69733 }, { 70113, 70132 }, { 71482, 71483 }, @@ -3629,7 +3783,7 @@ static const URange16 P_range16[] = { { 1545, 1546 }, { 1548, 1549 }, { 1563, 1563 }, - { 1566, 1567 }, + { 1565, 1567 }, { 1642, 1645 }, { 1748, 1748 }, { 1792, 1805 }, @@ -3668,6 +3822,7 @@ static const URange16 P_range16[] = { { 6816, 6822 }, { 6824, 6829 }, { 7002, 7008 }, + { 7037, 7038 }, { 7164, 7167 }, { 7227, 7231 }, { 7294, 7295 }, @@ -3692,6 +3847,7 @@ static const URange16 P_range16[] = { { 11632, 11632 }, { 11776, 11822 }, { 11824, 11855 }, + { 11858, 11869 }, { 12289, 12291 }, { 12296, 12305 }, { 12308, 12319 }, @@ -3747,7 +3903,9 @@ static const URange32 P_range32[] = { { 68336, 68342 }, { 68409, 68415 }, { 68505, 68508 }, + { 69293, 69293 }, { 69461, 69465 }, + { 69510, 69513 }, { 69703, 69709 }, { 69819, 69820 }, { 69822, 69825 }, @@ -3760,14 +3918,16 @@ static const URange32 P_range32[] = { { 70200, 70205 }, { 70313, 70313 }, { 70731, 70735 }, - { 70747, 70747 }, + { 70746, 70747 }, { 70749, 70749 }, { 70854, 70854 }, { 71105, 71127 }, { 71233, 71235 }, { 71264, 71276 }, + { 71353, 71353 }, { 71484, 71486 }, { 71739, 71739 }, + { 72004, 72006 }, { 72162, 72162 }, { 72255, 72262 }, { 72346, 72348 }, @@ -3777,6 +3937,7 @@ static const URange32 P_range32[] = { { 73463, 73464 }, { 73727, 73727 }, { 74864, 74868 }, + { 77809, 77810 }, { 92782, 92783 }, { 92917, 92917 }, { 92983, 92987 }, @@ -3806,6 +3967,7 @@ static const URange16 Pd_range16[] = { { 11802, 11802 }, { 11834, 11835 }, { 11840, 11840 }, + { 11869, 11869 }, { 12316, 12316 }, { 12336, 12336 }, { 12448, 12448 }, @@ -3814,6 +3976,9 @@ static const URange16 Pd_range16[] = { { 65123, 65123 }, { 65293, 65293 }, }; +static const URange32 Pd_range32[] = { + { 69293, 69293 }, +}; static const URange16 Pe_range16[] = { { 41, 41 }, { 93, 93 }, @@ -3858,6 +4023,10 @@ static const URange16 Pe_range16[] = { { 11813, 11813 }, { 11815, 11815 }, { 11817, 11817 }, + { 11862, 11862 }, + { 11864, 11864 }, + { 11866, 11866 }, + { 11868, 11868 }, { 12297, 12297 }, { 12299, 12299 }, { 12301, 12301 }, @@ -3937,7 +4106,7 @@ static const URange16 Po_range16[] = { { 1545, 1546 }, { 1548, 1549 }, { 1563, 1563 }, - { 1566, 1567 }, + { 1565, 1567 }, { 1642, 1645 }, { 1748, 1748 }, { 1792, 1805 }, @@ -3974,6 +4143,7 @@ static const URange16 Po_range16[] = { { 6816, 6822 }, { 6824, 6829 }, { 7002, 7008 }, + { 7037, 7038 }, { 7164, 7167 }, { 7227, 7231 }, { 7294, 7295 }, @@ -4002,6 +4172,7 @@ static const URange16 Po_range16[] = { { 11836, 11839 }, { 11841, 11841 }, { 11843, 11855 }, + { 11858, 11860 }, { 12289, 12291 }, { 12349, 12349 }, { 12539, 12539 }, @@ -4057,6 +4228,7 @@ static const URange32 Po_range32[] = { { 68409, 68415 }, { 68505, 68508 }, { 69461, 69465 }, + { 69510, 69513 }, { 69703, 69709 }, { 69819, 69820 }, { 69822, 69825 }, @@ -4069,14 +4241,16 @@ static const URange32 Po_range32[] = { { 70200, 70205 }, { 70313, 70313 }, { 70731, 70735 }, - { 70747, 70747 }, + { 70746, 70747 }, { 70749, 70749 }, { 70854, 70854 }, { 71105, 71127 }, { 71233, 71235 }, { 71264, 71276 }, + { 71353, 71353 }, { 71484, 71486 }, { 71739, 71739 }, + { 72004, 72006 }, { 72162, 72162 }, { 72255, 72262 }, { 72346, 72348 }, @@ -4086,6 +4260,7 @@ static const URange32 Po_range32[] = { { 73463, 73464 }, { 73727, 73727 }, { 74864, 74868 }, + { 77809, 77810 }, { 92782, 92783 }, { 92917, 92917 }, { 92983, 92987 }, @@ -4143,6 +4318,10 @@ static const URange16 Ps_range16[] = { { 11814, 11814 }, { 11816, 11816 }, { 11842, 11842 }, + { 11861, 11861 }, + { 11863, 11863 }, + { 11865, 11865 }, + { 11867, 11867 }, { 12296, 12296 }, { 12298, 12298 }, { 12300, 12300 }, @@ -4207,6 +4386,7 @@ static const URange16 S_range16[] = { { 1789, 1790 }, { 2038, 2038 }, { 2046, 2047 }, + { 2184, 2184 }, { 2546, 2547 }, { 2554, 2555 }, { 2801, 2801 }, @@ -4245,7 +4425,7 @@ static const URange16 S_range16[] = { { 8274, 8274 }, { 8314, 8316 }, { 8330, 8332 }, - { 8352, 8383 }, + { 8352, 8384 }, { 8448, 8449 }, { 8451, 8454 }, { 8456, 8457 }, @@ -4274,8 +4454,9 @@ static const URange16 S_range16[] = { { 10716, 10747 }, { 10750, 11123 }, { 11126, 11157 }, - { 11160, 11263 }, + { 11159, 11263 }, { 11493, 11498 }, + { 11856, 11857 }, { 11904, 11929 }, { 11931, 12019 }, { 12032, 12245 }, @@ -4304,9 +4485,12 @@ static const URange16 S_range16[] = { { 43062, 43065 }, { 43639, 43641 }, { 43867, 43867 }, + { 43882, 43883 }, { 64297, 64297 }, - { 64434, 64449 }, - { 65020, 65021 }, + { 64434, 64450 }, + { 64832, 64847 }, + { 64975, 64975 }, + { 65020, 65023 }, { 65122, 65122 }, { 65124, 65126 }, { 65129, 65129 }, @@ -4325,7 +4509,7 @@ static const URange32 S_range32[] = { { 65847, 65855 }, { 65913, 65929 }, { 65932, 65934 }, - { 65936, 65947 }, + { 65936, 65948 }, { 65952, 65952 }, { 66000, 66044 }, { 67703, 67704 }, @@ -4335,13 +4519,14 @@ static const URange32 S_range32[] = { { 92988, 92991 }, { 92997, 92997 }, { 113820, 113820 }, + { 118608, 118723 }, { 118784, 119029 }, { 119040, 119078 }, { 119081, 119140 }, { 119146, 119148 }, { 119171, 119172 }, { 119180, 119209 }, - { 119214, 119272 }, + { 119214, 119274 }, { 119296, 119361 }, { 119365, 119365 }, { 119552, 119638 }, @@ -4372,36 +4557,38 @@ static const URange32 S_range32[] = { { 127153, 127167 }, { 127169, 127183 }, { 127185, 127221 }, - { 127248, 127340 }, - { 127344, 127404 }, + { 127245, 127405 }, { 127462, 127490 }, { 127504, 127547 }, { 127552, 127560 }, { 127568, 127569 }, { 127584, 127589 }, - { 127744, 128725 }, - { 128736, 128748 }, - { 128752, 128762 }, + { 127744, 128727 }, + { 128733, 128748 }, + { 128752, 128764 }, { 128768, 128883 }, { 128896, 128984 }, { 128992, 129003 }, + { 129008, 129008 }, { 129024, 129035 }, { 129040, 129095 }, { 129104, 129113 }, { 129120, 129159 }, { 129168, 129197 }, - { 129280, 129291 }, - { 129293, 129393 }, - { 129395, 129398 }, - { 129402, 129442 }, - { 129445, 129450 }, - { 129454, 129482 }, - { 129485, 129619 }, + { 129200, 129201 }, + { 129280, 129619 }, { 129632, 129645 }, - { 129648, 129651 }, - { 129656, 129658 }, - { 129664, 129666 }, - { 129680, 129685 }, + { 129648, 129652 }, + { 129656, 129660 }, + { 129664, 129670 }, + { 129680, 129708 }, + { 129712, 129722 }, + { 129728, 129733 }, + { 129744, 129753 }, + { 129760, 129767 }, + { 129776, 129782 }, + { 129792, 129938 }, + { 129940, 129994 }, }; static const URange16 Sc_range16[] = { { 36, 36 }, @@ -4415,7 +4602,7 @@ static const URange16 Sc_range16[] = { { 3065, 3065 }, { 3647, 3647 }, { 6107, 6107 }, - { 8352, 8383 }, + { 8352, 8384 }, { 43064, 43064 }, { 65020, 65020 }, { 65129, 65129 }, @@ -4442,6 +4629,7 @@ static const URange16 Sk_range16[] = { { 751, 767 }, { 885, 885 }, { 900, 901 }, + { 2184, 2184 }, { 8125, 8125 }, { 8127, 8129 }, { 8141, 8143 }, @@ -4453,7 +4641,8 @@ static const URange16 Sk_range16[] = { { 42784, 42785 }, { 42889, 42890 }, { 43867, 43867 }, - { 64434, 64449 }, + { 43882, 43883 }, + { 64434, 64450 }, { 65342, 65342 }, { 65344, 65344 }, { 65507, 65507 }, @@ -4610,8 +4799,9 @@ static const URange16 So_range16[] = { { 11077, 11078 }, { 11085, 11123 }, { 11126, 11157 }, - { 11160, 11263 }, + { 11159, 11263 }, { 11493, 11498 }, + { 11856, 11857 }, { 11904, 11929 }, { 11931, 12019 }, { 12032, 12245 }, @@ -4636,7 +4826,9 @@ static const URange16 So_range16[] = { { 43062, 43063 }, { 43065, 43065 }, { 43639, 43641 }, - { 65021, 65021 }, + { 64832, 64847 }, + { 64975, 64975 }, + { 65021, 65023 }, { 65508, 65508 }, { 65512, 65512 }, { 65517, 65518 }, @@ -4646,7 +4838,7 @@ static const URange32 So_range32[] = { { 65847, 65855 }, { 65913, 65929 }, { 65932, 65934 }, - { 65936, 65947 }, + { 65936, 65948 }, { 65952, 65952 }, { 66000, 66044 }, { 67703, 67704 }, @@ -4657,13 +4849,14 @@ static const URange32 So_range32[] = { { 92988, 92991 }, { 92997, 92997 }, { 113820, 113820 }, + { 118608, 118723 }, { 118784, 119029 }, { 119040, 119078 }, { 119081, 119140 }, { 119146, 119148 }, { 119171, 119172 }, { 119180, 119209 }, - { 119214, 119272 }, + { 119214, 119274 }, { 119296, 119361 }, { 119365, 119365 }, { 119552, 119638 }, @@ -4681,37 +4874,39 @@ static const URange32 So_range32[] = { { 127153, 127167 }, { 127169, 127183 }, { 127185, 127221 }, - { 127248, 127340 }, - { 127344, 127404 }, + { 127245, 127405 }, { 127462, 127490 }, { 127504, 127547 }, { 127552, 127560 }, { 127568, 127569 }, { 127584, 127589 }, { 127744, 127994 }, - { 128000, 128725 }, - { 128736, 128748 }, - { 128752, 128762 }, + { 128000, 128727 }, + { 128733, 128748 }, + { 128752, 128764 }, { 128768, 128883 }, { 128896, 128984 }, { 128992, 129003 }, + { 129008, 129008 }, { 129024, 129035 }, { 129040, 129095 }, { 129104, 129113 }, { 129120, 129159 }, { 129168, 129197 }, - { 129280, 129291 }, - { 129293, 129393 }, - { 129395, 129398 }, - { 129402, 129442 }, - { 129445, 129450 }, - { 129454, 129482 }, - { 129485, 129619 }, + { 129200, 129201 }, + { 129280, 129619 }, { 129632, 129645 }, - { 129648, 129651 }, - { 129656, 129658 }, - { 129664, 129666 }, - { 129680, 129685 }, + { 129648, 129652 }, + { 129656, 129660 }, + { 129664, 129670 }, + { 129680, 129708 }, + { 129712, 129722 }, + { 129728, 129733 }, + { 129744, 129753 }, + { 129760, 129767 }, + { 129776, 129782 }, + { 129792, 129938 }, + { 129940, 129994 }, }; static const URange16 Z_range16[] = { { 32, 32 }, @@ -4746,7 +4941,7 @@ static const URange32 Adlam_range32[] = { static const URange32 Ahom_range32[] = { { 71424, 71450 }, { 71453, 71467 }, - { 71472, 71487 }, + { 71472, 71494 }, }; static const URange32 Anatolian_Hieroglyphs_range32[] = { { 82944, 83526 }, @@ -4755,23 +4950,23 @@ static const URange16 Arabic_range16[] = { { 1536, 1540 }, { 1542, 1547 }, { 1549, 1562 }, - { 1564, 1564 }, - { 1566, 1566 }, + { 1564, 1566 }, { 1568, 1599 }, { 1601, 1610 }, { 1622, 1647 }, { 1649, 1756 }, { 1758, 1791 }, { 1872, 1919 }, - { 2208, 2228 }, - { 2230, 2237 }, - { 2259, 2273 }, + { 2160, 2190 }, + { 2192, 2193 }, + { 2200, 2273 }, { 2275, 2303 }, - { 64336, 64449 }, + { 64336, 64450 }, { 64467, 64829 }, - { 64848, 64911 }, + { 64832, 64911 }, { 64914, 64967 }, - { 65008, 65021 }, + { 64975, 64975 }, + { 65008, 65023 }, { 65136, 65140 }, { 65142, 65276 }, }; @@ -4814,8 +5009,7 @@ static const URange32 Arabic_range32[] = { }; static const URange16 Armenian_range16[] = { { 1329, 1366 }, - { 1369, 1416 }, - { 1418, 1418 }, + { 1369, 1418 }, { 1421, 1423 }, { 64275, 64279 }, }; @@ -4824,8 +5018,8 @@ static const URange32 Avestan_range32[] = { { 68409, 68415 }, }; static const URange16 Balinese_range16[] = { - { 6912, 6987 }, - { 6992, 7036 }, + { 6912, 6988 }, + { 6992, 7038 }, }; static const URange16 Bamum_range16[] = { { 42656, 42743 }, @@ -4866,11 +5060,11 @@ static const URange32 Bhaiksuki_range32[] = { static const URange16 Bopomofo_range16[] = { { 746, 747 }, { 12549, 12591 }, - { 12704, 12730 }, + { 12704, 12735 }, }; static const URange32 Brahmi_range32[] = { { 69632, 69709 }, - { 69714, 69743 }, + { 69714, 69749 }, { 69759, 69759 }, }; static const URange16 Braille_range16[] = { @@ -4887,6 +5081,9 @@ static const URange16 Canadian_Aboriginal_range16[] = { { 5120, 5759 }, { 6320, 6389 }, }; +static const URange32 Canadian_Aboriginal_range32[] = { + { 72368, 72383 }, +}; static const URange32 Carian_range32[] = { { 66208, 66256 }, }; @@ -4896,7 +5093,7 @@ static const URange32 Caucasian_Albanian_range32[] = { }; static const URange32 Chakma_range32[] = { { 69888, 69940 }, - { 69942, 69958 }, + { 69942, 69959 }, }; static const URange16 Cham_range16[] = { { 43520, 43574 }, @@ -4909,6 +5106,9 @@ static const URange16 Cherokee_range16[] = { { 5112, 5117 }, { 43888, 43967 }, }; +static const URange32 Chorasmian_range32[] = { + { 69552, 69579 }, +}; static const URange16 Common_range16[] = { { 0, 64 }, { 91, 96 }, @@ -4924,7 +5124,6 @@ static const URange16 Common_range16[] = { { 894, 894 }, { 901, 901 }, { 903, 903 }, - { 1417, 1417 }, { 1541, 1541 }, { 1548, 1548 }, { 1563, 1563 }, @@ -4951,7 +5150,7 @@ static const URange16 Common_range16[] = { { 8294, 8304 }, { 8308, 8318 }, { 8320, 8334 }, - { 8352, 8383 }, + { 8352, 8384 }, { 8448, 8485 }, { 8487, 8489 }, { 8492, 8497 }, @@ -4963,8 +5162,8 @@ static const URange16 Common_range16[] = { { 9312, 10239 }, { 10496, 11123 }, { 11126, 11157 }, - { 11160, 11263 }, - { 11776, 11855 }, + { 11159, 11263 }, + { 11776, 11869 }, { 12272, 12283 }, { 12288, 12292 }, { 12294, 12294 }, @@ -4987,6 +5186,7 @@ static const URange16 Common_range16[] = { { 43310, 43310 }, { 43471, 43471 }, { 43867, 43867 }, + { 43882, 43883 }, { 64830, 64831 }, { 65040, 65049 }, { 65072, 65106 }, @@ -5006,18 +5206,18 @@ static const URange32 Common_range32[] = { { 65792, 65794 }, { 65799, 65843 }, { 65847, 65855 }, - { 65936, 65947 }, + { 65936, 65948 }, { 66000, 66044 }, { 66273, 66299 }, - { 94178, 94179 }, { 113824, 113827 }, + { 118608, 118723 }, { 118784, 119029 }, { 119040, 119078 }, { 119081, 119142 }, { 119146, 119162 }, { 119171, 119172 }, { 119180, 119209 }, - { 119214, 119272 }, + { 119214, 119274 }, { 119520, 119539 }, { 119552, 119638 }, { 119648, 119672 }, @@ -5050,38 +5250,40 @@ static const URange32 Common_range32[] = { { 127153, 127167 }, { 127169, 127183 }, { 127185, 127221 }, - { 127232, 127244 }, - { 127248, 127340 }, - { 127344, 127404 }, + { 127232, 127405 }, { 127462, 127487 }, { 127489, 127490 }, { 127504, 127547 }, { 127552, 127560 }, { 127568, 127569 }, { 127584, 127589 }, - { 127744, 128725 }, - { 128736, 128748 }, - { 128752, 128762 }, + { 127744, 128727 }, + { 128733, 128748 }, + { 128752, 128764 }, { 128768, 128883 }, { 128896, 128984 }, { 128992, 129003 }, + { 129008, 129008 }, { 129024, 129035 }, { 129040, 129095 }, { 129104, 129113 }, { 129120, 129159 }, { 129168, 129197 }, - { 129280, 129291 }, - { 129293, 129393 }, - { 129395, 129398 }, - { 129402, 129442 }, - { 129445, 129450 }, - { 129454, 129482 }, - { 129485, 129619 }, + { 129200, 129201 }, + { 129280, 129619 }, { 129632, 129645 }, - { 129648, 129651 }, - { 129656, 129658 }, - { 129664, 129666 }, - { 129680, 129685 }, + { 129648, 129652 }, + { 129656, 129660 }, + { 129664, 129670 }, + { 129680, 129708 }, + { 129712, 129722 }, + { 129728, 129733 }, + { 129744, 129753 }, + { 129760, 129767 }, + { 129776, 129782 }, + { 129792, 129938 }, + { 129940, 129994 }, + { 130032, 130041 }, { 917505, 917505 }, { 917536, 917631 }, }; @@ -5104,6 +5306,9 @@ static const URange32 Cypriot_range32[] = { { 67644, 67644 }, { 67647, 67647 }, }; +static const URange32 Cypro_Minoan_range32[] = { + { 77712, 77810 }, +}; static const URange16 Cyrillic_range16[] = { { 1024, 1156 }, { 1159, 1327 }, @@ -5123,6 +5328,16 @@ static const URange16 Devanagari_range16[] = { { 2406, 2431 }, { 43232, 43263 }, }; +static const URange32 Dives_Akuru_range32[] = { + { 71936, 71942 }, + { 71945, 71945 }, + { 71948, 71955 }, + { 71957, 71958 }, + { 71960, 71989 }, + { 71991, 71992 }, + { 71995, 72006 }, + { 72016, 72025 }, +}; static const URange32 Dogra_range32[] = { { 71680, 71739 }, }; @@ -5177,6 +5392,12 @@ static const URange16 Ethiopic_range16[] = { { 43808, 43814 }, { 43816, 43822 }, }; +static const URange32 Ethiopic_range32[] = { + { 124896, 124902 }, + { 124904, 124907 }, + { 124909, 124910 }, + { 124912, 124926 }, +}; static const URange16 Georgian_range16[] = { { 4256, 4293 }, { 4295, 4295 }, @@ -5190,8 +5411,7 @@ static const URange16 Georgian_range16[] = { { 11565, 11565 }, }; static const URange16 Glagolitic_range16[] = { - { 11264, 11310 }, - { 11312, 11358 }, + { 11264, 11359 }, }; static const URange32 Glagolitic_range32[] = { { 122880, 122886 }, @@ -5310,18 +5530,21 @@ static const URange16 Han_range16[] = { { 12295, 12295 }, { 12321, 12329 }, { 12344, 12347 }, - { 13312, 19893 }, - { 19968, 40943 }, + { 13312, 19903 }, + { 19968, 40959 }, { 63744, 64109 }, { 64112, 64217 }, }; static const URange32 Han_range32[] = { - { 131072, 173782 }, - { 173824, 177972 }, + { 94178, 94179 }, + { 94192, 94193 }, + { 131072, 173791 }, + { 173824, 177976 }, { 177984, 178205 }, { 178208, 183969 }, { 183984, 191456 }, { 194560, 195101 }, + { 196608, 201546 }, }; static const URange16 Hangul_range16[] = { { 4352, 4607 }, @@ -5367,7 +5590,7 @@ static const URange16 Hiragana_range16[] = { { 12445, 12447 }, }; static const URange32 Hiragana_range32[] = { - { 110593, 110878 }, + { 110593, 110879 }, { 110928, 110930 }, { 127488, 127488 }, }; @@ -5381,15 +5604,14 @@ static const URange16 Inherited_range16[] = { { 1611, 1621 }, { 1648, 1648 }, { 2385, 2388 }, - { 6832, 6846 }, + { 6832, 6862 }, { 7376, 7378 }, { 7380, 7392 }, { 7394, 7400 }, { 7405, 7405 }, { 7412, 7412 }, { 7416, 7417 }, - { 7616, 7673 }, - { 7675, 7679 }, + { 7616, 7679 }, { 8204, 8205 }, { 8400, 8432 }, { 12330, 12333 }, @@ -5401,6 +5623,8 @@ static const URange32 Inherited_range32[] = { { 66045, 66045 }, { 66272, 66272 }, { 70459, 70459 }, + { 118528, 118573 }, + { 118576, 118598 }, { 119143, 119145 }, { 119163, 119170 }, { 119173, 119179 }, @@ -5421,7 +5645,7 @@ static const URange16 Javanese_range16[] = { { 43486, 43487 }, }; static const URange32 Kaithi_range32[] = { - { 69760, 69825 }, + { 69760, 69826 }, { 69837, 69837 }, }; static const URange16 Kannada_range16[] = { @@ -5434,7 +5658,7 @@ static const URange16 Kannada_range16[] = { { 3270, 3272 }, { 3274, 3277 }, { 3285, 3286 }, - { 3294, 3294 }, + { 3293, 3294 }, { 3296, 3299 }, { 3302, 3311 }, { 3313, 3314 }, @@ -5449,7 +5673,11 @@ static const URange16 Katakana_range16[] = { { 65393, 65437 }, }; static const URange32 Katakana_range32[] = { + { 110576, 110579 }, + { 110581, 110587 }, + { 110589, 110590 }, { 110592, 110592 }, + { 110880, 110882 }, { 110948, 110951 }, }; static const URange16 Kayah_Li_range16[] = { @@ -5466,6 +5694,10 @@ static const URange32 Kharoshthi_range32[] = { { 68159, 68168 }, { 68176, 68184 }, }; +static const URange32 Khitan_Small_Script_range32[] = { + { 94180, 94180 }, + { 101120, 101589 }, +}; static const URange16 Khmer_range16[] = { { 6016, 6109 }, { 6112, 6121 }, @@ -5517,16 +5749,24 @@ static const URange16 Latin_range16[] = { { 8544, 8584 }, { 11360, 11391 }, { 42786, 42887 }, - { 42891, 42943 }, - { 42946, 42950 }, - { 42999, 43007 }, + { 42891, 42954 }, + { 42960, 42961 }, + { 42963, 42963 }, + { 42965, 42969 }, + { 42994, 43007 }, { 43824, 43866 }, { 43868, 43876 }, - { 43878, 43879 }, + { 43878, 43881 }, { 64256, 64262 }, { 65313, 65338 }, { 65345, 65370 }, }; +static const URange32 Latin_range32[] = { + { 67456, 67461 }, + { 67463, 67504 }, + { 67506, 67514 }, + { 122624, 122654 }, +}; static const URange16 Lepcha_range16[] = { { 7168, 7223 }, { 7227, 7241 }, @@ -5556,6 +5796,9 @@ static const URange32 Linear_B_range32[] = { static const URange16 Lisu_range16[] = { { 42192, 42239 }, }; +static const URange32 Lisu_range32[] = { + { 73648, 73648 }, +}; static const URange32 Lycian_range32[] = { { 66176, 66204 }, }; @@ -5570,8 +5813,7 @@ static const URange32 Makasar_range32[] = { { 73440, 73464 }, }; static const URange16 Malayalam_range16[] = { - { 3328, 3331 }, - { 3333, 3340 }, + { 3328, 3340 }, { 3342, 3344 }, { 3346, 3396 }, { 3398, 3400 }, @@ -5633,8 +5875,7 @@ static const URange32 Modi_range32[] = { static const URange16 Mongolian_range16[] = { { 6144, 6145 }, { 6148, 6148 }, - { 6150, 6158 }, - { 6160, 6169 }, + { 6150, 6169 }, { 6176, 6264 }, { 6272, 6314 }, }; @@ -5674,9 +5915,8 @@ static const URange16 New_Tai_Lue_range16[] = { { 6622, 6623 }, }; static const URange32 Newa_range32[] = { - { 70656, 70745 }, - { 70747, 70747 }, - { 70749, 70751 }, + { 70656, 70747 }, + { 70749, 70753 }, }; static const URange16 Nko_range16[] = { { 1984, 2042 }, @@ -5726,6 +5966,9 @@ static const URange32 Old_South_Arabian_range32[] = { static const URange32 Old_Turkic_range32[] = { { 68608, 68680 }, }; +static const URange32 Old_Uyghur_range32[] = { + { 69488, 69513 }, +}; static const URange16 Oriya_range16[] = { { 2817, 2819 }, { 2821, 2828 }, @@ -5737,7 +5980,7 @@ static const URange16 Oriya_range16[] = { { 2876, 2884 }, { 2887, 2888 }, { 2891, 2893 }, - { 2902, 2903 }, + { 2901, 2903 }, { 2908, 2909 }, { 2911, 2915 }, { 2918, 2935 }, @@ -5792,8 +6035,7 @@ static const URange16 Saurashtra_range16[] = { { 43214, 43225 }, }; static const URange32 Sharada_range32[] = { - { 70016, 70093 }, - { 70096, 70111 }, + { 70016, 70111 }, }; static const URange32 Shavian_range32[] = { { 66640, 66687 }, @@ -5808,7 +6050,7 @@ static const URange32 SignWriting_range32[] = { { 121505, 121519 }, }; static const URange16 Sinhala_range16[] = { - { 3458, 3459 }, + { 3457, 3459 }, { 3461, 3478 }, { 3482, 3505 }, { 3507, 3515 }, @@ -5839,7 +6081,7 @@ static const URange16 Sundanese_range16[] = { { 7360, 7367 }, }; static const URange16 Syloti_Nagri_range16[] = { - { 43008, 43051 }, + { 43008, 43052 }, }; static const URange16 Syriac_range16[] = { { 1792, 1805 }, @@ -5848,8 +6090,8 @@ static const URange16 Syriac_range16[] = { { 2144, 2154 }, }; static const URange16 Tagalog_range16[] = { - { 5888, 5900 }, - { 5902, 5908 }, + { 5888, 5909 }, + { 5919, 5919 }, }; static const URange16 Tagbanwa_range16[] = { { 5984, 5996 }, @@ -5872,7 +6114,7 @@ static const URange16 Tai_Viet_range16[] = { { 43739, 43743 }, }; static const URange32 Takri_range32[] = { - { 71296, 71352 }, + { 71296, 71353 }, { 71360, 71369 }, }; static const URange16 Tamil_range16[] = { @@ -5897,21 +6139,27 @@ static const URange32 Tamil_range32[] = { { 73664, 73713 }, { 73727, 73727 }, }; +static const URange32 Tangsa_range32[] = { + { 92784, 92862 }, + { 92864, 92873 }, +}; static const URange32 Tangut_range32[] = { { 94176, 94176 }, { 94208, 100343 }, - { 100352, 101106 }, + { 100352, 101119 }, + { 101632, 101640 }, }; static const URange16 Telugu_range16[] = { { 3072, 3084 }, { 3086, 3088 }, { 3090, 3112 }, { 3114, 3129 }, - { 3133, 3140 }, + { 3132, 3140 }, { 3142, 3144 }, { 3146, 3149 }, { 3157, 3158 }, { 3160, 3162 }, + { 3165, 3165 }, { 3168, 3171 }, { 3174, 3183 }, { 3191, 3199 }, @@ -5941,6 +6189,9 @@ static const URange32 Tirhuta_range32[] = { { 70784, 70855 }, { 70864, 70873 }, }; +static const URange32 Toto_range32[] = { + { 123536, 123566 }, +}; static const URange32 Ugaritic_range32[] = { { 66432, 66461 }, { 66463, 66463 }, @@ -5948,6 +6199,16 @@ static const URange32 Ugaritic_range32[] = { static const URange16 Vai_range16[] = { { 42240, 42539 }, }; +static const URange32 Vithkuqi_range32[] = { + { 66928, 66938 }, + { 66940, 66954 }, + { 66956, 66962 }, + { 66964, 66965 }, + { 66967, 66977 }, + { 66979, 66993 }, + { 66995, 67001 }, + { 67003, 67004 }, +}; static const URange32 Wancho_range32[] = { { 123584, 123641 }, { 123647, 123647 }, @@ -5956,6 +6217,11 @@ static const URange32 Warang_Citi_range32[] = { { 71840, 71922 }, { 71935, 71935 }, }; +static const URange32 Yezidi_range32[] = { + { 69248, 69289 }, + { 69291, 69293 }, + { 69296, 69297 }, +}; static const URange16 Yi_range16[] = { { 40960, 42124 }, { 42128, 42182 }, @@ -5963,13 +6229,13 @@ static const URange16 Yi_range16[] = { static const URange32 Zanabazar_Square_range32[] = { { 72192, 72263 }, }; -// 3987 16-bit ranges, 1525 32-bit ranges +// 4038 16-bit ranges, 1712 32-bit ranges const UGroup unicode_groups[] = { { "Adlam", +1, 0, 0, Adlam_range32, 3 }, { "Ahom", +1, 0, 0, Ahom_range32, 3 }, { "Anatolian_Hieroglyphs", +1, 0, 0, Anatolian_Hieroglyphs_range32, 1 }, { "Arabic", +1, Arabic_range16, 22, Arabic_range32, 35 }, - { "Armenian", +1, Armenian_range16, 5, 0, 0 }, + { "Armenian", +1, Armenian_range16, 4, 0, 0 }, { "Avestan", +1, 0, 0, Avestan_range32, 2 }, { "Balinese", +1, Balinese_range16, 2, 0, 0 }, { "Bamum", +1, Bamum_range16, 1, Bamum_range32, 1 }, @@ -5982,39 +6248,42 @@ const UGroup unicode_groups[] = { { "Braille", +1, Braille_range16, 1, 0, 0 }, { "Buginese", +1, Buginese_range16, 2, 0, 0 }, { "Buhid", +1, Buhid_range16, 1, 0, 0 }, - { "C", +1, C_range16, 16, C_range32, 9 }, - { "Canadian_Aboriginal", +1, Canadian_Aboriginal_range16, 2, 0, 0 }, + { "C", +1, C_range16, 17, C_range32, 9 }, + { "Canadian_Aboriginal", +1, Canadian_Aboriginal_range16, 2, Canadian_Aboriginal_range32, 1 }, { "Carian", +1, 0, 0, Carian_range32, 1 }, { "Caucasian_Albanian", +1, 0, 0, Caucasian_Albanian_range32, 2 }, { "Cc", +1, Cc_range16, 2, 0, 0 }, - { "Cf", +1, Cf_range16, 13, Cf_range32, 7 }, + { "Cf", +1, Cf_range16, 14, Cf_range32, 7 }, { "Chakma", +1, 0, 0, Chakma_range32, 2 }, { "Cham", +1, Cham_range16, 4, 0, 0 }, { "Cherokee", +1, Cherokee_range16, 3, 0, 0 }, + { "Chorasmian", +1, 0, 0, Chorasmian_range32, 1 }, { "Co", +1, Co_range16, 1, Co_range32, 2 }, - { "Common", +1, Common_range16, 91, Common_range32, 81 }, + { "Common", +1, Common_range16, 91, Common_range32, 83 }, { "Coptic", +1, Coptic_range16, 3, 0, 0 }, { "Cs", +1, Cs_range16, 1, 0, 0 }, { "Cuneiform", +1, 0, 0, Cuneiform_range32, 4 }, { "Cypriot", +1, 0, 0, Cypriot_range32, 6 }, + { "Cypro_Minoan", +1, 0, 0, Cypro_Minoan_range32, 1 }, { "Cyrillic", +1, Cyrillic_range16, 8, 0, 0 }, { "Deseret", +1, 0, 0, Deseret_range32, 1 }, { "Devanagari", +1, Devanagari_range16, 4, 0, 0 }, + { "Dives_Akuru", +1, 0, 0, Dives_Akuru_range32, 8 }, { "Dogra", +1, 0, 0, Dogra_range32, 1 }, { "Duployan", +1, 0, 0, Duployan_range32, 5 }, { "Egyptian_Hieroglyphs", +1, 0, 0, Egyptian_Hieroglyphs_range32, 2 }, { "Elbasan", +1, 0, 0, Elbasan_range32, 1 }, { "Elymaic", +1, 0, 0, Elymaic_range32, 1 }, - { "Ethiopic", +1, Ethiopic_range16, 32, 0, 0 }, + { "Ethiopic", +1, Ethiopic_range16, 32, Ethiopic_range32, 4 }, { "Georgian", +1, Georgian_range16, 10, 0, 0 }, - { "Glagolitic", +1, Glagolitic_range16, 2, Glagolitic_range32, 5 }, + { "Glagolitic", +1, Glagolitic_range16, 1, Glagolitic_range32, 5 }, { "Gothic", +1, 0, 0, Gothic_range32, 1 }, { "Grantha", +1, 0, 0, Grantha_range32, 15 }, { "Greek", +1, Greek_range16, 33, Greek_range32, 3 }, { "Gujarati", +1, Gujarati_range16, 14, 0, 0 }, { "Gunjala_Gondi", +1, 0, 0, Gunjala_Gondi_range32, 6 }, { "Gurmukhi", +1, Gurmukhi_range16, 16, 0, 0 }, - { "Han", +1, Han_range16, 11, Han_range32, 6 }, + { "Han", +1, Han_range16, 11, Han_range32, 9 }, { "Hangul", +1, Hangul_range16, 14, 0, 0 }, { "Hanifi_Rohingya", +1, 0, 0, Hanifi_Rohingya_range32, 2 }, { "Hanunoo", +1, Hanunoo_range16, 1, 0, 0 }, @@ -6022,42 +6291,43 @@ const UGroup unicode_groups[] = { { "Hebrew", +1, Hebrew_range16, 9, 0, 0 }, { "Hiragana", +1, Hiragana_range16, 2, Hiragana_range32, 3 }, { "Imperial_Aramaic", +1, 0, 0, Imperial_Aramaic_range32, 2 }, - { "Inherited", +1, Inherited_range16, 20, Inherited_range32, 8 }, + { "Inherited", +1, Inherited_range16, 19, Inherited_range32, 10 }, { "Inscriptional_Pahlavi", +1, 0, 0, Inscriptional_Pahlavi_range32, 2 }, { "Inscriptional_Parthian", +1, 0, 0, Inscriptional_Parthian_range32, 2 }, { "Javanese", +1, Javanese_range16, 3, 0, 0 }, { "Kaithi", +1, 0, 0, Kaithi_range32, 2 }, { "Kannada", +1, Kannada_range16, 13, 0, 0 }, - { "Katakana", +1, Katakana_range16, 7, Katakana_range32, 2 }, + { "Katakana", +1, Katakana_range16, 7, Katakana_range32, 6 }, { "Kayah_Li", +1, Kayah_Li_range16, 2, 0, 0 }, { "Kharoshthi", +1, 0, 0, Kharoshthi_range32, 8 }, + { "Khitan_Small_Script", +1, 0, 0, Khitan_Small_Script_range32, 2 }, { "Khmer", +1, Khmer_range16, 4, 0, 0 }, { "Khojki", +1, 0, 0, Khojki_range32, 2 }, { "Khudawadi", +1, 0, 0, Khudawadi_range32, 2 }, - { "L", +1, L_range16, 380, L_range32, 229 }, + { "L", +1, L_range16, 380, L_range32, 268 }, { "Lao", +1, Lao_range16, 11, 0, 0 }, - { "Latin", +1, Latin_range16, 32, 0, 0 }, + { "Latin", +1, Latin_range16, 34, Latin_range32, 4 }, { "Lepcha", +1, Lepcha_range16, 3, 0, 0 }, { "Limbu", +1, Limbu_range16, 5, 0, 0 }, { "Linear_A", +1, 0, 0, Linear_A_range32, 3 }, { "Linear_B", +1, 0, 0, Linear_B_range32, 7 }, - { "Lisu", +1, Lisu_range16, 1, 0, 0 }, - { "Ll", +1, Ll_range16, 608, Ll_range32, 34 }, - { "Lm", +1, Lm_range16, 54, Lm_range32, 6 }, - { "Lo", +1, Lo_range16, 290, Lo_range32, 186 }, + { "Lisu", +1, Lisu_range16, 1, Lisu_range32, 1 }, + { "Ll", +1, Ll_range16, 617, Ll_range32, 40 }, + { "Lm", +1, Lm_range16, 57, Lm_range32, 12 }, + { "Lo", +1, Lo_range16, 290, Lo_range32, 211 }, { "Lt", +1, Lt_range16, 10, 0, 0 }, - { "Lu", +1, Lu_range16, 599, Lu_range32, 37 }, + { "Lu", +1, Lu_range16, 605, Lu_range32, 41 }, { "Lycian", +1, 0, 0, Lycian_range32, 1 }, { "Lydian", +1, 0, 0, Lydian_range32, 2 }, - { "M", +1, M_range16, 186, M_range32, 94 }, + { "M", +1, M_range16, 189, M_range32, 110 }, { "Mahajani", +1, 0, 0, Mahajani_range32, 1 }, { "Makasar", +1, 0, 0, Makasar_range32, 1 }, - { "Malayalam", +1, Malayalam_range16, 8, 0, 0 }, + { "Malayalam", +1, Malayalam_range16, 7, 0, 0 }, { "Mandaic", +1, Mandaic_range16, 2, 0, 0 }, { "Manichaean", +1, 0, 0, Manichaean_range32, 2 }, { "Marchen", +1, 0, 0, Marchen_range32, 3 }, { "Masaram_Gondi", +1, 0, 0, Masaram_Gondi_range32, 7 }, - { "Mc", +1, Mc_range16, 109, Mc_range32, 59 }, + { "Mc", +1, Mc_range16, 111, Mc_range32, 66 }, { "Me", +1, Me_range16, 5, 0, 0 }, { "Medefaidrin", +1, 0, 0, Medefaidrin_range32, 1 }, { "Meetei_Mayek", +1, Meetei_Mayek_range16, 3, 0, 0 }, @@ -6065,21 +6335,21 @@ const UGroup unicode_groups[] = { { "Meroitic_Cursive", +1, 0, 0, Meroitic_Cursive_range32, 3 }, { "Meroitic_Hieroglyphs", +1, 0, 0, Meroitic_Hieroglyphs_range32, 1 }, { "Miao", +1, 0, 0, Miao_range32, 3 }, - { "Mn", +1, Mn_range16, 207, Mn_range32, 111 }, + { "Mn", +1, Mn_range16, 212, Mn_range32, 124 }, { "Modi", +1, 0, 0, Modi_range32, 2 }, - { "Mongolian", +1, Mongolian_range16, 6, Mongolian_range32, 1 }, + { "Mongolian", +1, Mongolian_range16, 5, Mongolian_range32, 1 }, { "Mro", +1, 0, 0, Mro_range32, 3 }, { "Multani", +1, 0, 0, Multani_range32, 5 }, { "Myanmar", +1, Myanmar_range16, 3, 0, 0 }, - { "N", +1, N_range16, 67, N_range32, 63 }, + { "N", +1, N_range16, 67, N_range32, 67 }, { "Nabataean", +1, 0, 0, Nabataean_range32, 2 }, { "Nandinagari", +1, 0, 0, Nandinagari_range32, 3 }, - { "Nd", +1, Nd_range16, 37, Nd_range32, 22 }, + { "Nd", +1, Nd_range16, 37, Nd_range32, 25 }, { "New_Tai_Lue", +1, New_Tai_Lue_range16, 4, 0, 0 }, - { "Newa", +1, 0, 0, Newa_range32, 3 }, + { "Newa", +1, 0, 0, Newa_range32, 2 }, { "Nko", +1, Nko_range16, 2, 0, 0 }, { "Nl", +1, Nl_range16, 7, Nl_range32, 5 }, - { "No", +1, No_range16, 29, No_range32, 41 }, + { "No", +1, No_range16, 29, No_range32, 42 }, { "Nushu", +1, 0, 0, Nushu_range32, 2 }, { "Nyiakeng_Puachue_Hmong", +1, 0, 0, Nyiakeng_Puachue_Hmong_range32, 4 }, { "Ogham", +1, Ogham_range16, 1, 0, 0 }, @@ -6092,37 +6362,38 @@ const UGroup unicode_groups[] = { { "Old_Sogdian", +1, 0, 0, Old_Sogdian_range32, 1 }, { "Old_South_Arabian", +1, 0, 0, Old_South_Arabian_range32, 1 }, { "Old_Turkic", +1, 0, 0, Old_Turkic_range32, 1 }, + { "Old_Uyghur", +1, 0, 0, Old_Uyghur_range32, 1 }, { "Oriya", +1, Oriya_range16, 14, 0, 0 }, { "Osage", +1, 0, 0, Osage_range32, 2 }, { "Osmanya", +1, 0, 0, Osmanya_range32, 2 }, - { "P", +1, P_range16, 131, P_range32, 51 }, + { "P", +1, P_range16, 133, P_range32, 56 }, { "Pahawh_Hmong", +1, 0, 0, Pahawh_Hmong_range32, 5 }, { "Palmyrene", +1, 0, 0, Palmyrene_range32, 1 }, { "Pau_Cin_Hau", +1, 0, 0, Pau_Cin_Hau_range32, 1 }, { "Pc", +1, Pc_range16, 6, 0, 0 }, - { "Pd", +1, Pd_range16, 17, 0, 0 }, - { "Pe", +1, Pe_range16, 72, 0, 0 }, + { "Pd", +1, Pd_range16, 18, Pd_range32, 1 }, + { "Pe", +1, Pe_range16, 76, 0, 0 }, { "Pf", +1, Pf_range16, 10, 0, 0 }, { "Phags_Pa", +1, Phags_Pa_range16, 1, 0, 0 }, { "Phoenician", +1, 0, 0, Phoenician_range32, 2 }, { "Pi", +1, Pi_range16, 11, 0, 0 }, - { "Po", +1, Po_range16, 128, Po_range32, 51 }, - { "Ps", +1, Ps_range16, 75, 0, 0 }, + { "Po", +1, Po_range16, 130, Po_range32, 55 }, + { "Ps", +1, Ps_range16, 79, 0, 0 }, { "Psalter_Pahlavi", +1, 0, 0, Psalter_Pahlavi_range32, 3 }, { "Rejang", +1, Rejang_range16, 2, 0, 0 }, { "Runic", +1, Runic_range16, 2, 0, 0 }, - { "S", +1, S_range16, 146, S_range32, 80 }, + { "S", +1, S_range16, 151, S_range32, 83 }, { "Samaritan", +1, Samaritan_range16, 2, 0, 0 }, { "Saurashtra", +1, Saurashtra_range16, 2, 0, 0 }, { "Sc", +1, Sc_range16, 18, Sc_range32, 3 }, - { "Sharada", +1, 0, 0, Sharada_range32, 2 }, + { "Sharada", +1, 0, 0, Sharada_range32, 1 }, { "Shavian", +1, 0, 0, Shavian_range32, 1 }, { "Siddham", +1, 0, 0, Siddham_range32, 2 }, { "SignWriting", +1, 0, 0, SignWriting_range32, 3 }, { "Sinhala", +1, Sinhala_range16, 12, Sinhala_range32, 1 }, - { "Sk", +1, Sk_range16, 28, Sk_range32, 1 }, + { "Sk", +1, Sk_range16, 30, Sk_range32, 1 }, { "Sm", +1, Sm_range16, 53, Sm_range32, 11 }, - { "So", +1, So_range16, 111, So_range32, 69 }, + { "So", +1, So_range16, 114, So_range32, 72 }, { "Sogdian", +1, 0, 0, Sogdian_range32, 1 }, { "Sora_Sompeng", +1, 0, 0, Sora_Sompeng_range32, 2 }, { "Soyombo", +1, 0, 0, Soyombo_range32, 1 }, @@ -6136,17 +6407,21 @@ const UGroup unicode_groups[] = { { "Tai_Viet", +1, Tai_Viet_range16, 2, 0, 0 }, { "Takri", +1, 0, 0, Takri_range32, 2 }, { "Tamil", +1, Tamil_range16, 16, Tamil_range32, 2 }, - { "Tangut", +1, 0, 0, Tangut_range32, 3 }, - { "Telugu", +1, Telugu_range16, 12, 0, 0 }, + { "Tangsa", +1, 0, 0, Tangsa_range32, 2 }, + { "Tangut", +1, 0, 0, Tangut_range32, 4 }, + { "Telugu", +1, Telugu_range16, 13, 0, 0 }, { "Thaana", +1, Thaana_range16, 1, 0, 0 }, { "Thai", +1, Thai_range16, 2, 0, 0 }, { "Tibetan", +1, Tibetan_range16, 7, 0, 0 }, { "Tifinagh", +1, Tifinagh_range16, 3, 0, 0 }, { "Tirhuta", +1, 0, 0, Tirhuta_range32, 2 }, + { "Toto", +1, 0, 0, Toto_range32, 1 }, { "Ugaritic", +1, 0, 0, Ugaritic_range32, 2 }, { "Vai", +1, Vai_range16, 1, 0, 0 }, + { "Vithkuqi", +1, 0, 0, Vithkuqi_range32, 8 }, { "Wancho", +1, 0, 0, Wancho_range32, 2 }, { "Warang_Citi", +1, 0, 0, Warang_Citi_range32, 2 }, + { "Yezidi", +1, 0, 0, Yezidi_range32, 3 }, { "Yi", +1, Yi_range16, 2, 0, 0 }, { "Z", +1, Z_range16, 8, 0, 0 }, { "Zanabazar_Square", +1, 0, 0, Zanabazar_Square_range32, 1 }, @@ -6154,7 +6429,7 @@ const UGroup unicode_groups[] = { { "Zp", +1, Zp_range16, 1, 0, 0 }, { "Zs", +1, Zs_range16, 7, 0, 0 }, }; -const int num_unicode_groups = 188; +const int num_unicode_groups = 197; } // namespace re2 diff --git a/re2/walker-inl.h b/re2/walker-inl.h index 310be54..4d064a0 100644 --- a/re2/walker-inl.h +++ b/re2/walker-inl.h @@ -89,7 +89,7 @@ template class Regexp::Walker { private: // Walk state for the entire traversal. - std::stack >* stack_; + std::stack> stack_; bool stopped_early_; int max_visits_; @@ -119,7 +119,7 @@ template T Regexp::Walker::Copy(T arg) { // State about a single level in the traversal. template struct WalkState { - WalkState(Regexp* re, T parent) + WalkState(Regexp* re, T parent) : re(re), n(-1), parent_arg(parent), @@ -134,24 +134,23 @@ template struct WalkState { }; template Regexp::Walker::Walker() { - stack_ = new std::stack >; stopped_early_ = false; } template Regexp::Walker::~Walker() { Reset(); - delete stack_; } // Clears the stack. Should never be necessary, since // Walk always enters and exits with an empty stack. // Logs DFATAL if stack is not already clear. template void Regexp::Walker::Reset() { - if (stack_ && stack_->size() > 0) { + if (!stack_.empty()) { LOG(DFATAL) << "Stack not empty."; - while (stack_->size() > 0) { - delete[] stack_->top().child_args; - stack_->pop(); + while (!stack_.empty()) { + if (stack_.top().re->nsub_ > 1) + delete[] stack_.top().child_args; + stack_.pop(); } } } @@ -165,13 +164,13 @@ template T Regexp::Walker::WalkInternal(Regexp* re, T top_arg, return top_arg; } - stack_->push(WalkState(re, top_arg)); + stack_.push(WalkState(re, top_arg)); WalkState* s; for (;;) { T t; - s = &stack_->top(); - Regexp* re = s->re; + s = &stack_.top(); + re = s->re; switch (s->n) { case -1: { if (--max_visits_ < 0) { @@ -201,7 +200,7 @@ template T Regexp::Walker::WalkInternal(Regexp* re, T top_arg, s->child_args[s->n] = Copy(s->child_args[s->n - 1]); s->n++; } else { - stack_->push(WalkState(sub[s->n], s->pre_arg)); + stack_.push(WalkState(sub[s->n], s->pre_arg)); } continue; } @@ -214,12 +213,12 @@ template T Regexp::Walker::WalkInternal(Regexp* re, T top_arg, } } - // We've finished stack_->top(). + // We've finished stack_.top(). // Update next guy down. - stack_->pop(); - if (stack_->size() == 0) + stack_.pop(); + if (stack_.empty()) return t; - s = &stack_->top(); + s = &stack_.top(); if (s->child_args != NULL) s->child_args[s->n] = t; else diff --git a/testinstall.cc b/testinstall.cc index 47db4e6..19cc900 100644 --- a/testinstall.cc +++ b/testinstall.cc @@ -2,23 +2,26 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include -#include #include +#include +#include + +int main() { + re2::FilteredRE2 f; + int id; + f.Add("a.*b.*c", RE2::DefaultOptions, &id); + std::vector v; + f.Compile(&v); + std::vector ids; + f.FirstMatch("abbccc", ids); -int main(void) { - re2::FilteredRE2 f; - int id; - f.Add("a.*b.*c", RE2::DefaultOptions, &id); - std::vector v; - f.Compile(&v); - std::vector ids; - f.FirstMatch("abbccc", ids); + int n; + if (RE2::FullMatch("axbyc", "a.*b.*c") && + RE2::PartialMatch("foo123bar", "(\\d+)", &n) && n == 123) { + printf("PASS\n"); + return 0; + } - if(RE2::FullMatch("axbyc", "a.*b.*c")) { - printf("PASS\n"); - return 0; - } - printf("FAIL\n"); - return 2; + printf("FAIL\n"); + return 2; } diff --git a/util/mutex.h b/util/mutex.h index 9c49158..158046b 100644 --- a/util/mutex.h +++ b/util/mutex.h @@ -10,7 +10,13 @@ * You should assume the locks are *not* re-entrant. */ -#if !defined(_WIN32) +#ifdef _WIN32 +// Requires Windows Vista or Windows Server 2008 at minimum. +#include +#if defined(WINVER) && WINVER >= 0x0600 +#define MUTEX_IS_WIN32_SRWLOCK +#endif +#else #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif @@ -20,7 +26,9 @@ #endif #endif -#if defined(MUTEX_IS_PTHREAD_RWLOCK) +#if defined(MUTEX_IS_WIN32_SRWLOCK) +typedef SRWLOCK MutexType; +#elif defined(MUTEX_IS_PTHREAD_RWLOCK) #include #include typedef pthread_rwlock_t MutexType; @@ -56,7 +64,16 @@ class Mutex { Mutex& operator=(const Mutex&) = delete; }; -#if defined(MUTEX_IS_PTHREAD_RWLOCK) +#if defined(MUTEX_IS_WIN32_SRWLOCK) + +Mutex::Mutex() : mutex_(SRWLOCK_INIT) { } +Mutex::~Mutex() { } +void Mutex::Lock() { AcquireSRWLockExclusive(&mutex_); } +void Mutex::Unlock() { ReleaseSRWLockExclusive(&mutex_); } +void Mutex::ReaderLock() { AcquireSRWLockShared(&mutex_); } +void Mutex::ReaderUnlock() { ReleaseSRWLockShared(&mutex_); } + +#elif defined(MUTEX_IS_PTHREAD_RWLOCK) #define SAFE_PTHREAD(fncall) \ do { \ diff --git a/util/pcre.cc b/util/pcre.cc index b3a32eb..b689851 100644 --- a/util/pcre.cc +++ b/util/pcre.cc @@ -22,9 +22,7 @@ #include "util/strutil.h" // Silence warnings about the wacky formatting in the operator() functions. -// Note that we test for Clang first because it defines __GNUC__ as well. -#if defined(__clang__) -#elif defined(__GNUC__) && __GNUC__ >= 6 +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 6 #pragma GCC diagnostic ignored "-Wmisleading-indentation" #endif diff --git a/util/pcre.h b/util/pcre.h index 644dce6..896b0bd 100644 --- a/util/pcre.h +++ b/util/pcre.h @@ -555,7 +555,7 @@ class PCRE_Options { // Hex/Octal/Binary? // Special class for parsing into objects that define a ParseFrom() method -template +template class _PCRE_MatchObject { public: static inline bool Parse(const char* str, size_t n, void* dest) { @@ -600,9 +600,9 @@ class PCRE::Arg { #undef MAKE_PARSER // Generic constructor - template Arg(T*, Parser parser); + template Arg(T*, Parser parser); // Generic constructor template - template Arg(T* p) + template Arg(T* p) : arg_(p), parser_(_PCRE_MatchObject::Parse) { } -- Gitee From f7233807b1f8934ecd0251f13c92cef87e13a455 Mon Sep 17 00:00:00 2001 From: wenlong_12 Date: Thu, 20 Apr 2023 18:15:42 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=20=20=20=20=20re2=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=20=20=20=20=20=20Signed-off-by:=20wenlong=5F?= =?UTF-8?q?12=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wenlong_12 --- libre2.map | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libre2.map b/libre2.map index cf15d15..76fd5c4 100644 --- a/libre2.map +++ b/libre2.map @@ -4,8 +4,8 @@ "re2::RE2::~RE2()"; "re2::RE2::RE2(re2::StringPiece const&, re2::RE2::Options const&)"; "re2::RE2::FullMatchN(re2::StringPiece const&, re2::RE2 const&, re2::RE2::Arg const* const*, int)"; - "re2::RE2::GlobalReplace(std::__h::basic_string, std::__h::allocator >*, re2::RE2 const&, re2::StringPiece const&)"; - "re2::RE2::RE2(std::__h::basic_string, std::__h::allocator > const&)"; + "re2::RE2::GlobalReplace(std::__h::basic_string, std::__h::allocator>*, re2::RE2 const&, re2::StringPiece const&)"; + "re2::RE2::RE2(std::__h::basic_string, std::__h::allocator> const&)"; }; local: *; -- Gitee From a22dbf7796bd1124344460e904fd90b2ee57e8d8 Mon Sep 17 00:00:00 2001 From: wenlong_12 Date: Fri, 21 Apr 2023 10:56:46 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=20=20=20=20=20re2=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=20=20=20=20=20=20Signed-off-by:=20wenlong=5F?= =?UTF-8?q?12=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wenlong_12 --- re2-20211101.tar.gz | Bin 0 -> 408934 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 re2-20211101.tar.gz diff --git a/re2-20211101.tar.gz b/re2-20211101.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7a793dc3521e3e55bc6807ee1273df0b36ae04c0 GIT binary patch literal 408934 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%0DO}rtY%}9E9od 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 literal 0 HcmV?d00001 -- Gitee