diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/bazel.sh src/.github/bazel.sh --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/bazel.sh 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/bazel.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -#!/bin/bash -set -eux - -bazel clean -bazel build --compilation_mode=dbg -- //:all -bazel test --compilation_mode=dbg --test_output=errors -- //:all \ - -//:dfa_test \ - -//:exhaustive1_test \ - -//:exhaustive2_test \ - -//:exhaustive3_test \ - -//:exhaustive_test \ - -//:random_test - -bazel clean -bazel build --compilation_mode=opt -- //:all -bazel test --compilation_mode=opt --test_output=errors -- //:all \ - -//:dfa_test \ - -//:exhaustive1_test \ - -//:exhaustive2_test \ - -//:exhaustive3_test \ - -//:exhaustive_test \ - -//:random_test - -exit 0 diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/cmake.sh src/.github/cmake.sh --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/cmake.sh 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/cmake.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -#!/bin/bash -set -eux - -cmake -D CMAKE_BUILD_TYPE=Debug -cmake --build . --config Debug --clean-first -ctest -C Debug --output-on-failure -E 'dfa|exhaustive|random' - -cmake -D CMAKE_BUILD_TYPE=Release -cmake --build . --config Release --clean-first -ctest -C Release --output-on-failure -E 'dfa|exhaustive|random' - -exit 0 diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci-bazel.yml src/.github/workflows/ci-bazel.yml --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci-bazel.yml 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci-bazel.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ -name: CI (Bazel) -on: - push: - branches: [master] -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] - steps: - - uses: actions/checkout@v2 - - run: .github/bazel.sh - shell: bash diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci-cmake.yml src/.github/workflows/ci-cmake.yml --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci-cmake.yml 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci-cmake.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ -name: CI (CMake) -on: - push: - branches: [master] -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] - steps: - - uses: actions/checkout@v2 - - run: .github/cmake.sh - shell: bash diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci.yml src/.github/workflows/ci.yml --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci.yml 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/.github/workflows/ci.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,51 +0,0 @@ -name: CI -on: - push: - branches: [master] -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [macos-latest, ubuntu-latest] - env: - CC: clang - CXX: clang++ - steps: - - uses: actions/checkout@v2 - - run: make && make test - shell: bash - build-clang: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - tag: [9, 10, 11] - env: - CC: clang-${{ matrix.tag }} - CXX: clang++-${{ matrix.tag }} - steps: - - uses: actions/checkout@v2 - - name: Install Clang ${{ matrix.tag }} - run: | - wget https://apt.llvm.org/llvm.sh - chmod +x ./llvm.sh - sudo ./llvm.sh ${{ matrix.tag }} - shell: bash - - run: make && make test - shell: bash - build-gcc: - runs-on: ubuntu-latest - container: gcc:${{ matrix.tag }} - strategy: - fail-fast: false - matrix: - tag: [4, 5, 6, 7, 8, 9, 10] - env: - CC: gcc - CXX: g++ - steps: - - uses: actions/checkout@v2 - - run: make && make test - shell: bash diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/BUILD src/BUILD --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/BUILD 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/BUILD 2023-02-20 19:50:47.000000000 +0100 @@ -8,26 +8,10 @@ exports_files(["LICENSE"]) -config_setting( - name = "macos", - values = {"cpu": "darwin"}, -) - -config_setting( - name = "wasm", - values = {"cpu": "wasm32"}, -) - -config_setting( - name = "windows", - values = {"cpu": "x64_windows"}, -) - -load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") - cc_library( name = "re2", srcs = [ + "re2/bitmap256.cc", "re2/bitmap256.h", "re2/bitstate.cc", "re2/compile.cc", @@ -75,17 +59,17 @@ "re2/stringpiece.h", ], copts = select({ - ":wasm": [], - ":windows": [], + "@platforms//os:wasi": [], + "@platforms//os:windows": [], "//conditions:default": ["-pthread"], }), linkopts = select({ # 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. - ":macos": [], - ":wasm": [], - ":windows": [], + "@platforms//os:macos": [], + "@platforms//os:wasi": [], + "@platforms//os:windows": [], "//conditions:default": ["-pthread"], }), visibility = ["//visibility:public"], diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/CMakeLists.txt src/CMakeLists.txt --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/CMakeLists.txt 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/CMakeLists.txt 2023-02-20 19:50:47.000000000 +0100 @@ -2,29 +2,37 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -# Old enough to support Ubuntu Xenial. -cmake_minimum_required(VERSION 3.5.1) - -if(POLICY CMP0048) - cmake_policy(SET CMP0048 NEW) -endif() +# Old enough to support Ubuntu Bionic, +# but just the MAJOR.MINOR components. +cmake_minimum_required(VERSION 3.10) project(RE2 CXX) +include(CMakePackageConfigHelpers) 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) +option(RE2_USE_ICU "build against ICU for full Unicode properties support" OFF) + +# For historical reasons, this is just "USEPCRE", not "RE2_USE_PCRE". +option(USEPCRE "build against PCRE for testing and benchmarking" OFF) + +# See https://groups.google.com/g/re2-dev/c/P6_NM0YIWvA for details. +# This has no effect unless RE2 is being built for an Apple platform +# such as macOS or iOS. +option(RE2_BUILD_FRAMEWORK "build RE2 as a framework" OFF) # CMake seems to have no way to enable/disable testing per subproject, # so we provide an option similar to BUILD_TESTING, but just for RE2. option(RE2_BUILD_TESTING "enable testing for RE2" ON) +# The pkg-config Requires: field. +set(REQUIRES) + +# ABI version +# http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html +set(SONAME 10) + set(EXTRA_TARGET_LINK_LIBRARIES) if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") @@ -46,9 +54,17 @@ 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) +endif() + +if(UNIX) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) +endif() + +if(RE2_USE_ICU) + find_package(ICU REQUIRED COMPONENTS uc) + add_definitions(-DRE2_USE_ICU) + list(APPEND REQUIRES icu-uc) endif() if(USEPCRE) @@ -56,9 +72,8 @@ list(APPEND EXTRA_TARGET_LINK_LIBRARIES pcre) endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - set(RE2_SOURCES + re2/bitmap256.cc re2/bitstate.cc re2/compile.cc re2/dfa.cc @@ -83,9 +98,37 @@ util/strutil.cc ) +set(RE2_HEADERS + re2/filtered_re2.h + re2/re2.h + re2/set.h + re2/stringpiece.h + ) + add_library(re2 ${RE2_SOURCES}) +target_compile_features(re2 PUBLIC cxx_std_11) +target_include_directories(re2 PUBLIC $) +# CMake gives "set_target_properties called with incorrect number of arguments." +# errors if we don't quote ${RE2_HEADERS}, so quote it despite prevailing style. +set_target_properties(re2 PROPERTIES PUBLIC_HEADER "${RE2_HEADERS}") +set_target_properties(re2 PROPERTIES SOVERSION ${SONAME} VERSION ${SONAME}.0.0) add_library(re2::re2 ALIAS re2) +if(APPLE AND RE2_BUILD_FRAMEWORK) + set_target_properties(re2 PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION A + MACOSX_FRAMEWORK_IDENTIFIER com.googlesource.code.re2) +endif() + +if(UNIX) + target_link_libraries(re2 PUBLIC Threads::Threads) +endif() + +if(RE2_USE_ICU) + target_link_libraries(re2 PUBLIC ICU::uc) +endif() + if(RE2_BUILD_TESTING) set(TESTING_SOURCES re2/testing/backtrack.cc @@ -99,6 +142,8 @@ ) add_library(testing STATIC ${TESTING_SOURCES}) + target_compile_features(testing PUBLIC cxx_std_11) + target_link_libraries(testing PUBLIC re2) set(TEST_TARGETS charclass_test @@ -130,29 +175,44 @@ 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_compile_features(${target} PUBLIC cxx_std_11) + 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_compile_features(${target} PUBLIC cxx_std_11) + target_link_libraries(${target} testing ${EXTRA_TARGET_LINK_LIBRARIES}) + endforeach() endif() -set(RE2_HEADERS - re2/filtered_re2.h - re2/re2.h - re2/set.h - re2/stringpiece.h - ) - -install(FILES ${RE2_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/re2) -install(TARGETS re2 EXPORT re2Config +install(TARGETS re2 + EXPORT re2Targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/re2 INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(EXPORT re2Config - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2 NAMESPACE re2::) +install(EXPORT re2Targets + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2 + NAMESPACE re2::) + +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/re2Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/re2Config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2) +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/re2ConfigVersion.cmake + VERSION ${SONAME}.0.0 + COMPATIBILITY SameMajorVersion) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/re2Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/re2ConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/re2.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/re2.pc + @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/re2.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/CONTRIBUTING.md src/CONTRIBUTING.md --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/CONTRIBUTING.md 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/CONTRIBUTING.md 2023-02-20 19:50:47.000000000 +0100 @@ -1,2 +1,2 @@ RE2 uses Gerrit instead of GitHub pull requests. -See the [Contributing](https://github.com/google/re2/wiki/Contribute) wiki page. +See the [Contribute](https://github.com/google/re2/wiki/Contribute) wiki page. diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/Makefile src/Makefile --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/Makefile 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/Makefile 2023-02-20 19:50:47.000000000 +0100 @@ -7,7 +7,7 @@ # CCICU=$(shell pkg-config icu-uc --cflags) -DRE2_USE_ICU # LDICU=$(shell pkg-config icu-uc --libs) -# To build against PCRE for testing or benchmarking, +# To build against PCRE for testing and benchmarking, # uncomment the next two lines: # CCPCRE=-I/usr/local/include -DUSEPCRE # LDPCRE=-L/usr/local/lib -lpcre @@ -17,7 +17,7 @@ CXXFLAGS?=-O3 -g LDFLAGS?= # required -RE2_CXXFLAGS?=-std=c++11 -pthread -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -I. $(CCICU) $(CCPCRE) +RE2_CXXFLAGS?=-pthread -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -I. $(CCICU) $(CCPCRE) RE2_LDFLAGS?=-pthread $(LDICU) $(LDPCRE) AR?=ar ARFLAGS?=rsc @@ -42,9 +42,15 @@ SED_INPLACE=sed -i endif +# The pkg-config Requires: field. +REQUIRES= +ifdef LDICU +REQUIRES+=icu-uc +endif + # ABI version # http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html -SONAME=8 +SONAME=10 # To rebuild the Tables generated by Perl and Python scripts (requires Internet # access for Unicode data), uncomment the following line: @@ -55,7 +61,7 @@ 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) @@ -112,6 +118,7 @@ OFILES=\ obj/util/rune.o\ obj/util/strutil.o\ + obj/re2/bitmap256.o\ obj/re2/bitstate.o\ obj/re2/compile.o\ obj/re2/dfa.o\ @@ -203,7 +210,7 @@ $(AR) $(ARFLAGS) obj/dbg/libre2.a $(DOFILES) .PRECIOUS: obj/so/libre2.$(SOEXT) -obj/so/libre2.$(SOEXT): $(SOFILES) +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) $@ @@ -244,8 +251,8 @@ perl $< > $@ .PRECIOUS: re2/unicode_%.cc -re2/unicode_%.cc: re2/make_unicode_%.py - python $< > $@ +re2/unicode_%.cc: re2/make_unicode_%.py re2/unicode.py + python3 $< > $@ endif .PHONY: distclean @@ -316,9 +323,11 @@ 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 + $(INSTALL_DATA) re2.pc.in $(DESTDIR)$(libdir)/pkgconfig/re2.pc + $(SED_INPLACE) -e "s#@CMAKE_INSTALL_FULL_INCLUDEDIR@#$(includedir)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc + $(SED_INPLACE) -e "s#@CMAKE_INSTALL_FULL_LIBDIR@#$(libdir)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc + $(SED_INPLACE) -e "s#@REQUIRES@#$(REQUIRES)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc + $(SED_INPLACE) -e "s#@SONAME@#$(SONAME)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc .PHONY: testinstall testinstall: static-testinstall shared-testinstall @@ -327,31 +336,31 @@ @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: - @mkdir -p obj - @cp testinstall.cc obj ifeq ($(shell uname),Darwin) @echo Skipping test for libre2.a on Darwin. else ifeq ($(shell uname),SunOS) @echo Skipping test for libre2.a on SunOS. else - (cd obj && $(CXX) testinstall.cc -o testinstall $(CXXFLAGS) $(LDFLAGS)) - obj/testinstall + @mkdir -p obj + @cp testinstall.cc obj/static-testinstall.cc + (cd obj && export PKG_CONFIG_PATH=$(DESTDIR)$(libdir)/pkgconfig; \ + $(CXX) static-testinstall.cc -o static-testinstall $(CXXFLAGS) $(LDFLAGS) \ + $$(pkg-config re2 --cflags --libs | sed -e "s#-lre2#-l:libre2.a#")) + obj/static-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: @mkdir -p obj - @cp testinstall.cc obj - (cd obj && $(CXX) testinstall.cc -o testinstall $(CXXFLAGS) $(LDFLAGS)) + @cp testinstall.cc obj/shared-testinstall.cc + (cd obj && export PKG_CONFIG_PATH=$(DESTDIR)$(libdir)/pkgconfig; \ + $(CXX) shared-testinstall.cc -o shared-testinstall $(CXXFLAGS) $(LDFLAGS) \ + $$(pkg-config re2 --cflags --libs)) ifeq ($(shell uname),Darwin) - DYLD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(DYLD_LIBRARY_PATH)" obj/testinstall + DYLD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(DYLD_LIBRARY_PATH)" obj/shared-testinstall else - LD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(LD_LIBRARY_PATH)" obj/testinstall + LD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(LD_LIBRARY_PATH)" obj/shared-testinstall endif .PHONY: benchlog diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/README src/README --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/README 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/README 2023-02-20 19:50:47.000000000 +0100 @@ -31,10 +31,12 @@ 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). -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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/SECURITY.md src/SECURITY.md --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/SECURITY.md 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/SECURITY.md 2023-02-20 19:50:47.000000000 +0100 @@ -0,0 +1,4 @@ +To report a security issue, please use https://g.co/vulnz. We use +https://g.co/vulnz for our intake, and do coordination and disclosure here on +GitHub (including using GitHub Security Advisory). The Google Security Team will +respond within 5 working days of your report on https://g.co/vulnz. diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/WORKSPACE src/WORKSPACE --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/WORKSPACE 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/WORKSPACE 2023-02-20 19:50:47.000000000 +0100 @@ -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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/README.xkcd src/doc/README.xkcd --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/README.xkcd 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/README.xkcd 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -xkcd.png is a cropped version of http://xkcd.com/208/ diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/mksyntaxgo src/doc/mksyntaxgo --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/mksyntaxgo 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/mksyntaxgo 2023-02-20 19:50:47.000000000 +0100 @@ -15,7 +15,7 @@ ,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 @@ . $a +Unicode character classes are those in unicode.Categories and unicode.Scripts. */ package syntax . diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/syntax.html src/doc/syntax.html --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/syntax.html 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/syntax.html 2023-02-20 19:50:47.000000000 +0100 @@ -269,6 +269,7 @@ Coptic Cuneiform Cypriot +Cypro_Minoan Cyrillic Deseret Devanagari @@ -302,6 +303,7 @@ Kaithi Kannada Katakana +Kawi Kayah_Li Kharoshthi Khitan_Small_Script @@ -336,6 +338,7 @@ Multani Myanmar Nabataean +Nag_Mundari Nandinagari New_Tai_Lue Newa @@ -352,6 +355,7 @@ Old_Sogdian Old_South_Arabian Old_Turkic +Old_Uyghur Oriya Osage Osmanya @@ -383,6 +387,7 @@ Tai_Viet Takri Tamil +Tangsa Tangut Telugu Thaana @@ -390,8 +395,10 @@ Tibetan Tifinagh Tirhuta +Toto Ugaritic Vai +Vithkuqi Wancho Warang_Citi Yezidi diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/syntax.txt src/doc/syntax.txt --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/syntax.txt 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/doc/syntax.txt 2023-02-20 19:50:47.000000000 +0100 @@ -258,6 +258,7 @@ Coptic Cuneiform Cypriot +Cypro_Minoan Cyrillic Deseret Devanagari @@ -291,6 +292,7 @@ Kaithi Kannada Katakana +Kawi Kayah_Li Kharoshthi Khitan_Small_Script @@ -325,6 +327,7 @@ Multani Myanmar Nabataean +Nag_Mundari Nandinagari New_Tai_Lue Newa @@ -341,6 +344,7 @@ Old_Sogdian Old_South_Arabian Old_Turkic +Old_Uyghur Oriya Osage Osmanya @@ -372,6 +376,7 @@ Tai_Viet Takri Tamil +Tangsa Tangut Telugu Thaana @@ -379,8 +384,10 @@ Tibetan Tifinagh Tirhuta +Toto Ugaritic Vai +Vithkuqi Wancho Warang_Citi Yezidi diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/libre2.symbols src/libre2.symbols --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/libre2.symbols 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/libre2.symbols 2023-02-20 19:50:47.000000000 +0100 @@ -11,6 +11,9 @@ # re2::FilteredRE2* _ZN3re211FilteredRE2*; _ZNK3re211FilteredRE2*; + # re2::re2_internal* + _ZN3re212re2_internal*; + _ZNK3re212re2_internal*; local: *; }; diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/libre2.symbols.darwin src/libre2.symbols.darwin --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/libre2.symbols.darwin 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/libre2.symbols.darwin 2023-02-20 19:50:47.000000000 +0100 @@ -10,3 +10,6 @@ # re2::FilteredRE2* __ZN3re211FilteredRE2* __ZNK3re211FilteredRE2* +# re2::re2_internal* +__ZN3re212re2_internal* +__ZNK3re212re2_internal* diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitmap256.cc src/re2/bitmap256.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitmap256.cc 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitmap256.cc 2023-02-20 19:50:47.000000000 +0100 @@ -0,0 +1,44 @@ +// Copyright 2023 The RE2 Authors. All Rights Reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "re2/bitmap256.h" + +#include + +#include "util/util.h" +#include "util/logging.h" + +namespace re2 { + +int Bitmap256::FindNextSetBit(int c) const { + DCHECK_GE(c, 0); + DCHECK_LE(c, 255); + + // Check the word that contains the bit. Mask out any lower bits. + int i = c / 64; + uint64_t word = words_[i] & (~uint64_t{0} << (c % 64)); + if (word != 0) + return (i * 64) + FindLSBSet(word); + + // Check any following words. + i++; + switch (i) { + case 1: + if (words_[1] != 0) + return (1 * 64) + FindLSBSet(words_[1]); + FALLTHROUGH_INTENDED; + case 2: + if (words_[2] != 0) + return (2 * 64) + FindLSBSet(words_[2]); + FALLTHROUGH_INTENDED; + case 3: + if (words_[3] != 0) + return (3 * 64) + FindLSBSet(words_[3]); + FALLTHROUGH_INTENDED; + default: + return -1; + } +} + +} // namespace re2 diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitmap256.h src/re2/bitmap256.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitmap256.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitmap256.h 2023-02-20 19:50:47.000000000 +0100 @@ -11,7 +11,6 @@ #include #include -#include "util/util.h" #include "util/logging.h" namespace re2 { @@ -82,36 +81,6 @@ uint64_t words_[4]; }; -int Bitmap256::FindNextSetBit(int c) const { - DCHECK_GE(c, 0); - DCHECK_LE(c, 255); - - // Check the word that contains the bit. Mask out any lower bits. - int i = c / 64; - uint64_t word = words_[i] & (~uint64_t{0} << (c % 64)); - if (word != 0) - return (i * 64) + FindLSBSet(word); - - // Check any following words. - i++; - switch (i) { - case 1: - if (words_[1] != 0) - return (1 * 64) + FindLSBSet(words_[1]); - FALLTHROUGH_INTENDED; - case 2: - if (words_[2] != 0) - return (2 * 64) + FindLSBSet(words_[2]); - FALLTHROUGH_INTENDED; - case 3: - if (words_[3] != 0) - return (3 * 64) + FindLSBSet(words_[3]); - FALLTHROUGH_INTENDED; - default: - return -1; - } -} - } // namespace re2 #endif // RE2_BITMAP256_H_ diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitstate.cc src/re2/bitstate.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitstate.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/bitstate.cc 2023-02-20 19:50:47.000000000 +0100 @@ -293,9 +293,9 @@ 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(); @@ -377,7 +377,7 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/compile.cc src/re2/compile.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/compile.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/compile.cc 2023-02-20 19:50:47.000000000 +0100 @@ -79,9 +79,11 @@ struct Frag { uint32_t begin; PatchList end; + bool nullable; - Frag() : begin(0) { end.head = 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. @@ -264,7 +266,7 @@ // Returns an unmatchable fragment. Frag Compiler::NoMatch() { - return Frag(0, kNullPatchList); + return Frag(); } // Is a an unmatchable fragment? @@ -290,11 +292,11 @@ // 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. @@ -310,7 +312,8 @@ 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 @@ -320,27 +323,44 @@ // 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) @@ -358,7 +378,7 @@ 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. @@ -367,7 +387,7 @@ 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. @@ -376,7 +396,7 @@ 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. @@ -385,7 +405,7 @@ if (id < 0) return NoMatch(); inst_[id].InitMatch(match_id); - return Frag(id, kNullPatchList); + return Frag(id, kNullPatchList, false); } // Returns a fragment matching a particular empty-width op (like ^ or $) @@ -394,7 +414,7 @@ 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. @@ -408,7 +428,7 @@ 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. @@ -567,7 +587,7 @@ Frag Compiler::FindByteRange(int root, int id) { if (inst_[root].opcode() == kInstByteRange) { if (ByteRangeEqual(root, id)) - return Frag(root, kNullPatchList); + return Frag(root, kNullPatchList, false); else return NoMatch(); } @@ -575,7 +595,7 @@ 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 @@ -587,7 +607,7 @@ 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(); } @@ -769,8 +789,8 @@ // Should not be called. Frag Compiler::Copy(Frag arg) { // We're using WalkExponential; there should be no copying. - LOG(DFATAL) << "Compiler::Copy called!"; failed_ = true; + LOG(DFATAL) << "Compiler::Copy called!"; return NoMatch(); } @@ -896,8 +916,8 @@ CharClass* cc = re->cc(); if (cc->empty()) { // This can't happen. - LOG(DFATAL) << "No ranges in char class"; failed_ = true; + LOG(DFATAL) << "No ranges in char class"; return NoMatch(); } @@ -954,8 +974,8 @@ case kRegexpNoWordBoundary: return EmptyWidth(kEmptyNonWordBoundary); } - LOG(DFATAL) << "Missing case in Compiler: " << re->op(); failed_ = true; + LOG(DFATAL) << "Missing case in Compiler: " << re->op(); return NoMatch(); } @@ -1156,12 +1176,8 @@ if (!prog_->reversed()) { std::string prefix; bool prefix_foldcase; - if (re->RequiredPrefixForAccel(&prefix, &prefix_foldcase) && - !prefix_foldcase) { - prog_->prefix_size_ = prefix.size(); - prog_->prefix_front_ = prefix.front(); - prog_->prefix_back_ = prefix.back(); - } + if (re->RequiredPrefixForAccel(&prefix, &prefix_foldcase)) + prog_->ConfigurePrefixAccel(prefix, prefix_foldcase); } // Record remaining memory for DFA. diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/dfa.cc src/re2/dfa.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/dfa.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/dfa.cc 2023-02-20 19:50:47.000000000 +0100 @@ -56,6 +56,10 @@ // 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; @@ -167,6 +171,9 @@ typedef std::unordered_set StateSet; private: + // Make it easier to swap in a scalable reader-writer mutex. + using CacheMutex = Mutex; + enum { // Indices into start_ for unanchored searches. // Add kStartAnchored for anchored searches. @@ -331,7 +338,7 @@ // 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. @@ -1106,7 +1113,7 @@ class DFA::RWLocker { public: - explicit RWLocker(Mutex* mu); + explicit RWLocker(CacheMutex* mu); ~RWLocker(); // If the lock is only held for reading right now, @@ -1116,14 +1123,14 @@ 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(); } @@ -1481,15 +1488,15 @@ 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); @@ -1620,7 +1627,7 @@ 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; @@ -1630,13 +1637,13 @@ 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 { @@ -1644,13 +1651,13 @@ 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 { @@ -1668,8 +1675,8 @@ if (!AnalyzeSearchHelper(params, info, flags)) { ResetCache(params->cache_lock); if (!AnalyzeSearchHelper(params, info, flags)) { - LOG(DFATAL) << "Failed to analyze start state."; params->failed = true; + LOG(DFATAL) << "Failed to analyze start state."; return false; } } @@ -1830,9 +1837,9 @@ using std::swap; swap(caret, dollar); } - if (caret && 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 @@ -1963,10 +1970,6 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/compiler-rt/LICENSE src/re2/fuzzing/compiler-rt/LICENSE --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/compiler-rt/LICENSE 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/compiler-rt/LICENSE 2023-02-20 19:50:47.000000000 +0100 @@ -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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h src/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h 2023-02-20 19:50:47.000000000 +0100 @@ -0,0 +1,397 @@ +//===- 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 +#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; + + // See the implementation below (after the class definition) for more verbose + // comments for each of the methods. + + // Methods returning std::vector of bytes. These are the most popular choice + // when splitting fuzzing input into pieces, as every piece is put into a + // separate buffer (i.e. ASan would catch any under-/overflow) and the memory + // will be released automatically. + template std::vector ConsumeBytes(size_t num_bytes); + template + std::vector ConsumeBytesWithTerminator(size_t num_bytes, T terminator = 0); + template std::vector ConsumeRemainingBytes(); + + // Methods returning strings. Use only when you need a std::string or a null + // terminated C-string. Otherwise, prefer the methods returning std::vector. + std::string ConsumeBytesAsString(size_t num_bytes); + std::string ConsumeRandomLengthString(size_t max_length); + std::string ConsumeRandomLengthString(); + std::string ConsumeRemainingBytesAsString(); + + // Methods returning integer values. + template T ConsumeIntegral(); + template T ConsumeIntegralInRange(T min, T max); + + // Methods returning floating point values. + template T ConsumeFloatingPoint(); + template T ConsumeFloatingPointInRange(T min, T max); + + // 0 <= return value <= 1. + template T ConsumeProbability(); + + bool ConsumeBool(); + + // Returns a value chosen from the given enum. + template T ConsumeEnum(); + + // Returns a value from the given array. + template T PickValueInArray(const T (&array)[size]); + template + T PickValueInArray(const std::array &array); + template T PickValueInArray(std::initializer_list list); + + // Writes data to the given destination and returns number of bytes written. + size_t ConsumeData(void *destination, size_t num_bytes); + + // 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 CopyAndAdvance(void *destination, size_t num_bytes); + + void Advance(size_t num_bytes); + + template + std::vector ConsumeBytes(size_t size, size_t num_bytes); + + template TS ConvertUnsignedToSigned(TU value); + + const uint8_t *data_ptr_; + size_t remaining_bytes_; +}; + +// 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 FuzzedDataProvider::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 FuzzedDataProvider::ConsumeBytesWithTerminator(size_t num_bytes, + T terminator) { + 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::vector containing all remaining bytes of the input data. +template +std::vector FuzzedDataProvider::ConsumeRemainingBytes() { + return ConsumeBytes(remaining_bytes_); +} + +// 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. +inline std::string FuzzedDataProvider::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 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|. +inline std::string +FuzzedDataProvider::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::string of length from 0 to |remaining_bytes_|. +inline std::string FuzzedDataProvider::ConsumeRandomLengthString() { + return ConsumeRandomLengthString(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. +inline std::string FuzzedDataProvider::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 FuzzedDataProvider::ConsumeIntegral() { + return ConsumeIntegralInRange(std::numeric_limits::min(), + std::numeric_limits::max()); +} + +// 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 FuzzedDataProvider::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 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 FuzzedDataProvider::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 FuzzedDataProvider::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(); +} + +// Returns a floating point number in the range [0.0, 1.0]. If there's no +// input data left, always returns 0. +template T FuzzedDataProvider::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; +} + +// Reads one byte and returns a bool, or false when no data remains. +inline bool FuzzedDataProvider::ConsumeBool() { + return 1 & ConsumeIntegral(); +} + +// 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 FuzzedDataProvider::ConsumeEnum() { + static_assert(std::is_enum::value, "|T| must be an enum type."); + return static_cast( + ConsumeIntegralInRange(0, static_cast(T::kMaxValue))); +} + +// Returns a copy of the value selected from the given fixed-size |array|. +template +T FuzzedDataProvider::PickValueInArray(const T (&array)[size]) { + static_assert(size > 0, "The array must be non empty."); + return array[ConsumeIntegralInRange(0, size - 1)]; +} + +template +T FuzzedDataProvider::PickValueInArray(const std::array &array) { + static_assert(size > 0, "The array must be non empty."); + return array[ConsumeIntegralInRange(0, size - 1)]; +} + +template +T FuzzedDataProvider::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)); +} + +// Writes |num_bytes| of input data to the given destination pointer. If there +// is not enough data left, writes all remaining bytes. Return value is the +// number of bytes written. +// In general, it's better to avoid using this function, but it may be useful +// in cases when it's necessary to fill a certain buffer or object with +// fuzzing data. +inline size_t FuzzedDataProvider::ConsumeData(void *destination, + size_t num_bytes) { + num_bytes = std::min(num_bytes, remaining_bytes_); + CopyAndAdvance(destination, num_bytes); + return num_bytes; +} + +// Private methods. +inline void FuzzedDataProvider::CopyAndAdvance(void *destination, + size_t num_bytes) { + std::memcpy(destination, data_ptr_, num_bytes); + Advance(num_bytes); +} + +inline void FuzzedDataProvider::Advance(size_t num_bytes) { + if (num_bytes > remaining_bytes_) + abort(); + + data_ptr_ += num_bytes; + remaining_bytes_ -= num_bytes; +} + +template +std::vector FuzzedDataProvider::ConsumeBytes(size_t size, size_t num_bytes) { + 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 != 0) + abort(); + return result; + } + + CopyAndAdvance(result.data(), num_bytes); + + // 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 FuzzedDataProvider::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 signed 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); + } +} + +#endif // LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/re2_fuzzer.cc src/re2/fuzzing/re2_fuzzer.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/re2_fuzzer.cc 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/fuzzing/re2_fuzzer.cc 2023-02-20 19:50:47.000000000 +0100 @@ -0,0 +1,283 @@ +// Copyright 2016 The RE2 Authors. All Rights Reserved. +// 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 "re2/filtered_re2.h" +#include "re2/re2.h" +#include "re2/regexp.h" +#include "re2/set.h" +#include "re2/walker-inl.h" + +using re2::StringPiece; + +// NOT static, NOT signed. +uint8_t dummy = 0; + +// 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, + RE2::Anchor anchor, 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; + + // Iterate just once when fuzzing. Otherwise, we easily get bogged down + // and coverage is unlikely to improve despite significant expense. + RE2::FUZZING_ONLY_set_maximum_global_replace_count(1); + // 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. + if (SubstringWalker().Walk(re.Regexp(), -1) > 9) + return; + + // Don't waste time fuzzing high-size programs. + // They can cause bug reports due to fuzzer timeouts. + int size = re.ProgramSize(); + if (size > 9999) + return; + int rsize = re.ReverseProgramSize(); + if (rsize > 9999) + return; + + // Don't waste time fuzzing high-fanout programs. + // They can cause bug reports due to fuzzer timeouts. + std::vector histogram; + int fanout = re.ProgramFanout(&histogram); + if (fanout > 9) + return; + int rfanout = re.ReverseProgramFanout(&histogram); + if (rfanout > 9) + return; + + if (re.NumberOfCapturingGroups() == 0) { + // Avoid early return due to too many arguments. + StringPiece sp = text; + RE2::FullMatch(sp, re); + RE2::PartialMatch(sp, re); + RE2::Consume(&sp, re); + sp = text; // Reset. + RE2::FindAndConsume(&sp, re); + } else { + // Okay, we have at least one capturing group... + // Try conversion for variously typed arguments. + StringPiece sp = text; + short s; + RE2::FullMatch(sp, re, &s); + long l; + RE2::PartialMatch(sp, re, &l); + float f; + RE2::Consume(&sp, re, &f); + sp = text; // Reset. + double d; + RE2::FindAndConsume(&sp, re, &d); + } + + std::string s = std::string(text); + RE2::Replace(&s, re, ""); + s = std::string(text); // Reset. + RE2::GlobalReplace(&s, re, ""); + + std::string min, max; + re.PossibleMatchRange(&min, &max, /*maxlen=*/9); + + // Exercise some other API functionality. + dummy += re.NamedCapturingGroups().size(); + dummy += re.CapturingGroupNames().size(); + dummy += RE2::QuoteMeta(pattern).size(); + + RE2::Set set(options, anchor); + int index = set.Add(pattern, /*error=*/NULL); // -1 on error + if (index != -1 && set.Compile()) { + std::vector matches; + set.Match(text, &matches); + } + + re2::FilteredRE2 filter; + index = -1; // not clobbered on error + filter.Add(pattern, options, &index); + if (index != -1) { + std::vector atoms; + filter.Compile(&atoms); + // Pretend that all atoms match, which + // triggers the AND-OR tree maximally. + std::vector matched_atoms; + matched_atoms.reserve(atoms.size()); + for (size_t i = 0; i < atoms.size(); ++i) + matched_atoms.push_back(static_cast(i)); + std::vector matches; + filter.AllMatches(text, matched_atoms, &matches); + } +} + +// Entry point for libFuzzer. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // 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; + + 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_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()); + + // ConsumeEnum() would require RE2::Anchor to specify + // kMaxValue, so just use PickValueInArray() instead. + RE2::Anchor anchor = fdp.PickValueInArray({ + RE2::UNANCHORED, + RE2::ANCHOR_START, + RE2::ANCHOR_BOTH, + }); + + std::string pattern = fdp.ConsumeRandomLengthString(999); + std::string text = fdp.ConsumeRandomLengthString(999); + + TestOneInput(pattern, options, anchor, text); + return 0; +} diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_perl_groups.pl src/re2/make_perl_groups.pl --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_perl_groups.pl 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_perl_groups.pl 2023-02-20 19:50:47.000000000 +0100 @@ -76,7 +76,7 @@ } 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_unicode_casefold.py src/re2/make_unicode_casefold.py --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_unicode_casefold.py 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_unicode_casefold.py 2023-02-20 19:50:47.000000000 +0100 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # coding=utf-8 # # Copyright 2008 The RE2 Authors. All Rights Reserved. diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_unicode_groups.py src/re2/make_unicode_groups.py --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_unicode_groups.py 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/make_unicode_groups.py 2023-02-20 19:50:47.000000000 +0100 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # Copyright 2008 The RE2 Authors. All Rights Reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/nfa.cc src/re2/nfa.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/nfa.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/nfa.cc 2023-02-20 19:50:47.000000000 +0100 @@ -456,14 +456,14 @@ 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()) { @@ -600,7 +600,7 @@ // 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); @@ -646,7 +646,7 @@ } 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/onepass.cc src/re2/onepass.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/onepass.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/onepass.cc 2023-02-20 19:50:47.000000000 +0100 @@ -237,9 +237,9 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/parse.cc src/re2/parse.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/parse.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/parse.cc 2023-02-20 19:50:47.000000000 +0100 @@ -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 @@ -568,7 +568,9 @@ 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; @@ -591,7 +593,7 @@ 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; @@ -1407,13 +1409,15 @@ } } - 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; @@ -1585,8 +1589,6 @@ // return true; } - LOG(DFATAL) << "Not reached in ParseEscape."; - BadEscape: // Unrecognized escape sequence. status->set_code(kRegexpBadEscape); @@ -2011,19 +2013,34 @@ 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; } @@ -2040,8 +2057,8 @@ // Caller is supposed to check this. if (!(flags_ & PerlX) || t.size() < 2 || t[0] != '(' || t[1] != '?') { - LOG(DFATAL) << "Bad call to ParseState::ParsePerlFlags"; status_->set_code(kRegexpInternalError); + LOG(DFATAL) << "Bad call to ParseState::ParsePerlFlags"; return false; } diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/perl_groups.cc src/re2/perl_groups.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/perl_groups.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/perl_groups.cc 2023-02-20 19:50:47.000000000 +0100 @@ -20,12 +20,12 @@ { 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 @@ { 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter.cc src/re2/prefilter.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter.cc 2023-02-20 19:50:47.000000000 +0100 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "util/util.h" @@ -21,9 +22,6 @@ static const bool ExtraDebug = false; -typedef std::set::iterator SSIter; -typedef std::set::const_iterator ConstSSIter; - // Initializes a Prefilter, allocating subs_ as necessary. Prefilter::Prefilter(Op op) { op_ = op; @@ -140,7 +138,7 @@ return AndOr(OR, a, b); } -static void SimplifyStringSet(std::set* ss) { +void Prefilter::SimplifyStringSet(SSet* ss) { // Now make sure that the strings aren't redundant. For example, if // we know "ab" is a required string, then it doesn't help at all to // know that "abc" is also a required string, so delete "abc". This @@ -149,13 +147,19 @@ // candidate for match, so further matching "abc" is redundant. // Note that we must ignore "" because find() would find it at the // start of everything and thus we would end up erasing everything. - for (SSIter i = ss->begin(); i != ss->end(); ++i) { - if (i->empty()) - continue; + // + // The SSet sorts strings by length, then lexicographically. Note that + // smaller strings appear first and all strings must be unique. These + // observations let us skip string comparisons when possible. + SSIter i = ss->begin(); + if (i != ss->end() && i->empty()) { + ++i; + } + for (; i != ss->end(); ++i) { SSIter j = i; ++j; while (j != ss->end()) { - if (j->find(*i) != std::string::npos) { + if (j->size() > i->size() && j->find(*i) != std::string::npos) { j = ss->erase(j); continue; } @@ -164,7 +168,7 @@ } } -Prefilter* Prefilter::OrStrings(std::set* ss) { +Prefilter* Prefilter::OrStrings(SSet* ss) { Prefilter* or_prefilter = new Prefilter(NONE); SimplifyStringSet(ss); for (SSIter i = ss->begin(); i != ss->end(); ++i) @@ -226,14 +230,14 @@ // Caller takes ownership of the Prefilter. Prefilter* TakeMatch(); - std::set& exact() { return exact_; } + SSet& exact() { return exact_; } bool is_exact() const { return is_exact_; } class Walker; private: - std::set exact_; + SSet exact_; // When is_exact_ is true, the strings that match // are placed in exact_. When it is no longer an exact @@ -286,18 +290,7 @@ return ""; } -// Add the strings from src to dst. -static void CopyIn(const std::set& src, - std::set* dst) { - for (ConstSSIter i = src.begin(); i != src.end(); ++i) - dst->insert(*i); -} - -// Add the cross-product of a and b to dst. -// (For each string i in a and j in b, add i+j.) -static void CrossProduct(const std::set& a, - const std::set& b, - std::set* dst) { +void Prefilter::CrossProduct(const SSet& a, const SSet& b, SSet* dst) { for (ConstSSIter i = a.begin(); i != a.end(); ++i) for (ConstSSIter j = b.begin(); j != b.end(); ++j) dst->insert(*i + *j); @@ -343,8 +336,14 @@ Info *ab = new Info(); if (a->is_exact_ && b->is_exact_) { - CopyIn(a->exact_, &ab->exact_); - CopyIn(b->exact_, &ab->exact_); + // Avoid string copies by moving the larger exact_ set into + // ab directly, then merge in the smaller set. + if (a->exact_.size() < b->exact_.size()) { + using std::swap; + swap(a, b); + } + ab->exact_ = std::move(a->exact_); + ab->exact_.insert(b->exact_.begin(), b->exact_.end()); ab->is_exact_ = true; } else { // Either a or b has is_exact_ = false. If the other @@ -532,8 +531,8 @@ switch (re->op()) { default: case kRegexpRepeat: - LOG(DFATAL) << "Bad regexp op " << re->op(); info = EmptyString(); + LOG(DFATAL) << "Bad regexp op " << re->op(); break; case kRegexpNoMatch: diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter.h src/re2/prefilter.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter.h 2023-02-20 19:50:47.000000000 +0100 @@ -60,8 +60,21 @@ std::string DebugString() const; private: + // A comparator used to store exact strings. We compare by length, + // then lexicographically. This ordering makes it easier to reduce the + // set of strings in SimplifyStringSet. + struct LengthThenLex { + bool operator()(const std::string& a, const std::string& b) const { + return (a.size() < b.size()) || (a.size() == b.size() && a < b); + } + }; + class Info; + using SSet = std::set; + using SSIter = SSet::iterator; + using ConstSSIter = SSet::const_iterator; + // Combines two prefilters together to create an AND. The passed // Prefilters will be part of the returned Prefilter or deleted. static Prefilter* And(Prefilter* a, Prefilter* b); @@ -77,12 +90,21 @@ static Prefilter* FromString(const std::string& str); - static Prefilter* OrStrings(std::set* ss); + static Prefilter* OrStrings(SSet* ss); static Info* BuildInfo(Regexp* re); Prefilter* Simplify(); + // Removes redundant strings from the set. A string is redundant if + // any of the other strings appear as a substring. The empty string + // is a special case, which is ignored. + static void SimplifyStringSet(SSet* ss); + + // Adds the cross-product of a and b to dst. + // (For each string i in a and j in b, add i+j.) + static void CrossProduct(const SSet& a, const SSet& b, SSet* dst); + // Kind of Prefilter. Op op_; diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter_tree.cc src/re2/prefilter_tree.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter_tree.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter_tree.cc 2023-02-20 19:50:47.000000000 +0100 @@ -6,9 +6,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -36,9 +36,6 @@ PrefilterTree::~PrefilterTree() { for (size_t i = 0; i < prefilter_vec_.size(); i++) delete prefilter_vec_[i]; - - for (size_t i = 0; i < entries_.size(); i++) - delete entries_[i].parents; } void PrefilterTree::Add(Prefilter* prefilter) { @@ -67,40 +64,8 @@ compiled_ = true; - // TODO(junyer): Use std::unordered_set instead? NodeMap nodes; AssignUniqueIds(&nodes, atom_vec); - - // Identify nodes that are too common among prefilters and are - // triggering too many parents. Then get rid of them if possible. - // Note that getting rid of a prefilter node simply means they are - // no longer necessary for their parent to trigger; that is, we do - // not miss out on any regexps triggering by getting rid of a - // prefilter node. - for (size_t i = 0; i < entries_.size(); i++) { - StdIntMap* parents = entries_[i].parents; - if (parents->size() > 8) { - // This one triggers too many things. If all the parents are AND - // nodes and have other things guarding them, then get rid of - // this trigger. TODO(vsri): Adjust the threshold appropriately, - // make it a function of total number of nodes? - bool have_other_guard = true; - for (StdIntMap::iterator it = parents->begin(); - it != parents->end(); ++it) { - have_other_guard = have_other_guard && - (entries_[it->first].propagate_up_at_count > 1); - } - - if (have_other_guard) { - for (StdIntMap::iterator it = parents->begin(); - it != parents->end(); ++it) - entries_[it->first].propagate_up_at_count -= 1; - - parents->clear(); // Forget the parents - } - } - } - if (ExtraDebug) PrintDebugInfo(&nodes); } @@ -217,65 +182,42 @@ node->set_unique_id(canonical->unique_id()); } } - entries_.resize(nodes->size()); - - // Create parent StdIntMap for the entries. - for (int i = static_cast(v.size()) - 1; i >= 0; i--) { - Prefilter* prefilter = v[i]; - if (prefilter == NULL) - continue; - - if (CanonicalNode(nodes, prefilter) != prefilter) - continue; - - Entry* entry = &entries_[prefilter->unique_id()]; - entry->parents = new StdIntMap(); - } + entries_.resize(unique_id); // Fill the entries. for (int i = static_cast(v.size()) - 1; i >= 0; i--) { Prefilter* prefilter = v[i]; if (prefilter == NULL) continue; - if (CanonicalNode(nodes, prefilter) != prefilter) continue; - - Entry* entry = &entries_[prefilter->unique_id()]; - + int id = prefilter->unique_id(); switch (prefilter->op()) { default: - case Prefilter::ALL: LOG(DFATAL) << "Unexpected op: " << prefilter->op(); return; case Prefilter::ATOM: - entry->propagate_up_at_count = 1; + entries_[id].propagate_up_at_count = 1; break; case Prefilter::OR: case Prefilter::AND: { - std::set uniq_child; + // For each child, we append our id to the child's list of + // parent ids... unless we happen to have done so already. + // The number of appends is the number of unique children, + // which allows correct upward propagation from AND nodes. + int up_count = 0; for (size_t j = 0; j < prefilter->subs()->size(); j++) { - Prefilter* child = (*prefilter->subs())[j]; - Prefilter* canonical = CanonicalNode(nodes, child); - if (canonical == NULL) { - LOG(DFATAL) << "Null canonical node"; - return; - } - int child_id = canonical->unique_id(); - uniq_child.insert(child_id); - // To the child, we want to add to parent indices. - Entry* child_entry = &entries_[child_id]; - if (child_entry->parents->find(prefilter->unique_id()) == - child_entry->parents->end()) { - (*child_entry->parents)[prefilter->unique_id()] = 1; + int child_id = (*prefilter->subs())[j]->unique_id(); + std::vector& parents = entries_[child_id].parents; + if (parents.empty() || parents.back() != id) { + parents.push_back(id); + up_count++; } } - entry->propagate_up_at_count = prefilter->op() == Prefilter::AND - ? static_cast(uniq_child.size()) - : 1; - + entries_[id].propagate_up_at_count = + prefilter->op() == Prefilter::AND ? up_count : 1; break; } } @@ -290,6 +232,52 @@ Entry* entry = &entries_[id]; entry->regexps.push_back(static_cast(i)); } + + // Lastly, using probability-based heuristics, we identify nodes + // that trigger too many parents and then we try to prune edges. + // We use logarithms below to avoid the likelihood of underflow. + double log_num_regexps = std::log(prefilter_vec_.size() - unfiltered_.size()); + // Hoisted this above the loop so that we don't thrash the heap. + std::vector> entries_by_num_edges; + for (int i = static_cast(v.size()) - 1; i >= 0; i--) { + Prefilter* prefilter = v[i]; + // Pruning applies only to AND nodes because it "just" reduces + // precision; applied to OR nodes, it would break correctness. + if (prefilter == NULL || prefilter->op() != Prefilter::AND) + continue; + if (CanonicalNode(nodes, prefilter) != prefilter) + continue; + int id = prefilter->unique_id(); + + // Sort the current node's children by the numbers of parents. + entries_by_num_edges.clear(); + for (size_t j = 0; j < prefilter->subs()->size(); j++) { + int child_id = (*prefilter->subs())[j]->unique_id(); + const std::vector& parents = entries_[child_id].parents; + entries_by_num_edges.emplace_back(parents.size(), child_id); + } + std::stable_sort(entries_by_num_edges.begin(), entries_by_num_edges.end()); + + // A running estimate of how many regexps will be triggered by + // pruning the remaining children's edges to the current node. + // Our nominal target is one, so the threshold is log(1) == 0; + // pruning occurs iff the child has more than nine edges left. + double log_num_triggered = log_num_regexps; + for (const auto& pair : entries_by_num_edges) { + int child_id = pair.second; + std::vector& parents = entries_[child_id].parents; + if (log_num_triggered > 0.) { + log_num_triggered += std::log(parents.size()); + log_num_triggered -= log_num_regexps; + } else if (parents.size() > 9) { + auto it = std::find(parents.begin(), parents.end(), id); + if (it != parents.end()) { + parents.erase(it); + entries_[id].propagate_up_at_count--; + } + } + } + } } // Functions for triggering during search. @@ -336,10 +324,7 @@ regexps->set(entry.regexps[i], 1); int c; // Pass trigger up to parents. - for (StdIntMap::iterator it = entry.parents->begin(); - it != entry.parents->end(); - ++it) { - int j = it->first; + for (int j : entry.parents) { const Entry& parent = entries_[j]; // Delay until all the children have succeeded. if (parent.propagate_up_at_count > 1) { @@ -369,12 +354,12 @@ LOG(ERROR) << "#Unique Nodes: " << entries_.size(); for (size_t i = 0; i < entries_.size(); i++) { - StdIntMap* parents = entries_[i].parents; + const std::vector& parents = entries_[i].parents; const std::vector& regexps = entries_[i].regexps; LOG(ERROR) << "EntryId: " << i - << " N: " << parents->size() << " R: " << regexps.size(); - for (StdIntMap::iterator it = parents->begin(); it != parents->end(); ++it) - LOG(ERROR) << it->first; + << " N: " << parents.size() << " R: " << regexps.size(); + for (int parent : parents) + LOG(ERROR) << parent; } LOG(ERROR) << "Map:"; for (NodeMap::const_iterator iter = nodes->begin(); diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter_tree.h src/re2/prefilter_tree.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter_tree.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prefilter_tree.h 2023-02-20 19:50:47.000000000 +0100 @@ -59,7 +59,8 @@ private: typedef SparseArray IntMap; - typedef std::map StdIntMap; + // TODO(junyer): Use std::unordered_set instead? + // It should be trivial to get rid of the stringification... typedef std::map NodeMap; // Each unique node has a corresponding Entry that helps in @@ -77,7 +78,7 @@ // are two different nodes, but they share the atom 'def'. So when // 'def' matches, it triggers two parents, corresponding to the two // different OR nodes. - StdIntMap* parents; + std::vector parents; // When this node is ready to trigger the parent, what are the // regexps that are triggered. diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prog.cc src/re2/prog.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prog.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prog.cc 2023-02-20 19:50:47.000000000 +0100 @@ -115,10 +115,10 @@ start_unanchored_(0), size_(0), bytemap_range_(0), + prefix_foldcase_(false), prefix_size_(0), - prefix_front_(-1), - prefix_back_(-1), list_count_(0), + bit_state_text_max_size_(0), dfa_mem_(0), dfa_first_(NULL), dfa_longest_(NULL) { @@ -127,6 +127,8 @@ Prog::~Prog() { DeleteDFA(dfa_longest_); DeleteDFA(dfa_first_); + if (prefix_foldcase_) + delete[] prefix_dfa_; } typedef SparseSet Workq; @@ -509,7 +511,7 @@ builder.Build(bytemap_, &bytemap_range_); - if (0) { // For debugging, use trivial bytemap. + if ((0)) { // For debugging, use trivial bytemap. LOG(ERROR) << "Using trivial bytemap."; for (int i = 0; i < 256; i++) bytemap_[i] = static_cast(i); @@ -609,10 +611,13 @@ inst_count_[ip->opcode()]++; } - int total = 0; +#if !defined(NDEBUG) + // Address a `-Wunused-but-set-variable' warning from Clang 13.x. + size_t total = 0; for (int i = 0; i < kNumInst; i++) total += inst_count_[i]; - DCHECK_EQ(total, static_cast(flat.size())); + CHECK_EQ(total, flat.size()); +#endif // Remap start_unanchored and start. if (start_unanchored() == 0) { @@ -639,6 +644,11 @@ 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, @@ -916,6 +926,183 @@ } } +// 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) { @@ -958,7 +1145,7 @@ 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_); - while (fp != endfp) { + 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); @@ -970,7 +1157,7 @@ const int fb_ctz = FindLSBSet(fb_movemask); return reinterpret_cast(fp-1) + fb_ctz; } - } + } while (fp != endfp); data = fp; size = size%sizeof(__m256i); } diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prog.h src/re2/prog.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prog.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/prog.h 2023-02-20 19:50:47.000000000 +0100 @@ -207,6 +207,7 @@ int list_count() { return list_count_; } int inst_count(InstOp op) { return inst_count_[op]; } uint16_t* list_heads() { return list_heads_.data(); } + size_t bit_state_text_max_size() { return bit_state_text_max_size_; } int64_t dfa_mem() { return dfa_mem_; } void set_dfa_mem(int64_t dfa_mem) { dfa_mem_ = dfa_mem; } bool anchor_start() { return anchor_start_; } @@ -220,11 +221,23 @@ // 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_GE(prefix_size_, 1); - return prefix_size_ == 1 ? memchr(data, prefix_front_, size) - : PrefixAccel_FrontAndBack(data, 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); + // 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); @@ -298,10 +311,6 @@ // 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(); @@ -352,7 +361,6 @@ // Returns true on success, false on error. bool PossibleMatchRange(std::string* min, std::string* max, int maxlen); - // EXPERIMENTAL! SUBJECT TO CHANGE! // Outputs the program fanout into the given sparse array. void Fanout(SparseArray* fanout); @@ -390,6 +398,10 @@ // 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; @@ -406,14 +418,22 @@ int start_unanchored_; // unanchored entry point for program int size_; // number of instructions int bytemap_range_; // bytemap_[x] < bytemap_range_ - size_t prefix_size_; // size of prefix (0 if no prefix) - int prefix_front_; // first byte of prefix (-1 if no prefix) - int prefix_back_; // last byte of prefix (-1 if no 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 + 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 @@ -431,6 +451,17 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/re2.cc src/re2/re2.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/re2.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/re2.cc 2023-02-20 19:50:47.000000000 +0100 @@ -36,6 +36,13 @@ namespace re2 { +// Controls the maximum count permitted by GlobalReplace(); -1 is unlimited. +static int maximum_global_replace_count = -1; + +void RE2::FUZZING_ONLY_set_maximum_global_replace_count(int i) { + maximum_global_replace_count = i; +} + // Maximum number of args we can set static const int kMaxArgs = 16; static const int kVecSize = 1+kMaxArgs; @@ -43,11 +50,11 @@ const int RE2::Options::kDefaultMaxMem; // initialized in re2.h RE2::Options::Options(RE2::CannedOptions opt) - : encoding_(opt == RE2::Latin1 ? EncodingLatin1 : EncodingUTF8), + : max_mem_(kDefaultMaxMem), + encoding_(opt == RE2::Latin1 ? EncodingLatin1 : EncodingUTF8), posix_syntax_(opt == RE2::POSIX), longest_match_(opt == RE2::POSIX), log_errors_(opt != RE2::Quiet), - max_mem_(kDefaultMaxMem), literal_(false), never_nl_(false), dot_nl_(false), @@ -58,11 +65,30 @@ one_line_(false) { } -// static empty objects for use as const references. -// To avoid global constructors, allocated in RE2::Init(). -static const std::string* empty_string; -static const std::map* empty_named_groups; -static const std::map* empty_group_names; +// Empty objects for use as const references. +// Statically allocating the storage and then +// lazily constructing the objects (in a once +// in RE2::Init()) avoids global constructors +// and the false positives (thanks, Valgrind) +// about memory leaks at program termination. +struct EmptyStorage { + std::string empty_string; + std::map empty_named_groups; + std::map empty_group_names; +}; +alignas(EmptyStorage) static char empty_storage[sizeof(EmptyStorage)]; + +static inline std::string* empty_string() { + return &reinterpret_cast(empty_storage)->empty_string; +} + +static inline std::map* empty_named_groups() { + return &reinterpret_cast(empty_storage)->empty_named_groups; +} + +static inline std::map* empty_group_names() { + return &reinterpret_cast(empty_storage)->empty_group_names; +} // Converts from Regexp error code to RE2 error code. // Maybe some day they will diverge. In any event, this @@ -173,23 +199,23 @@ void RE2::Init(const StringPiece& pattern, const Options& options) { static std::once_flag empty_once; std::call_once(empty_once, []() { - empty_string = new std::string; - empty_named_groups = new std::map; - empty_group_names = new std::map; + (void) new (empty_storage) EmptyStorage; }); - pattern_.assign(pattern.data(), pattern.size()); + pattern_ = new std::string(pattern); 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; + error_ = empty_string(); + error_arg_ = empty_string(); + num_captures_ = -1; + error_code_ = NoError; + longest_match_ = options_.longest_match(); is_one_pass_ = false; + prefix_foldcase_ = false; + prefix_.clear(); + prog_ = NULL; rprog_ = NULL; named_groups_ = NULL; @@ -197,25 +223,29 @@ RegexpStatus status; entire_regexp_ = Regexp::Parse( - pattern_, + *pattern_, static_cast(options_.ParseFlags()), &status); if (entire_regexp_ == NULL) { if (options_.log_errors()) { - LOG(ERROR) << "Error parsing '" << trunc(pattern_) << "': " + LOG(ERROR) << "Error parsing '" << trunc(*pattern_) << "': " << status.Text(); } error_ = new std::string(status.Text()); error_code_ = RegexpErrorToRE2(status.code()); - error_arg_ = std::string(status.error_arg()); + error_arg_ = new std::string(status.error_arg()); return; } + bool foldcase; re2::Regexp* suffix; - if (entire_regexp_->RequiredPrefix(&prefix_, &prefix_foldcase_, &suffix)) + if (entire_regexp_->RequiredPrefix(&prefix_, &foldcase, &suffix)) { + prefix_foldcase_ = foldcase; suffix_regexp_ = suffix; - else + } + else { suffix_regexp_ = entire_regexp_->Incref(); + } // Two thirds of the memory goes to the forward Prog, // one third to the reverse prog, because the forward @@ -223,7 +253,7 @@ prog_ = suffix_regexp_->CompileToProg(options_.max_mem()*2/3); if (prog_ == NULL) { if (options_.log_errors()) - LOG(ERROR) << "Error compiling '" << trunc(pattern_) << "'"; + LOG(ERROR) << "Error compiling '" << trunc(*pattern_) << "'"; error_ = new std::string("pattern too large - compile failed"); error_code_ = RE2::ErrorPatternTooLarge; return; @@ -249,7 +279,8 @@ re->suffix_regexp_->CompileToReverseProg(re->options_.max_mem() / 3); if (re->rprog_ == NULL) { if (re->options_.log_errors()) - LOG(ERROR) << "Error reverse compiling '" << trunc(re->pattern_) << "'"; + LOG(ERROR) << "Error reverse compiling '" << trunc(*re->pattern_) + << "'"; // 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 @@ -261,18 +292,21 @@ } RE2::~RE2() { + if (group_names_ != empty_group_names()) + delete group_names_; + if (named_groups_ != empty_named_groups()) + delete named_groups_; + delete rprog_; + delete prog_; + if (error_arg_ != empty_string()) + delete error_arg_; + if (error_ != empty_string()) + delete error_; if (suffix_regexp_) suffix_regexp_->Decref(); if (entire_regexp_) entire_regexp_->Decref(); - delete prog_; - delete rprog_; - if (error_ != empty_string) - delete error_; - if (named_groups_ != NULL && named_groups_ != empty_named_groups) - delete named_groups_; - if (group_names_ != NULL && group_names_ != empty_group_names) - delete group_names_; + delete pattern_; } int RE2::ProgramSize() const { @@ -352,7 +386,7 @@ if (re->suffix_regexp_ != NULL) re->named_groups_ = re->suffix_regexp_->NamedCaptures(); if (re->named_groups_ == NULL) - re->named_groups_ = empty_named_groups; + re->named_groups_ = empty_named_groups(); }, this); return *named_groups_; } @@ -363,7 +397,7 @@ if (re->suffix_regexp_ != NULL) re->group_names_ = re->suffix_regexp_->CaptureNames(); if (re->group_names_ == NULL) - re->group_names_ = empty_group_names; + re->group_names_ = empty_group_names(); }, this); return *group_names_; } @@ -439,13 +473,10 @@ const char* lastend = NULL; std::string out; int count = 0; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - // Iterate just once when fuzzing. Otherwise, we easily get bogged down - // and coverage is unlikely to improve despite significant expense. - while (p == str->data()) { -#else while (p <= ep) { -#endif + if (maximum_global_replace_count != -1 && + count >= maximum_global_replace_count) + break; if (!re.Match(*str, static_cast(p - str->data()), str->size(), UNANCHORED, vec, nvec)) break; @@ -686,19 +717,12 @@ } Prog::Anchor anchor = Prog::kUnanchored; - Prog::MatchKind kind = Prog::kFirstMatch; - if (options_.longest_match()) - kind = Prog::kLongestMatch; - - 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) + Prog::MatchKind kind = + longest_match_ ? Prog::kLongestMatch : Prog::kFirstMatch; + + 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; @@ -726,7 +750,7 @@ if (dfa_failed) { if (options_.log_errors()) LOG(ERROR) << "DFA out of memory: " - << "pattern length " << pattern_.size() << ", " + << "pattern length " << pattern_->size() << ", " << "program size " << prog->size() << ", " << "list count " << prog->list_count() << ", " << "bytemap range " << prog->bytemap_range(); @@ -746,7 +770,7 @@ if (dfa_failed) { if (options_.log_errors()) LOG(ERROR) << "DFA out of memory: " - << "pattern length " << pattern_.size() << ", " + << "pattern length " << pattern_->size() << ", " << "program size " << prog_->size() << ", " << "list count " << prog_->list_count() << ", " << "bytemap range " << prog_->bytemap_range(); @@ -772,7 +796,7 @@ if (dfa_failed) { if (options_.log_errors()) LOG(ERROR) << "DFA out of memory: " - << "pattern length " << pattern_.size() << ", " + << "pattern length " << pattern_->size() << ", " << "program size " << prog->size() << ", " << "list count " << prog->list_count() << ", " << "bytemap range " << prog->bytemap_range(); @@ -801,11 +825,12 @@ // 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; } @@ -814,7 +839,7 @@ if (dfa_failed) { if (options_.log_errors()) LOG(ERROR) << "DFA out of memory: " - << "pattern length " << pattern_.size() << ", " + << "pattern length " << pattern_->size() << ", " << "program size " << prog_->size() << ", " << "list count " << prog_->list_count() << ", " << "bytemap range " << prog_->bytemap_range(); @@ -852,7 +877,7 @@ 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()) @@ -920,7 +945,7 @@ } 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 @@ -1040,41 +1065,49 @@ /***** 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; } @@ -1138,10 +1171,40 @@ 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); @@ -1151,14 +1214,12 @@ 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); @@ -1174,62 +1235,52 @@ 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); @@ -1239,14 +1290,12 @@ 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); @@ -1261,68 +1310,11 @@ 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; -} - -bool RE2::Arg::parse_double(const char* str, size_t n, void* dest) { - return parse_double_float(str, n, false, dest); -} - -bool RE2::Arg::parse_float(const char* str, size_t n, void* dest) { - return parse_double_float(str, n, true, dest); -} - -#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); \ - } - -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_INTEGER_PARSER +} // namespace re2_internal namespace hooks { diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/re2.h src/re2/re2.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/re2.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/re2.h 2023-02-20 19:50:47.000000000 +0100 @@ -66,17 +66,17 @@ // CHECK(RE2::FullMatch(latin1_string, RE2(latin1_pattern, RE2::Latin1))); // // ----------------------------------------------------------------------- -// MATCHING WITH SUBSTRING EXTRACTION: +// SUBMATCH EXTRACTION: // -// You can supply extra pointer arguments to extract matched substrings. +// You can supply extra pointer arguments to extract submatches. // On match failure, none of the pointees will have been modified. -// On match success, the substrings will be converted (as necessary) and +// On match success, the submatches will be converted (as necessary) and // their values will be assigned to their pointees until all conversions // have succeeded or one conversion has failed. // On conversion failure, the pointees will be in an indeterminate state // because the caller has no way of knowing which conversion failed. // However, conversion cannot fail for types like string and StringPiece -// that do not inspect the substring contents. Hence, in the common case +// that do not inspect the submatch contents. Hence, in the common case // where all of the pointees are of such types, failure is always due to // match failure and thus none of the pointees will have been modified. // @@ -100,10 +100,10 @@ // Example: integer overflow causes failure // CHECK(!RE2::FullMatch("ruby:1234567891234", "\\w+:(\\d+)", &i)); // -// NOTE(rsc): Asking for substrings slows successful matches quite a bit. +// NOTE(rsc): Asking for submatches slows successful matches quite a bit. // This may get a little faster in the future, but right now is slower // than PCRE. On the other hand, failed matches run *very* fast (faster -// than PCRE), as do matches without substring extraction. +// than PCRE), as do matches without submatch extraction. // // ----------------------------------------------------------------------- // PARTIAL MATCHES @@ -208,6 +208,7 @@ #include #include #include +#include #include #if defined(__APPLE__) @@ -273,21 +274,33 @@ // Need to have the const char* and const std::string& forms for implicit // conversions when passing string literals to FullMatch and PartialMatch. // Otherwise the StringPiece form would be sufficient. -#ifndef SWIG RE2(const char* pattern); RE2(const std::string& pattern); -#endif RE2(const StringPiece& pattern); RE2(const StringPiece& pattern, const Options& options); ~RE2(); + // Not copyable. + // RE2 objects are expensive. You should probably use std::shared_ptr + // instead. If you really must copy, RE2(first.pattern(), first.options()) + // effectively does so: it produces a second object that mimics the first. + RE2(const RE2&) = delete; + RE2& operator=(const RE2&) = delete; + // Not movable. + // RE2 objects are thread-safe and logically immutable. You should probably + // use std::unique_ptr instead. Otherwise, consider std::deque if + // direct emplacement into a container is desired. If you really must move, + // be prepared to submit a design document along with your feature request. + RE2(RE2&&) = delete; + RE2& operator=(RE2&&) = delete; + // Returns whether RE2 was created properly. bool ok() const { return error_code() == NoError; } // The string specification for this RE2. E.g. // RE2 re("ab*c?d+"); // re.pattern(); // "ab*c?d+" - const std::string& pattern() const { return pattern_; } + const std::string& pattern() const { return *pattern_; } // If RE2 could not be created properly, returns an error string. // Else returns the empty string. @@ -299,7 +312,7 @@ // If RE2 could not be created properly, returns the offending // portion of the regexp. - const std::string& error_arg() const { return error_arg_; } + const std::string& error_arg() const { return *error_arg_; } // Returns the program size, a very approximate measure of a regexp's "cost". // Larger numbers are more expensive than smaller numbers. @@ -332,7 +345,6 @@ static bool FindAndConsumeN(StringPiece* input, const RE2& re, const Arg* const args[], int n); -#ifndef SWIG private: template static inline bool Apply(F f, SP sp, const RE2& re) { @@ -438,7 +450,6 @@ static bool FindAndConsume(StringPiece* input, const RE2& re, A&&... a) { return Apply(FindAndConsumeN, input, re, Arg(std::forward(a))...); } -#endif // Replace the first match of "re" in "str" with "rewrite". // Within "rewrite", backslash-escaped digits (\1 to \9) can be @@ -580,7 +591,7 @@ // Replace(). E.g. if rewrite == "foo \\2,\\1", returns 2. static int MaxSubmatch(const StringPiece& rewrite); - // Append the "rewrite" string, with backslash subsitutions from "vec", + // Append the "rewrite" string, with backslash substitutions from "vec", // to string "out". // Returns true on success. This method can fail because of a malformed // rewrite string. CheckRewriteString guarantees that the rewrite will @@ -652,11 +663,11 @@ }; Options() : + max_mem_(kDefaultMaxMem), encoding_(EncodingUTF8), posix_syntax_(false), longest_match_(false), log_errors_(true), - max_mem_(kDefaultMaxMem), literal_(false), never_nl_(false), dot_nl_(false), @@ -669,6 +680,9 @@ /*implicit*/ Options(CannedOptions); + int64_t max_mem() const { return max_mem_; } + void set_max_mem(int64_t m) { max_mem_ = m; } + Encoding encoding() const { return encoding_; } void set_encoding(Encoding encoding) { encoding_ = encoding; } @@ -681,9 +695,6 @@ bool log_errors() const { return log_errors_; } void set_log_errors(bool b) { log_errors_ = b; } - int64_t max_mem() const { return max_mem_; } - void set_max_mem(int64_t m) { max_mem_ = m; } - bool literal() const { return literal_; } void set_literal(bool b) { literal_ = b; } @@ -715,11 +726,11 @@ int ParseFlags() const; private: + int64_t max_mem_; Encoding encoding_; bool posix_syntax_; bool longest_match_; bool log_errors_; - int64_t max_mem_; bool literal_; bool never_nl_; bool dot_nl_; @@ -734,32 +745,16 @@ 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); + + // Controls the maximum count permitted by GlobalReplace(); -1 is unlimited. + // FOR FUZZING ONLY. + static void FUZZING_ONLY_set_maximum_global_replace_count(int i); private: void Init(const StringPiece& pattern, const Options& options); @@ -772,18 +767,23 @@ re2::Prog* ReverseProg() const; - 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? + // First cache line is relatively cold fields. + const std::string* pattern_; // string regular expression + Options options_; // option flags + re2::Regexp* entire_regexp_; // parsed regular expression + re2::Regexp* suffix_regexp_; // parsed regular expression, prefix_ removed + const std::string* error_; // error indicator (or points to empty string) + const std::string* error_arg_; // fragment of regexp showing error (or ditto) + + // Second cache line is relatively hot fields. + // These are ordered oddly to pack everything. + int num_captures_; // number of capturing groups + ErrorCode error_code_ : 29; // error code (29 bits is more than enough) + bool longest_match_ : 1; // cached copy of options_.longest_match() + bool is_one_pass_ : 1; // can use prog_->SearchOnePass? + bool prefix_foldcase_ : 1; // prefix_ is ASCII case-insensitive + std::string prefix_; // required prefix (before suffix_regexp_) + re2::Prog* prog_; // compiled program for regexp // Reverse Prog for DFA execution only mutable re2::Prog* rprog_; @@ -795,139 +795,135 @@ mutable std::once_flag rprog_once_; mutable std::once_flag named_groups_once_; mutable std::once_flag group_names_once_; - - RE2(const RE2&) = delete; - RE2& operator=(const RE2&) = delete; }; /***** Implementation details *****/ -// Hex/Octal/Binary? +namespace re2_internal { -// 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); - } -}; +// 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) { } + template + Arg(T* ptr, Parser parser) : arg_(ptr), parser_(parser) {} - // Parse the data - bool Parse(const char* str, size_t n) const; + 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) + template + static bool DoParse3ary(const char* str, size_t n, void* dest) { + return re2_internal::Parse(str, n, reinterpret_cast(dest)); + } -#undef DECLARE_INTEGER_PARSER + template + static bool DoParse4ary(const char* str, size_t n, void* dest) { + return re2_internal::Parse(str, n, reinterpret_cast(dest), 10); + } -}; +#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 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) { } + void* arg_; + Parser parser_; +}; -inline bool RE2::Arg::Parse(const char* str, size_t n) const { - return (*parser_)(str, n, arg_); +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); + }); } -// 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); \ - } - -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. #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 6 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -978,7 +974,6 @@ void operator=(const LazyRE2&); // disallowed }; -#endif namespace hooks { @@ -986,8 +981,11 @@ // 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 +#if (defined(__APPLE__) && !(defined(TARGET_OS_OSX) && TARGET_OS_OSX)) || defined(__MINGW32__) #undef RE2_HAVE_THREAD_LOCAL #endif diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/regexp.cc src/re2/regexp.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/regexp.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/regexp.cc 2023-02-20 19:50:47.000000000 +0100 @@ -74,16 +74,27 @@ return false; } -// Lazily allocated. -static Mutex* ref_mutex; -static std::map* ref_map; +// Similar to EmptyStorage in re2.cc. +struct RefStorage { + Mutex ref_mutex; + std::map ref_map; +}; +alignas(RefStorage) static char ref_storage[sizeof(RefStorage)]; + +static inline Mutex* ref_mutex() { + return &reinterpret_cast(ref_storage)->ref_mutex; +} + +static inline std::map* ref_map() { + return &reinterpret_cast(ref_storage)->ref_map; +} int Regexp::Ref() { if (ref_ < kMaxRef) return ref_; - MutexLock l(ref_mutex); - return (*ref_map)[this]; + MutexLock l(ref_mutex()); + return (*ref_map())[this]; } // Increments reference count, returns object as convenience. @@ -91,18 +102,17 @@ if (ref_ >= kMaxRef-1) { static std::once_flag ref_once; std::call_once(ref_once, []() { - ref_mutex = new Mutex; - ref_map = new std::map; + (void) new (ref_storage) RefStorage; }); // Store ref count in overflow map. - MutexLock l(ref_mutex); + MutexLock l(ref_mutex()); if (ref_ == kMaxRef) { // already overflowed - (*ref_map)[this]++; + (*ref_map())[this]++; } else { // overflowing now - (*ref_map)[this] = kMaxRef; + (*ref_map())[this] = kMaxRef; ref_ = kMaxRef; } return this; @@ -116,13 +126,13 @@ void Regexp::Decref() { if (ref_ == kMaxRef) { // Ref count is stored in overflow map. - MutexLock l(ref_mutex); - int r = (*ref_map)[this] - 1; + MutexLock l(ref_mutex()); + int r = (*ref_map())[this] - 1; if (r < kMaxRef) { ref_ = static_cast(r); - ref_map->erase(this); + ref_map()->erase(this); } else { - (*ref_map)[this] = r; + (*ref_map())[this] = r; } return; } @@ -585,8 +595,7 @@ // Record first occurrence of each name. // (The rule is that if you have the same name // multiple times, only the leftmost one counts.) - if (map_->find(*re->name()) == map_->end()) - (*map_)[*re->name()] = re->cap(); + map_->insert({*re->name(), re->cap()}); } return ignored; } @@ -722,8 +731,14 @@ *foldcase = false; // No need for a walker: the regexp must either begin with or be - // a literal char or string. + // 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; @@ -913,7 +928,7 @@ // 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); @@ -930,7 +945,7 @@ } 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; @@ -949,7 +964,7 @@ return cc; } -bool CharClass::Contains(Rune r) { +bool CharClass::Contains(Rune r) const { RuneRange* rr = ranges_; int n = nranges_; while (n > 0) { @@ -967,7 +982,7 @@ } 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/regexp.h src/re2/regexp.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/regexp.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/regexp.h 2023-02-20 19:50:47.000000000 +0100 @@ -86,6 +86,7 @@ // form accessible to clients, so that client code can analyze the // parsed regular expressions. +#include #include #include #include @@ -253,13 +254,13 @@ 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; @@ -448,6 +449,10 @@ // 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/set.cc src/re2/set.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/set.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/set.cc 2023-02-20 19:50:47.000000000 +0100 @@ -128,11 +128,14 @@ bool RE2::Set::Match(const StringPiece& text, std::vector* v, ErrorInfo* error_info) const { if (!compiled_) { - LOG(DFATAL) << "RE2::Set::Match() called before compiling"; if (error_info != NULL) error_info->kind = kNotCompiled; + LOG(DFATAL) << "RE2::Set::Match() called before compiling"; return false; } +#ifdef RE2_HAVE_THREAD_LOCAL + hooks::context = NULL; +#endif bool dfa_failed = false; std::unique_ptr matches; if (v != NULL) { @@ -158,9 +161,9 @@ } if (v != NULL) { if (matches->empty()) { - LOG(DFATAL) << "RE2::Set::Match() matched, but no matches returned?!"; if (error_info != NULL) error_info->kind = kInconsistent; + LOG(DFATAL) << "RE2::Set::Match() matched, but no matches returned?!"; return false; } v->assign(matches->begin(), matches->end()); diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/simplify.cc src/re2/simplify.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/simplify.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/simplify.cc 2023-02-20 19:50:47.000000000 +0100 @@ -371,8 +371,8 @@ break; default: - LOG(DFATAL) << "DoCoalesce failed: r1->op() is " << r1->op(); nre->Decref(); + LOG(DFATAL) << "DoCoalesce failed: r1->op() is " << r1->op(); return; } @@ -432,8 +432,8 @@ } default: - LOG(DFATAL) << "DoCoalesce failed: r2->op() is " << r2->op(); nre->Decref(); + LOG(DFATAL) << "DoCoalesce failed: r2->op() is " << r2->op(); return; } diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/stringpiece.h src/re2/stringpiece.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/stringpiece.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/stringpiece.h 2023-02-20 19:50:47.000000000 +0100 @@ -19,18 +19,13 @@ // // Arghh! I wish C++ literals were "string". -// Doing this simplifies the logic below. -#ifndef __has_include -#define __has_include(x) 0 -#endif - #include #include #include #include #include #include -#if __has_include() && __cplusplus >= 201703L +#ifdef __cpp_lib_string_view #include #endif @@ -57,7 +52,7 @@ // expected. StringPiece() : data_(NULL), size_(0) {} -#if __has_include() && __cplusplus >= 201703L +#ifdef __cpp_lib_string_view StringPiece(const std::string_view& str) : data_(str.data()), size_(str.size()) {} #endif @@ -103,6 +98,14 @@ size_ = len; } +#ifdef __cpp_lib_string_view + // Converts to `std::basic_string_view`. + operator std::basic_string_view() const { + if (!data_) return {}; + return std::basic_string_view(data_, size_); + } +#endif + // Converts to `std::basic_string`. template explicit operator std::basic_string() const { diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/backtrack.cc src/re2/testing/backtrack.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/backtrack.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/backtrack.cc 2023-02-20 19:50:47.000000000 +0100 @@ -103,9 +103,9 @@ 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(); @@ -267,7 +267,7 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/charclass_test.cc src/re2/testing/charclass_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/charclass_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/charclass_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -85,7 +85,7 @@ { {-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 @@ delete cc; } -template +template bool CorrectCC(CharClass *cc, CCTest *t, const char *desc) { typename CharClass::iterator it = cc->begin(); int size = 0; diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/compile_test.cc src/re2/testing/compile_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/compile_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/compile_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -109,6 +109,20 @@ { "[[-`]", "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) { @@ -338,27 +352,37 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/dfa_test.cc src/re2/testing/dfa_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/dfa_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/dfa_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -143,7 +143,7 @@ // NFA implementation instead. (The DFA loses its speed advantage // if it can't get a good cache hit rate.) // Tell the DFA to trudge along instead. - 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; @@ -194,7 +194,7 @@ 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); } @@ -218,7 +218,7 @@ } 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; @@ -259,7 +259,7 @@ 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); } diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/exhaustive_tester.cc src/re2/testing/exhaustive_tester.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/exhaustive_tester.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/exhaustive_tester.cc 2023-02-20 19:50:47.000000000 +0100 @@ -67,8 +67,8 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/filtered_re2_test.cc src/re2/testing/filtered_re2_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/filtered_re2_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/filtered_re2_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -106,12 +106,13 @@ // substring in an OR are removed; that is, only the shortest // substring is kept. "SubstrAtomRemovesSuperStrInOr", { - "(abc123|abc|ghi789|abc1234).*[x-z]+", + "(abc123|abc|defxyz|ghi789|abc1234|xyz).*[x-z]+", "abcd..yyy..yyyzzz", "mnmnpp[a-z]+PPP" }, { "abc", "ghi789", + "xyz", "abcd", "yyy", "yyyzzz", diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/parse_test.cc src/re2/testing/parse_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/parse_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/parse_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -164,6 +164,7 @@ // Test named captures { "(?Pa)", "cap{name:lit{a}}" }, + { "(?P<中文>a)", "cap{中文:lit{a}}" }, // Case-folded literals { "[Aa]", "litfold{a}" }, diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/re2_arg_test.cc src/re2/testing/re2_arg_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/re2_arg_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/re2_arg_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -11,6 +11,7 @@ #include #include "util/test.h" +#include "util/logging.h" #include "re2/re2.h" namespace re2 { @@ -132,4 +133,28 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/re2_test.cc src/re2/testing/re2_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/re2_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/re2_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -485,37 +485,37 @@ 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]); - // 6 is the largest non-empty bucket and has 10 elements. + // 6 is the largest non-empty bucket and has 11 elements. ASSERT_EQ(6, re10.ProgramFanout(&histogram)); - ASSERT_EQ(10, histogram[6]); + ASSERT_EQ(11, histogram[6]); - // 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.ProgramFanout(&histogram)); - ASSERT_EQ(100, histogram[9]); + 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 1 element. + // 2 is the largest non-empty bucket and has 2 element. ASSERT_EQ(2, re1.ReverseProgramFanout(&histogram)); - ASSERT_EQ(1, 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 @@ -1641,4 +1641,19 @@ 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/regexp_benchmark.cc src/re2/testing/regexp_benchmark.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/regexp_benchmark.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/regexp_benchmark.cc 2023-02-20 19:50:47.000000000 +0100 @@ -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 @@ // 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 @@ #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 @@ 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: 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 @@ 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 @@ // 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 @@ // 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)); @@ -939,13 +954,54 @@ // regexp parsing and compiling once. This lets us measure // search time without the per-regexp overhead. +Prog* GetCachedProg(const char* regexp) { + static auto& mutex = *new Mutex; + MutexLock lock(&mutex); + static auto& cache = *new std::unordered_map; + 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(int64_t{1}<<31); - CHECK(prog); + Prog* prog = GetCachedProg(regexp); for (auto _ : state) { bool failed = false; CHECK_EQ(prog->SearchDFA(text, StringPiece(), anchor, Prog::kFirstMatch, @@ -953,63 +1009,45 @@ 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); @@ -1021,8 +1059,7 @@ 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); @@ -1115,67 +1152,46 @@ 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)); @@ -1184,8 +1200,7 @@ 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)); @@ -1262,67 +1277,46 @@ 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)); @@ -1331,8 +1325,7 @@ 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)); @@ -1341,8 +1334,7 @@ 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)); @@ -1351,8 +1343,7 @@ 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)); @@ -1361,8 +1352,7 @@ 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)); @@ -1371,8 +1361,7 @@ 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)); @@ -1507,8 +1496,7 @@ 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) { @@ -1518,8 +1506,7 @@ } 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/required_prefix_test.cc src/re2/testing/required_prefix_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/required_prefix_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/required_prefix_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -30,8 +30,8 @@ // 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:$)" }, @@ -84,17 +84,25 @@ // If the regexp immediately goes into // something not a literal match, there's no required prefix. - { "(abc)", false }, { "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, }, + { "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) { @@ -123,23 +131,69 @@ } } -TEST(PrefixAccel, BasicTest) { - Regexp* re = Regexp::Parse("abc\\d+", Regexp::LikePerl, NULL); +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); - Prog* prog = re->CompileToProg(0); - ASSERT_TRUE(prog != NULL); - for (int i = 0; i < 100; i++) { - std::string text(i, 'a'); - const char* p = reinterpret_cast( - prog->PrefixAccel(text.data(), text.size())); - EXPECT_TRUE(p == NULL); - text.append("abc"); - p = reinterpret_cast( - prog->PrefixAccel(text.data(), text.size())); - EXPECT_EQ(i, p-text.data()); - } - delete prog; + 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/search_test.cc src/re2/testing/search_test.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/search_test.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/search_test.cc 2023-02-20 19:50:47.000000000 +0100 @@ -308,6 +308,8 @@ // Former bugs. { "a\\C*|ba\\C", "baba" }, { "\\w*I\\w*", "Inc." }, + { "(?:|a)*", "aaa" }, + { "(?:|a)+", "aaa" }, }; TEST(Regexp, SearchTests) { diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/tester.cc src/re2/testing/tester.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/tester.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/testing/tester.cc 2023-02-20 19:50:47.000000000 +0100 @@ -117,8 +117,8 @@ 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. @@ -403,7 +403,7 @@ case kEngineRE2: case kEngineRE2a: case kEngineRE2b: { - if (!re2_ || text.end() != context.end()) { + if (!re2_ || EndPtr(text) != EndPtr(context)) { result->skipped = true; break; } @@ -418,8 +418,8 @@ 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); @@ -428,8 +428,8 @@ } 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; } @@ -606,9 +606,9 @@ << " 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/tostring.cc src/re2/tostring.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/tostring.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/tostring.cc 2023-02-20 19:50:47.000000000 +0100 @@ -291,7 +291,7 @@ // 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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode.py src/re2/unicode.py --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode.py 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode.py 2023-02-20 19:50:47.000000000 +0100 @@ -10,10 +10,10 @@ import os import re -from six.moves import urllib +import urllib.request # Directory or URL where Unicode tables reside. -_UNICODE_DIR = "https://www.unicode.org/Public/13.0.0/ucd" +_UNICODE_DIR = "https://www.unicode.org/Public/15.0.0/ucd" # Largest valid Unicode code value. _RUNE_MAX = 0x10FFFF diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode_casefold.cc src/re2/unicode_casefold.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode_casefold.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode_casefold.cc 2023-02-20 19:50:47.000000000 +0100 @@ -7,7 +7,7 @@ namespace re2 { -// 1384 groups, 2798 pairs, 358 ranges +// 1424 groups, 2878 pairs, 367 ranges const CaseFold unicode_casefold[] = { { 65, 90, 32 }, { 97, 106, -32 }, @@ -299,8 +299,8 @@ { 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,12 +344,13 @@ { 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 }, @@ -359,6 +360,14 @@ { 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 }, @@ -368,9 +377,9 @@ { 125184, 125217, 34 }, { 125218, 125251, -34 }, }; -const int num_unicode_casefold = 358; +const int num_unicode_casefold = 367; -// 1384 groups, 1414 pairs, 200 ranges +// 1424 groups, 1454 pairs, 205 ranges const CaseFold unicode_tolower[] = { { 65, 90, 32 }, { 181, 181, 775 }, @@ -521,7 +530,7 @@ { 8544, 8559, 16 }, { 8579, 8579, OddEven }, { 9398, 9423, 26 }, - { 11264, 11310, 48 }, + { 11264, 11311, 48 }, { 11360, 11360, EvenOdd }, { 11362, 11362, -10743 }, { 11363, 11363, -3814 }, @@ -557,23 +566,28 @@ { 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 = 200; +const int num_unicode_tolower = 205; diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode_groups.cc src/re2/unicode_groups.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode_groups.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/unicode_groups.cc 2023-02-20 19:50:47.000000000 +0100 @@ -15,6 +15,7 @@ { 1564, 1564 }, { 1757, 1757 }, { 1807, 1807 }, + { 2192, 2193 }, { 2274, 2274 }, { 6158, 6158 }, { 8203, 8207 }, @@ -28,7 +29,7 @@ static const URange32 C_range32[] = { { 69821, 69821 }, { 69837, 69837 }, - { 78896, 78904 }, + { 78896, 78911 }, { 113824, 113827 }, { 119155, 119162 }, { 917505, 917505 }, @@ -46,6 +47,7 @@ { 1564, 1564 }, { 1757, 1757 }, { 1807, 1807 }, + { 2192, 2193 }, { 2274, 2274 }, { 6158, 6158 }, { 8203, 8207 }, @@ -58,7 +60,7 @@ static const URange32 Cf_range32[] = { { 69821, 69821 }, { 69837, 69837 }, - { 78896, 78904 }, + { 78896, 78911 }, { 113824, 113827 }, { 119155, 119162 }, { 917505, 917505 }, @@ -124,8 +126,9 @@ { 2088, 2088 }, { 2112, 2136 }, { 2144, 2154 }, - { 2208, 2228 }, - { 2230, 2247 }, + { 2160, 2183 }, + { 2185, 2190 }, + { 2208, 2249 }, { 2308, 2361 }, { 2365, 2365 }, { 2384, 2384 }, @@ -190,6 +193,7 @@ { 3114, 3129 }, { 3133, 3133 }, { 3160, 3162 }, + { 3165, 3165 }, { 3168, 3169 }, { 3200, 3200 }, { 3205, 3212 }, @@ -198,7 +202,7 @@ { 3242, 3251 }, { 3253, 3257 }, { 3261, 3261 }, - { 3294, 3294 }, + { 3293, 3294 }, { 3296, 3297 }, { 3313, 3314 }, { 3332, 3340 }, @@ -269,9 +273,8 @@ { 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 @@ { 6688, 6740 }, { 6823, 6823 }, { 6917, 6963 }, - { 6981, 6987 }, + { 6981, 6988 }, { 7043, 7072 }, { 7086, 7087 }, { 7098, 7141 }, @@ -343,9 +346,7 @@ { 8517, 8521 }, { 8526, 8526 }, { 8579, 8580 }, - { 11264, 11310 }, - { 11312, 11358 }, - { 11360, 11492 }, + { 11264, 11492 }, { 11499, 11502 }, { 11506, 11507 }, { 11520, 11557 }, @@ -375,8 +376,7 @@ { 12704, 12735 }, { 12784, 12799 }, { 13312, 19903 }, - { 19968, 40956 }, - { 40960, 42124 }, + { 19968, 42124 }, { 42192, 42237 }, { 42240, 42508 }, { 42512, 42527 }, @@ -386,9 +386,11 @@ { 42656, 42725 }, { 42775, 42783 }, { 42786, 42888 }, - { 42891, 42943 }, - { 42946, 42954 }, - { 42997, 43009 }, + { 42891, 42954 }, + { 42960, 42961 }, + { 42963, 42963 }, + { 42965, 42969 }, + { 42994, 43009 }, { 43011, 43013 }, { 43015, 43018 }, { 43020, 43042 }, @@ -478,9 +480,20 @@ { 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 }, @@ -516,9 +529,12 @@ { 69376, 69404 }, { 69415, 69415 }, { 69424, 69445 }, + { 69488, 69505 }, { 69552, 69572 }, { 69600, 69622 }, { 69635, 69687 }, + { 69745, 69746 }, + { 69749, 69749 }, { 69763, 69807 }, { 69840, 69864 }, { 69891, 69926 }, @@ -532,6 +548,7 @@ { 70108, 70108 }, { 70144, 70161 }, { 70163, 70187 }, + { 70207, 70208 }, { 70272, 70278 }, { 70280, 70280 }, { 70282, 70285 }, @@ -560,6 +577,7 @@ { 71296, 71338 }, { 71352, 71352 }, { 71424, 71450 }, + { 71488, 71494 }, { 71680, 71723 }, { 71840, 71903 }, { 71935, 71942 }, @@ -579,7 +597,7 @@ { 72272, 72272 }, { 72284, 72329 }, { 72349, 72349 }, - { 72384, 72440 }, + { 72368, 72440 }, { 72704, 72712 }, { 72714, 72750 }, { 72768, 72768 }, @@ -593,13 +611,19 @@ { 73066, 73097 }, { 73112, 73112 }, { 73440, 73458 }, + { 73474, 73474 }, + { 73476, 73488 }, + { 73490, 73523 }, { 73648, 73648 }, { 73728, 74649 }, { 74880, 75075 }, - { 77824, 78894 }, + { 77712, 77808 }, + { 77824, 78895 }, + { 78913, 78918 }, { 82944, 83526 }, { 92160, 92728 }, { 92736, 92766 }, + { 92784, 92862 }, { 92880, 92909 }, { 92928, 92975 }, { 92992, 92995 }, @@ -614,8 +638,13 @@ { 94208, 100343 }, { 100352, 101589 }, { 101632, 101640 }, - { 110592, 110878 }, + { 110576, 110579 }, + { 110581, 110587 }, + { 110589, 110590 }, + { 110592, 110882 }, + { 110898, 110898 }, { 110928, 110930 }, + { 110933, 110933 }, { 110948, 110951 }, { 110960, 111355 }, { 113664, 113770 }, @@ -652,10 +681,19 @@ { 120714, 120744 }, { 120746, 120770 }, { 120772, 120779 }, + { 122624, 122654 }, + { 122661, 122666 }, + { 122928, 122989 }, { 123136, 123180 }, { 123191, 123197 }, { 123214, 123214 }, + { 123536, 123565 }, { 123584, 123627 }, + { 124112, 124139 }, + { 124896, 124902 }, + { 124904, 124907 }, + { 124909, 124910 }, + { 124912, 124926 }, { 124928, 125124 }, { 125184, 125251 }, { 125259, 125259 }, @@ -692,13 +730,14 @@ { 126625, 126627 }, { 126629, 126633 }, { 126635, 126651 }, - { 131072, 173789 }, - { 173824, 177972 }, + { 131072, 173791 }, + { 173824, 177977 }, { 177984, 178205 }, { 178208, 183969 }, { 183984, 191456 }, { 194560, 195101 }, { 196608, 201546 }, + { 201552, 205743 }, }; static const URange16 Ll_range16[] = { { 97, 122 }, @@ -1132,7 +1171,7 @@ { 8518, 8521 }, { 8526, 8526 }, { 8580, 8580 }, - { 11312, 11358 }, + { 11312, 11359 }, { 11361, 11361 }, { 11365, 11366 }, { 11368, 11368 }, @@ -1301,9 +1340,15 @@ { 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 }, @@ -1316,6 +1361,10 @@ static const URange32 Ll_range32[] = { { 66600, 66639 }, { 66776, 66811 }, + { 66967, 66977 }, + { 66979, 66993 }, + { 66995, 67001 }, + { 67003, 67004 }, { 68800, 68850 }, { 71872, 71903 }, { 93792, 93823 }, @@ -1347,6 +1396,9 @@ { 120746, 120770 }, { 120772, 120777 }, { 120779, 120779 }, + { 122624, 122633 }, + { 122635, 122654 }, + { 122661, 122666 }, { 125218, 125251 }, }; static const URange16 Lm_range16[] = { @@ -1365,6 +1417,7 @@ { 2074, 2074 }, { 2084, 2084 }, { 2088, 2088 }, + { 2249, 2249 }, { 2417, 2417 }, { 3654, 3654 }, { 3782, 3782 }, @@ -1395,6 +1448,7 @@ { 42775, 42783 }, { 42864, 42864 }, { 42888, 42888 }, + { 42994, 42996 }, { 43000, 43001 }, { 43471, 43471 }, { 43494, 43494 }, @@ -1407,11 +1461,19 @@ { 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 }, + { 122928, 122989 }, { 123191, 123197 }, + { 124139, 124139 }, { 125259, 125259 }, }; static const URange16 Lo_range16[] = { @@ -1438,8 +1500,9 @@ { 2048, 2069 }, { 2112, 2136 }, { 2144, 2154 }, - { 2208, 2228 }, - { 2230, 2247 }, + { 2160, 2183 }, + { 2185, 2190 }, + { 2208, 2248 }, { 2308, 2361 }, { 2365, 2365 }, { 2384, 2384 }, @@ -1504,6 +1567,7 @@ { 3114, 3129 }, { 3133, 3133 }, { 3160, 3162 }, + { 3165, 3165 }, { 3168, 3169 }, { 3200, 3200 }, { 3205, 3212 }, @@ -1512,7 +1576,7 @@ { 3242, 3251 }, { 3253, 3257 }, { 3261, 3261 }, - { 3294, 3294 }, + { 3293, 3294 }, { 3296, 3297 }, { 3313, 3314 }, { 3332, 3340 }, @@ -1576,9 +1640,8 @@ { 5761, 5786 }, { 5792, 5866 }, { 5873, 5880 }, - { 5888, 5900 }, - { 5902, 5905 }, - { 5920, 5937 }, + { 5888, 5905 }, + { 5919, 5937 }, { 5952, 5969 }, { 5984, 5996 }, { 5998, 6000 }, @@ -1598,7 +1661,7 @@ { 6656, 6678 }, { 6688, 6740 }, { 6917, 6963 }, - { 6981, 6987 }, + { 6981, 6988 }, { 7043, 7072 }, { 7086, 7087 }, { 7098, 7141 }, @@ -1631,8 +1694,7 @@ { 12704, 12735 }, { 12784, 12799 }, { 13312, 19903 }, - { 19968, 40956 }, - { 40960, 40980 }, + { 19968, 40980 }, { 40982, 42124 }, { 42192, 42231 }, { 42240, 42507 }, @@ -1762,9 +1824,12 @@ { 69376, 69404 }, { 69415, 69415 }, { 69424, 69445 }, + { 69488, 69505 }, { 69552, 69572 }, { 69600, 69622 }, { 69635, 69687 }, + { 69745, 69746 }, + { 69749, 69749 }, { 69763, 69807 }, { 69840, 69864 }, { 69891, 69926 }, @@ -1778,6 +1843,7 @@ { 70108, 70108 }, { 70144, 70161 }, { 70163, 70187 }, + { 70207, 70208 }, { 70272, 70278 }, { 70280, 70280 }, { 70282, 70285 }, @@ -1806,6 +1872,7 @@ { 71296, 71338 }, { 71352, 71352 }, { 71424, 71450 }, + { 71488, 71494 }, { 71680, 71723 }, { 71935, 71942 }, { 71945, 71945 }, @@ -1824,7 +1891,7 @@ { 72272, 72272 }, { 72284, 72329 }, { 72349, 72349 }, - { 72384, 72440 }, + { 72368, 72440 }, { 72704, 72712 }, { 72714, 72750 }, { 72768, 72768 }, @@ -1838,13 +1905,19 @@ { 73066, 73097 }, { 73112, 73112 }, { 73440, 73458 }, + { 73474, 73474 }, + { 73476, 73488 }, + { 73490, 73523 }, { 73648, 73648 }, { 73728, 74649 }, { 74880, 75075 }, - { 77824, 78894 }, + { 77712, 77808 }, + { 77824, 78895 }, + { 78913, 78918 }, { 82944, 83526 }, { 92160, 92728 }, { 92736, 92766 }, + { 92784, 92862 }, { 92880, 92909 }, { 92928, 92975 }, { 93027, 93047 }, @@ -1854,17 +1927,26 @@ { 94208, 100343 }, { 100352, 101589 }, { 101632, 101640 }, - { 110592, 110878 }, + { 110592, 110882 }, + { 110898, 110898 }, { 110928, 110930 }, + { 110933, 110933 }, { 110948, 110951 }, { 110960, 111355 }, { 113664, 113770 }, { 113776, 113788 }, { 113792, 113800 }, { 113808, 113817 }, + { 122634, 122634 }, { 123136, 123180 }, { 123214, 123214 }, + { 123536, 123565 }, { 123584, 123627 }, + { 124112, 124138 }, + { 124896, 124902 }, + { 124904, 124907 }, + { 124909, 124910 }, + { 124912, 124926 }, { 124928, 125124 }, { 126464, 126467 }, { 126469, 126495 }, @@ -1899,13 +1981,14 @@ { 126625, 126627 }, { 126629, 126633 }, { 126635, 126651 }, - { 131072, 173789 }, - { 173824, 177972 }, + { 131072, 173791 }, + { 173824, 177977 }, { 177984, 178205 }, { 178208, 183969 }, { 183984, 191456 }, { 194560, 195101 }, { 196608, 201546 }, + { 201552, 205743 }, }; static const URange16 Lt_range16[] = { { 453, 453 }, @@ -2351,7 +2434,7 @@ { 8510, 8511 }, { 8517, 8517 }, { 8579, 8579 }, - { 11264, 11310 }, + { 11264, 11311 }, { 11360, 11360 }, { 11362, 11364 }, { 11367, 11367 }, @@ -2516,15 +2599,23 @@ { 42938, 42938 }, { 42940, 42940 }, { 42942, 42942 }, + { 42944, 42944 }, { 42946, 42946 }, { 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 }, @@ -2586,7 +2677,8 @@ { 2085, 2087 }, { 2089, 2093 }, { 2137, 2139 }, - { 2259, 2273 }, + { 2200, 2207 }, + { 2250, 2273 }, { 2275, 2307 }, { 2362, 2364 }, { 2366, 2383 }, @@ -2628,6 +2720,7 @@ { 3018, 3021 }, { 3031, 3031 }, { 3072, 3076 }, + { 3132, 3132 }, { 3134, 3140 }, { 3142, 3144 }, { 3146, 3149 }, @@ -2640,6 +2733,7 @@ { 3274, 3277 }, { 3285, 3286 }, { 3298, 3299 }, + { 3315, 3315 }, { 3328, 3331 }, { 3387, 3388 }, { 3390, 3396 }, @@ -2658,7 +2752,7 @@ { 3655, 3662 }, { 3761, 3761 }, { 3764, 3772 }, - { 3784, 3789 }, + { 3784, 3790 }, { 3864, 3865 }, { 3893, 3893 }, { 3895, 3895 }, @@ -2679,13 +2773,14 @@ { 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 }, @@ -2694,7 +2789,7 @@ { 6741, 6750 }, { 6752, 6780 }, { 6783, 6783 }, - { 6832, 6848 }, + { 6832, 6862 }, { 6912, 6916 }, { 6964, 6980 }, { 7019, 7027 }, @@ -2707,8 +2802,7 @@ { 7405, 7405 }, { 7412, 7412 }, { 7415, 7417 }, - { 7616, 7673 }, - { 7675, 7679 }, + { 7616, 7679 }, { 8400, 8432 }, { 11503, 11505 }, { 11647, 11647 }, @@ -2762,11 +2856,16 @@ { 68325, 68326 }, { 68900, 68903 }, { 69291, 69292 }, + { 69373, 69375 }, { 69446, 69456 }, + { 69506, 69509 }, { 69632, 69634 }, { 69688, 69702 }, + { 69744, 69744 }, + { 69747, 69748 }, { 69759, 69762 }, { 69808, 69818 }, + { 69826, 69826 }, { 69888, 69890 }, { 69927, 69940 }, { 69957, 69958 }, @@ -2777,6 +2876,7 @@ { 70094, 70095 }, { 70188, 70199 }, { 70206, 70206 }, + { 70209, 70209 }, { 70367, 70378 }, { 70400, 70403 }, { 70459, 70460 }, @@ -2824,6 +2924,12 @@ { 73104, 73105 }, { 73107, 73111 }, { 73459, 73462 }, + { 73472, 73473 }, + { 73475, 73475 }, + { 73524, 73530 }, + { 73534, 73538 }, + { 78912, 78912 }, + { 78919, 78933 }, { 92912, 92916 }, { 92976, 92982 }, { 94031, 94031 }, @@ -2832,6 +2938,8 @@ { 94180, 94180 }, { 94192, 94193 }, { 113821, 113822 }, + { 118528, 118573 }, + { 118576, 118598 }, { 119141, 119145 }, { 119149, 119154 }, { 119163, 119170 }, @@ -2849,8 +2957,11 @@ { 122907, 122913 }, { 122915, 122916 }, { 122918, 122922 }, + { 123023, 123023 }, { 123184, 123190 }, + { 123566, 123566 }, { 123628, 123631 }, + { 124140, 124143 }, { 125136, 125142 }, { 125252, 125258 }, { 917760, 917999 }, @@ -2891,6 +3002,7 @@ { 3271, 3272 }, { 3274, 3275 }, { 3285, 3286 }, + { 3315, 3315 }, { 3330, 3331 }, { 3390, 3392 }, { 3398, 3400 }, @@ -2913,6 +3025,8 @@ { 4231, 4236 }, { 4239, 4239 }, { 4250, 4252 }, + { 5909, 5909 }, + { 5940, 5940 }, { 6070, 6070 }, { 6078, 6085 }, { 6087, 6088 }, @@ -3029,6 +3143,10 @@ { 73107, 73108 }, { 73110, 73110 }, { 73461, 73462 }, + { 73475, 73475 }, + { 73524, 73525 }, + { 73534, 73535 }, + { 73537, 73537 }, { 94033, 94087 }, { 94192, 94193 }, { 119141, 119142 }, @@ -3066,7 +3184,8 @@ { 2085, 2087 }, { 2089, 2093 }, { 2137, 2139 }, - { 2259, 2273 }, + { 2200, 2207 }, + { 2250, 2273 }, { 2275, 2306 }, { 2362, 2362 }, { 2364, 2364 }, @@ -3107,6 +3226,7 @@ { 3021, 3021 }, { 3072, 3072 }, { 3076, 3076 }, + { 3132, 3132 }, { 3134, 3136 }, { 3142, 3144 }, { 3146, 3149 }, @@ -3132,7 +3252,7 @@ { 3655, 3662 }, { 3761, 3761 }, { 3764, 3772 }, - { 3784, 3789 }, + { 3784, 3790 }, { 3864, 3865 }, { 3893, 3893 }, { 3895, 3895 }, @@ -3156,7 +3276,7 @@ { 4253, 4253 }, { 4957, 4959 }, { 5906, 5908 }, - { 5938, 5940 }, + { 5938, 5939 }, { 5970, 5971 }, { 6002, 6003 }, { 6068, 6069 }, @@ -3165,6 +3285,7 @@ { 6089, 6099 }, { 6109, 6109 }, { 6155, 6157 }, + { 6159, 6159 }, { 6277, 6278 }, { 6313, 6313 }, { 6432, 6434 }, @@ -3181,7 +3302,7 @@ { 6771, 6780 }, { 6783, 6783 }, { 6832, 6845 }, - { 6847, 6848 }, + { 6847, 6862 }, { 6912, 6915 }, { 6964, 6964 }, { 6966, 6970 }, @@ -3204,8 +3325,7 @@ { 7405, 7405 }, { 7412, 7412 }, { 7416, 7417 }, - { 7616, 7673 }, - { 7675, 7679 }, + { 7616, 7679 }, { 8400, 8412 }, { 8417, 8417 }, { 8421, 8432 }, @@ -3265,12 +3385,17 @@ { 68325, 68326 }, { 68900, 68903 }, { 69291, 69292 }, + { 69373, 69375 }, { 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 }, @@ -3283,6 +3408,7 @@ { 70196, 70196 }, { 70198, 70199 }, { 70206, 70206 }, + { 70209, 70209 }, { 70367, 70367 }, { 70371, 70378 }, { 70400, 70401 }, @@ -3344,12 +3470,20 @@ { 73109, 73109 }, { 73111, 73111 }, { 73459, 73460 }, + { 73472, 73473 }, + { 73526, 73530 }, + { 73536, 73536 }, + { 73538, 73538 }, + { 78912, 78912 }, + { 78919, 78933 }, { 92912, 92916 }, { 92976, 92982 }, { 94031, 94031 }, { 94095, 94098 }, { 94180, 94180 }, { 113821, 113822 }, + { 118528, 118573 }, + { 118576, 118598 }, { 119143, 119145 }, { 119163, 119170 }, { 119173, 119179 }, @@ -3366,8 +3500,11 @@ { 122907, 122913 }, { 122915, 122916 }, { 122918, 122922 }, + { 123023, 123023 }, { 123184, 123190 }, + { 123566, 123566 }, { 123628, 123631 }, + { 124140, 124143 }, { 125136, 125142 }, { 125252, 125258 }, { 917760, 917999 }, @@ -3488,17 +3625,21 @@ { 72784, 72812 }, { 73040, 73049 }, { 73120, 73129 }, + { 73552, 73561 }, { 73664, 73684 }, { 74752, 74862 }, { 92768, 92777 }, + { 92864, 92873 }, { 93008, 93017 }, { 93019, 93025 }, { 93824, 93846 }, + { 119488, 119507 }, { 119520, 119539 }, { 119648, 119672 }, { 120782, 120831 }, { 123200, 123209 }, { 123632, 123641 }, + { 124144, 124153 }, { 125127, 125135 }, { 125264, 125273 }, { 126065, 126123 }, @@ -3566,11 +3707,14 @@ { 72784, 72793 }, { 73040, 73049 }, { 73120, 73129 }, + { 73552, 73561 }, { 92768, 92777 }, + { 92864, 92873 }, { 93008, 93017 }, { 120782, 120831 }, { 123200, 123209 }, { 123632, 123641 }, + { 124144, 124153 }, { 125264, 125273 }, { 130032, 130041 }, }; @@ -3655,6 +3799,7 @@ { 73664, 73684 }, { 93019, 93025 }, { 93824, 93846 }, + { 119488, 119507 }, { 119520, 119539 }, { 119648, 119672 }, { 125127, 125135 }, @@ -3693,7 +3838,7 @@ { 1545, 1546 }, { 1548, 1549 }, { 1563, 1563 }, - { 1566, 1567 }, + { 1565, 1567 }, { 1642, 1645 }, { 1748, 1748 }, { 1792, 1805 }, @@ -3732,6 +3877,7 @@ { 6816, 6822 }, { 6824, 6829 }, { 7002, 7008 }, + { 7037, 7038 }, { 7164, 7167 }, { 7227, 7231 }, { 7294, 7295 }, @@ -3756,7 +3902,7 @@ { 11632, 11632 }, { 11776, 11822 }, { 11824, 11855 }, - { 11858, 11858 }, + { 11858, 11869 }, { 12289, 12291 }, { 12296, 12305 }, { 12308, 12319 }, @@ -3814,6 +3960,7 @@ { 68505, 68508 }, { 69293, 69293 }, { 69461, 69465 }, + { 69510, 69513 }, { 69703, 69709 }, { 69819, 69820 }, { 69822, 69825 }, @@ -3832,6 +3979,7 @@ { 71105, 71127 }, { 71233, 71235 }, { 71264, 71276 }, + { 71353, 71353 }, { 71484, 71486 }, { 71739, 71739 }, { 72004, 72006 }, @@ -3839,11 +3987,14 @@ { 72255, 72262 }, { 72346, 72348 }, { 72350, 72354 }, + { 72448, 72457 }, { 72769, 72773 }, { 72816, 72817 }, { 73463, 73464 }, + { 73539, 73551 }, { 73727, 73727 }, { 74864, 74868 }, + { 77809, 77810 }, { 92782, 92783 }, { 92917, 92917 }, { 92983, 92987 }, @@ -3873,6 +4024,7 @@ { 11802, 11802 }, { 11834, 11835 }, { 11840, 11840 }, + { 11869, 11869 }, { 12316, 12316 }, { 12336, 12336 }, { 12448, 12448 }, @@ -3928,6 +4080,10 @@ { 11813, 11813 }, { 11815, 11815 }, { 11817, 11817 }, + { 11862, 11862 }, + { 11864, 11864 }, + { 11866, 11866 }, + { 11868, 11868 }, { 12297, 12297 }, { 12299, 12299 }, { 12301, 12301 }, @@ -4007,7 +4163,7 @@ { 1545, 1546 }, { 1548, 1549 }, { 1563, 1563 }, - { 1566, 1567 }, + { 1565, 1567 }, { 1642, 1645 }, { 1748, 1748 }, { 1792, 1805 }, @@ -4044,6 +4200,7 @@ { 6816, 6822 }, { 6824, 6829 }, { 7002, 7008 }, + { 7037, 7038 }, { 7164, 7167 }, { 7227, 7231 }, { 7294, 7295 }, @@ -4072,7 +4229,7 @@ { 11836, 11839 }, { 11841, 11841 }, { 11843, 11855 }, - { 11858, 11858 }, + { 11858, 11860 }, { 12289, 12291 }, { 12349, 12349 }, { 12539, 12539 }, @@ -4128,6 +4285,7 @@ { 68409, 68415 }, { 68505, 68508 }, { 69461, 69465 }, + { 69510, 69513 }, { 69703, 69709 }, { 69819, 69820 }, { 69822, 69825 }, @@ -4146,6 +4304,7 @@ { 71105, 71127 }, { 71233, 71235 }, { 71264, 71276 }, + { 71353, 71353 }, { 71484, 71486 }, { 71739, 71739 }, { 72004, 72006 }, @@ -4153,11 +4312,14 @@ { 72255, 72262 }, { 72346, 72348 }, { 72350, 72354 }, + { 72448, 72457 }, { 72769, 72773 }, { 72816, 72817 }, { 73463, 73464 }, + { 73539, 73551 }, { 73727, 73727 }, { 74864, 74868 }, + { 77809, 77810 }, { 92782, 92783 }, { 92917, 92917 }, { 92983, 92987 }, @@ -4215,6 +4377,10 @@ { 11814, 11814 }, { 11816, 11816 }, { 11842, 11842 }, + { 11861, 11861 }, + { 11863, 11863 }, + { 11865, 11865 }, + { 11867, 11867 }, { 12296, 12296 }, { 12298, 12298 }, { 12300, 12300 }, @@ -4279,6 +4445,7 @@ { 1789, 1790 }, { 2038, 2038 }, { 2046, 2047 }, + { 2184, 2184 }, { 2546, 2547 }, { 2554, 2555 }, { 2801, 2801 }, @@ -4317,7 +4484,7 @@ { 8274, 8274 }, { 8314, 8316 }, { 8330, 8332 }, - { 8352, 8383 }, + { 8352, 8384 }, { 8448, 8449 }, { 8451, 8454 }, { 8456, 8457 }, @@ -4379,8 +4546,10 @@ { 43867, 43867 }, { 43882, 43883 }, { 64297, 64297 }, - { 64434, 64449 }, - { 65020, 65021 }, + { 64434, 64450 }, + { 64832, 64847 }, + { 64975, 64975 }, + { 65020, 65023 }, { 65122, 65122 }, { 65124, 65126 }, { 65129, 65129 }, @@ -4409,13 +4578,14 @@ { 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 }, @@ -4453,28 +4623,27 @@ { 127568, 127569 }, { 127584, 127589 }, { 127744, 128727 }, - { 128736, 128748 }, + { 128732, 128748 }, { 128752, 128764 }, - { 128768, 128883 }, - { 128896, 128984 }, + { 128768, 128886 }, + { 128891, 128985 }, { 128992, 129003 }, + { 129008, 129008 }, { 129024, 129035 }, { 129040, 129095 }, { 129104, 129113 }, { 129120, 129159 }, { 129168, 129197 }, { 129200, 129201 }, - { 129280, 129400 }, - { 129402, 129483 }, - { 129485, 129619 }, + { 129280, 129619 }, { 129632, 129645 }, - { 129648, 129652 }, - { 129656, 129658 }, - { 129664, 129670 }, - { 129680, 129704 }, - { 129712, 129718 }, - { 129728, 129730 }, - { 129744, 129750 }, + { 129648, 129660 }, + { 129664, 129672 }, + { 129680, 129725 }, + { 129727, 129733 }, + { 129742, 129755 }, + { 129760, 129768 }, + { 129776, 129784 }, { 129792, 129938 }, { 129940, 129994 }, }; @@ -4490,7 +4659,7 @@ { 3065, 3065 }, { 3647, 3647 }, { 6107, 6107 }, - { 8352, 8383 }, + { 8352, 8384 }, { 43064, 43064 }, { 65020, 65020 }, { 65129, 65129 }, @@ -4517,6 +4686,7 @@ { 751, 767 }, { 885, 885 }, { 900, 901 }, + { 2184, 2184 }, { 8125, 8125 }, { 8127, 8129 }, { 8141, 8143 }, @@ -4529,7 +4699,7 @@ { 42889, 42890 }, { 43867, 43867 }, { 43882, 43883 }, - { 64434, 64449 }, + { 64434, 64450 }, { 65342, 65342 }, { 65344, 65344 }, { 65507, 65507 }, @@ -4713,7 +4883,9 @@ { 43062, 43063 }, { 43065, 43065 }, { 43639, 43641 }, - { 65021, 65021 }, + { 64832, 64847 }, + { 64975, 64975 }, + { 65021, 65023 }, { 65508, 65508 }, { 65512, 65512 }, { 65517, 65518 }, @@ -4734,13 +4906,14 @@ { 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 }, @@ -4766,28 +4939,27 @@ { 127584, 127589 }, { 127744, 127994 }, { 128000, 128727 }, - { 128736, 128748 }, + { 128732, 128748 }, { 128752, 128764 }, - { 128768, 128883 }, - { 128896, 128984 }, + { 128768, 128886 }, + { 128891, 128985 }, { 128992, 129003 }, + { 129008, 129008 }, { 129024, 129035 }, { 129040, 129095 }, { 129104, 129113 }, { 129120, 129159 }, { 129168, 129197 }, { 129200, 129201 }, - { 129280, 129400 }, - { 129402, 129483 }, - { 129485, 129619 }, + { 129280, 129619 }, { 129632, 129645 }, - { 129648, 129652 }, - { 129656, 129658 }, - { 129664, 129670 }, - { 129680, 129704 }, - { 129712, 129718 }, - { 129728, 129730 }, - { 129744, 129750 }, + { 129648, 129660 }, + { 129664, 129672 }, + { 129680, 129725 }, + { 129727, 129733 }, + { 129742, 129755 }, + { 129760, 129768 }, + { 129776, 129784 }, { 129792, 129938 }, { 129940, 129994 }, }; @@ -4824,7 +4996,7 @@ static const URange32 Ahom_range32[] = { { 71424, 71450 }, { 71453, 71467 }, - { 71472, 71487 }, + { 71472, 71494 }, }; static const URange32 Anatolian_Hieroglyphs_range32[] = { { 82944, 83526 }, @@ -4833,28 +5005,29 @@ { 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, 2247 }, - { 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 }, }; static const URange32 Arabic_range32[] = { { 69216, 69246 }, + { 69373, 69375 }, { 126464, 126467 }, { 126469, 126495 }, { 126497, 126498 }, @@ -4901,8 +5074,8 @@ { 68409, 68415 }, }; static const URange16 Balinese_range16[] = { - { 6912, 6987 }, - { 6992, 7036 }, + { 6912, 6988 }, + { 6992, 7038 }, }; static const URange16 Bamum_range16[] = { { 42656, 42743 }, @@ -4947,7 +5120,7 @@ }; static const URange32 Brahmi_range32[] = { { 69632, 69709 }, - { 69714, 69743 }, + { 69714, 69749 }, { 69759, 69759 }, }; static const URange16 Braille_range16[] = { @@ -4964,6 +5137,9 @@ { 5120, 5759 }, { 6320, 6389 }, }; +static const URange32 Canadian_Aboriginal_range32[] = { + { 72368, 72383 }, +}; static const URange32 Carian_range32[] = { { 66208, 66256 }, }; @@ -5030,7 +5206,7 @@ { 8294, 8304 }, { 8308, 8318 }, { 8320, 8334 }, - { 8352, 8383 }, + { 8352, 8384 }, { 8448, 8485 }, { 8487, 8489 }, { 8492, 8497 }, @@ -5043,7 +5219,7 @@ { 10496, 11123 }, { 11126, 11157 }, { 11159, 11263 }, - { 11776, 11858 }, + { 11776, 11869 }, { 12272, 12283 }, { 12288, 12292 }, { 12294, 12294 }, @@ -5089,15 +5265,16 @@ { 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 }, + { 119488, 119507 }, { 119520, 119539 }, { 119552, 119638 }, { 119648, 119672 }, @@ -5138,28 +5315,27 @@ { 127568, 127569 }, { 127584, 127589 }, { 127744, 128727 }, - { 128736, 128748 }, + { 128732, 128748 }, { 128752, 128764 }, - { 128768, 128883 }, - { 128896, 128984 }, + { 128768, 128886 }, + { 128891, 128985 }, { 128992, 129003 }, + { 129008, 129008 }, { 129024, 129035 }, { 129040, 129095 }, { 129104, 129113 }, { 129120, 129159 }, { 129168, 129197 }, { 129200, 129201 }, - { 129280, 129400 }, - { 129402, 129483 }, - { 129485, 129619 }, + { 129280, 129619 }, { 129632, 129645 }, - { 129648, 129652 }, - { 129656, 129658 }, - { 129664, 129670 }, - { 129680, 129704 }, - { 129712, 129718 }, - { 129728, 129730 }, - { 129744, 129750 }, + { 129648, 129660 }, + { 129664, 129672 }, + { 129680, 129725 }, + { 129727, 129733 }, + { 129742, 129755 }, + { 129760, 129768 }, + { 129776, 129784 }, { 129792, 129938 }, { 129940, 129994 }, { 130032, 130041 }, @@ -5185,6 +5361,9 @@ { 67644, 67644 }, { 67647, 67647 }, }; +static const URange32 Cypro_Minoan_range32[] = { + { 77712, 77810 }, +}; static const URange16 Cyrillic_range16[] = { { 1024, 1156 }, { 1159, 1327 }, @@ -5195,6 +5374,10 @@ { 42560, 42655 }, { 65070, 65071 }, }; +static const URange32 Cyrillic_range32[] = { + { 122928, 122989 }, + { 123023, 123023 }, +}; static const URange32 Deseret_range32[] = { { 66560, 66639 }, }; @@ -5204,6 +5387,9 @@ { 2406, 2431 }, { 43232, 43263 }, }; +static const URange32 Devanagari_range32[] = { + { 72448, 72457 }, +}; static const URange32 Dives_Akuru_range32[] = { { 71936, 71942 }, { 71945, 71945 }, @@ -5225,8 +5411,7 @@ { 113820, 113823 }, }; static const URange32 Egyptian_Hieroglyphs_range32[] = { - { 77824, 78894 }, - { 78896, 78904 }, + { 77824, 78933 }, }; static const URange32 Elbasan_range32[] = { { 66816, 66855 }, @@ -5268,6 +5453,12 @@ { 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 }, @@ -5281,8 +5472,7 @@ { 11565, 11565 }, }; static const URange16 Glagolitic_range16[] = { - { 11264, 11310 }, - { 11312, 11358 }, + { 11264, 11359 }, }; static const URange32 Glagolitic_range32[] = { { 122880, 122886 }, @@ -5402,19 +5592,21 @@ { 12321, 12329 }, { 12344, 12347 }, { 13312, 19903 }, - { 19968, 40956 }, + { 19968, 40959 }, { 63744, 64109 }, { 64112, 64217 }, }; static const URange32 Han_range32[] = { + { 94178, 94179 }, { 94192, 94193 }, - { 131072, 173789 }, - { 173824, 177972 }, + { 131072, 173791 }, + { 173824, 177977 }, { 177984, 178205 }, { 178208, 183969 }, { 183984, 191456 }, { 194560, 195101 }, { 196608, 201546 }, + { 201552, 205743 }, }; static const URange16 Hangul_range16[] = { { 4352, 4607 }, @@ -5460,7 +5652,8 @@ { 12445, 12447 }, }; static const URange32 Hiragana_range32[] = { - { 110593, 110878 }, + { 110593, 110879 }, + { 110898, 110898 }, { 110928, 110930 }, { 127488, 127488 }, }; @@ -5474,15 +5667,14 @@ { 1611, 1621 }, { 1648, 1648 }, { 2385, 2388 }, - { 6832, 6848 }, + { 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 }, @@ -5494,6 +5686,8 @@ { 66045, 66045 }, { 66272, 66272 }, { 70459, 70459 }, + { 118528, 118573 }, + { 118576, 118598 }, { 119143, 119145 }, { 119163, 119170 }, { 119173, 119179 }, @@ -5514,7 +5708,7 @@ { 43486, 43487 }, }; static const URange32 Kaithi_range32[] = { - { 69760, 69825 }, + { 69760, 69826 }, { 69837, 69837 }, }; static const URange16 Kannada_range16[] = { @@ -5527,10 +5721,10 @@ { 3270, 3272 }, { 3274, 3277 }, { 3285, 3286 }, - { 3294, 3294 }, + { 3293, 3294 }, { 3296, 3299 }, { 3302, 3311 }, - { 3313, 3314 }, + { 3313, 3315 }, }; static const URange16 Katakana_range16[] = { { 12449, 12538 }, @@ -5542,9 +5736,19 @@ { 65393, 65437 }, }; static const URange32 Katakana_range32[] = { + { 110576, 110579 }, + { 110581, 110587 }, + { 110589, 110590 }, { 110592, 110592 }, + { 110880, 110882 }, + { 110933, 110933 }, { 110948, 110951 }, }; +static const URange32 Kawi_range32[] = { + { 73472, 73488 }, + { 73490, 73530 }, + { 73534, 73561 }, +}; static const URange16 Kayah_Li_range16[] = { { 43264, 43309 }, { 43311, 43311 }, @@ -5571,7 +5775,7 @@ }; static const URange32 Khojki_range32[] = { { 70144, 70161 }, - { 70163, 70206 }, + { 70163, 70209 }, }; static const URange32 Khudawadi_range32[] = { { 70320, 70378 }, @@ -5586,7 +5790,7 @@ { 3751, 3773 }, { 3776, 3780 }, { 3782, 3782 }, - { 3784, 3789 }, + { 3784, 3790 }, { 3792, 3801 }, { 3804, 3807 }, }; @@ -5614,9 +5818,11 @@ { 8544, 8584 }, { 11360, 11391 }, { 42786, 42887 }, - { 42891, 42943 }, - { 42946, 42954 }, - { 42997, 43007 }, + { 42891, 42954 }, + { 42960, 42961 }, + { 42963, 42963 }, + { 42965, 42969 }, + { 42994, 43007 }, { 43824, 43866 }, { 43868, 43876 }, { 43878, 43881 }, @@ -5624,6 +5830,13 @@ { 65313, 65338 }, { 65345, 65370 }, }; +static const URange32 Latin_range32[] = { + { 67456, 67461 }, + { 67463, 67504 }, + { 67506, 67514 }, + { 122624, 122654 }, + { 122661, 122666 }, +}; static const URange16 Lepcha_range16[] = { { 7168, 7223 }, { 7227, 7241 }, @@ -5732,8 +5945,7 @@ static const URange16 Mongolian_range16[] = { { 6144, 6145 }, { 6148, 6148 }, - { 6150, 6158 }, - { 6160, 6169 }, + { 6150, 6169 }, { 6176, 6264 }, { 6272, 6314 }, }; @@ -5761,6 +5973,9 @@ { 67712, 67742 }, { 67751, 67759 }, }; +static const URange32 Nag_Mundari_range32[] = { + { 124112, 124153 }, +}; static const URange32 Nandinagari_range32[] = { { 72096, 72103 }, { 72106, 72151 }, @@ -5824,6 +6039,9 @@ 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 }, @@ -5945,8 +6163,8 @@ { 2144, 2154 }, }; static const URange16 Tagalog_range16[] = { - { 5888, 5900 }, - { 5902, 5908 }, + { 5888, 5909 }, + { 5919, 5919 }, }; static const URange16 Tagbanwa_range16[] = { { 5984, 5996 }, @@ -5969,7 +6187,7 @@ { 43739, 43743 }, }; static const URange32 Takri_range32[] = { - { 71296, 71352 }, + { 71296, 71353 }, { 71360, 71369 }, }; static const URange16 Tamil_range16[] = { @@ -5994,6 +6212,10 @@ { 73664, 73713 }, { 73727, 73727 }, }; +static const URange32 Tangsa_range32[] = { + { 92784, 92862 }, + { 92864, 92873 }, +}; static const URange32 Tangut_range32[] = { { 94176, 94176 }, { 94208, 100343 }, @@ -6005,11 +6227,12 @@ { 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 }, @@ -6039,6 +6262,9 @@ { 70784, 70855 }, { 70864, 70873 }, }; +static const URange32 Toto_range32[] = { + { 123536, 123566 }, +}; static const URange32 Ugaritic_range32[] = { { 66432, 66461 }, { 66463, 66463 }, @@ -6046,6 +6272,16 @@ 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 }, @@ -6066,12 +6302,12 @@ static const URange32 Zanabazar_Square_range32[] = { { 72192, 72263 }, }; -// 4001 16-bit ranges, 1602 32-bit ranges +// 4040 16-bit ranges, 1775 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 }, + { "Arabic", +1, Arabic_range16, 22, Arabic_range32, 36 }, { "Armenian", +1, Armenian_range16, 4, 0, 0 }, { "Avestan", +1, 0, 0, Avestan_range32, 2 }, { "Balinese", +1, Balinese_range16, 2, 0, 0 }, @@ -6085,12 +6321,12 @@ { "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 }, @@ -6101,61 +6337,63 @@ { "Cs", +1, Cs_range16, 1, 0, 0 }, { "Cuneiform", +1, 0, 0, Cuneiform_range32, 4 }, { "Cypriot", +1, 0, 0, Cypriot_range32, 6 }, - { "Cyrillic", +1, Cyrillic_range16, 8, 0, 0 }, + { "Cypro_Minoan", +1, 0, 0, Cypro_Minoan_range32, 1 }, + { "Cyrillic", +1, Cyrillic_range16, 8, Cyrillic_range32, 2 }, { "Deseret", +1, 0, 0, Deseret_range32, 1 }, - { "Devanagari", +1, Devanagari_range16, 4, 0, 0 }, + { "Devanagari", +1, Devanagari_range16, 4, Devanagari_range32, 1 }, { "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 }, + { "Egyptian_Hieroglyphs", +1, 0, 0, Egyptian_Hieroglyphs_range32, 1 }, { "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, 8 }, + { "Han", +1, Han_range16, 11, Han_range32, 10 }, { "Hangul", +1, Hangul_range16, 14, 0, 0 }, { "Hanifi_Rohingya", +1, 0, 0, Hanifi_Rohingya_range32, 2 }, { "Hanunoo", +1, Hanunoo_range16, 1, 0, 0 }, { "Hatran", +1, 0, 0, Hatran_range32, 3 }, { "Hebrew", +1, Hebrew_range16, 9, 0, 0 }, - { "Hiragana", +1, Hiragana_range16, 2, Hiragana_range32, 3 }, + { "Hiragana", +1, Hiragana_range16, 2, Hiragana_range32, 4 }, { "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, 7 }, + { "Kawi", +1, 0, 0, Kawi_range32, 3 }, { "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, 242 }, + { "L", +1, L_range16, 380, L_range32, 279 }, { "Lao", +1, Lao_range16, 11, 0, 0 }, - { "Latin", +1, Latin_range16, 32, 0, 0 }, + { "Latin", +1, Latin_range16, 34, Latin_range32, 5 }, { "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, Lisu_range32, 1 }, - { "Ll", +1, Ll_range16, 611, Ll_range32, 34 }, - { "Lm", +1, Lm_range16, 55, Lm_range32, 6 }, - { "Lo", +1, Lo_range16, 290, Lo_range32, 199 }, + { "Ll", +1, Ll_range16, 617, Ll_range32, 41 }, + { "Lm", +1, Lm_range16, 57, Lm_range32, 14 }, + { "Lo", +1, Lo_range16, 290, Lo_range32, 220 }, { "Lt", +1, Lt_range16, 10, 0, 0 }, - { "Lu", +1, Lu_range16, 601, 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, 187, M_range32, 103 }, + { "M", +1, M_range16, 190, M_range32, 120 }, { "Mahajani", +1, 0, 0, Mahajani_range32, 1 }, { "Makasar", +1, 0, 0, Makasar_range32, 1 }, { "Malayalam", +1, Malayalam_range16, 7, 0, 0 }, @@ -6163,7 +6401,7 @@ { "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, 66 }, + { "Mc", +1, Mc_range16, 112, Mc_range32, 70 }, { "Me", +1, Me_range16, 5, 0, 0 }, { "Medefaidrin", +1, 0, 0, Medefaidrin_range32, 1 }, { "Meetei_Mayek", +1, Meetei_Mayek_range16, 3, 0, 0 }, @@ -6171,21 +6409,22 @@ { "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, 210, Mn_range32, 117 }, + { "Mn", +1, Mn_range16, 212, Mn_range32, 134 }, { "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, 66 }, + { "N", +1, N_range16, 67, N_range32, 70 }, { "Nabataean", +1, 0, 0, Nabataean_range32, 2 }, + { "Nag_Mundari", +1, 0, 0, Nag_Mundari_range32, 1 }, { "Nandinagari", +1, 0, 0, Nandinagari_range32, 3 }, - { "Nd", +1, Nd_range16, 37, Nd_range32, 24 }, + { "Nd", +1, Nd_range16, 37, Nd_range32, 27 }, { "New_Tai_Lue", +1, New_Tai_Lue_range16, 4, 0, 0 }, { "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, 42 }, + { "No", +1, No_range16, 29, No_range32, 43 }, { "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 }, @@ -6198,26 +6437,27 @@ { "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, 132, P_range32, 53 }, + { "P", +1, P_range16, 133, P_range32, 58 }, { "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, Pd_range32, 1 }, - { "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, 129, Po_range32, 52 }, - { "Ps", +1, Ps_range16, 75, 0, 0 }, + { "Po", +1, Po_range16, 130, Po_range32, 57 }, + { "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, 148, S_range32, 81 }, + { "S", +1, S_range16, 151, S_range32, 81 }, { "Samaritan", +1, Samaritan_range16, 2, 0, 0 }, { "Saurashtra", +1, Saurashtra_range16, 2, 0, 0 }, { "Sc", +1, Sc_range16, 18, Sc_range32, 3 }, @@ -6226,9 +6466,9 @@ { "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, 29, Sk_range32, 1 }, + { "Sk", +1, Sk_range16, 30, Sk_range32, 1 }, { "Sm", +1, Sm_range16, 53, Sm_range32, 11 }, - { "So", +1, So_range16, 112, So_range32, 70 }, + { "So", +1, So_range16, 114, So_range32, 70 }, { "Sogdian", +1, 0, 0, Sogdian_range32, 1 }, { "Sora_Sompeng", +1, 0, 0, Sora_Sompeng_range32, 2 }, { "Soyombo", +1, 0, 0, Soyombo_range32, 1 }, @@ -6242,15 +6482,18 @@ { "Tai_Viet", +1, Tai_Viet_range16, 2, 0, 0 }, { "Takri", +1, 0, 0, Takri_range32, 2 }, { "Tamil", +1, Tamil_range16, 16, Tamil_range32, 2 }, + { "Tangsa", +1, 0, 0, Tangsa_range32, 2 }, { "Tangut", +1, 0, 0, Tangut_range32, 4 }, - { "Telugu", +1, Telugu_range16, 12, 0, 0 }, + { "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 }, @@ -6261,7 +6504,7 @@ { "Zp", +1, Zp_range16, 1, 0, 0 }, { "Zs", +1, Zs_range16, 7, 0, 0 }, }; -const int num_unicode_groups = 192; +const int num_unicode_groups = 199; } // namespace re2 diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/walker-inl.h src/re2/walker-inl.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/walker-inl.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2/walker-inl.h 2023-02-20 19:50:47.000000000 +0100 @@ -148,7 +148,8 @@ if (!stack_.empty()) { LOG(DFATAL) << "Stack not empty."; while (!stack_.empty()) { - delete[] stack_.top().child_args; + if (stack_.top().re->nsub_ > 1) + delete[] stack_.top().child_args; stack_.pop(); } } @@ -169,7 +170,7 @@ for (;;) { T t; s = &stack_.top(); - Regexp* re = s->re; + re = s->re; switch (s->n) { case -1: { if (--max_visits_ < 0) { diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2.pc src/re2.pc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2.pc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2.pc 1970-01-01 01:00:00.000000000 +0100 @@ -1,8 +0,0 @@ -includedir=@includedir@ -libdir=@libdir@ - -Name: re2 -Description: RE2 is a fast, safe, thread-friendly regular expression engine. -Version: 0.0.0 -Cflags: -std=c++11 -pthread -I${includedir} -Libs: -pthread -L${libdir} -lre2 diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2.pc.in src/re2.pc.in --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2.pc.in 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2.pc.in 2023-02-20 19:50:47.000000000 +0100 @@ -0,0 +1,9 @@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ + +Name: re2 +Description: RE2 is a fast, safe, thread-friendly regular expression engine. +Requires: @REQUIRES@ +Version: @SONAME@.0.0 +Cflags: -pthread -I${includedir} +Libs: -pthread -L${libdir} -lre2 diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2Config.cmake.in src/re2Config.cmake.in --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2Config.cmake.in 1970-01-01 01:00:00.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/re2Config.cmake.in 2023-02-20 19:50:47.000000000 +0100 @@ -0,0 +1,26 @@ +# Copyright 2022 The RE2 Authors. All Rights Reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +set_and_check(re2_INCLUDE_DIR ${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@) + +if(UNIX) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_dependency(Threads REQUIRED) +endif() + +if(@RE2_USE_ICU@) + find_dependency(ICU REQUIRED COMPONENTS uc) +endif() + +check_required_components(re2) + +if(TARGET re2::re2) + return() +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/re2Targets.cmake) diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/testinstall.cc src/testinstall.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/testinstall.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/testinstall.cc 2023-02-20 19:50:47.000000000 +0100 @@ -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 -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/fuzz.cc src/util/fuzz.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/fuzz.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/fuzz.cc 2023-02-20 19:50:47.000000000 +0100 @@ -10,12 +10,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); int main(int argc, char** argv) { - uint8_t data[32]; - for (int i = 0; i < 32; i++) { - for (int j = 0; j < 32; j++) { + uint8_t data[4096]; + for (int i = 0; i < 4096; i++) { + for (int j = 0; j < 4096; j++) { data[j] = random() & 0xFF; } - LLVMFuzzerTestOneInput(data, 32); + LLVMFuzzerTestOneInput(data, 4096); } return 0; } diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/mutex.h src/util/mutex.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/mutex.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/mutex.h 2023-02-20 19:50:47.000000000 +0100 @@ -10,8 +10,13 @@ * You should assume the locks are *not* re-entrant. */ +#ifdef RE2_NO_THREADS +#include +#define MUTEX_IS_LOCK_COUNTER +#else #ifdef _WIN32 // Requires Windows Vista or Windows Server 2008 at minimum. +#include #if defined(WINVER) && WINVER >= 0x0600 #define MUTEX_IS_WIN32_SRWLOCK #endif @@ -24,17 +29,19 @@ #define MUTEX_IS_PTHREAD_RWLOCK #endif #endif +#endif -#if defined(MUTEX_IS_WIN32_SRWLOCK) -#include +#if defined(MUTEX_IS_LOCK_COUNTER) +typedef int MutexType; +#elif defined(MUTEX_IS_WIN32_SRWLOCK) typedef SRWLOCK MutexType; #elif defined(MUTEX_IS_PTHREAD_RWLOCK) #include #include typedef pthread_rwlock_t MutexType; #else -#include -typedef std::mutex MutexType; +#include +typedef std::shared_mutex MutexType; #endif namespace re2 { @@ -64,9 +71,18 @@ Mutex& operator=(const Mutex&) = delete; }; -#if defined(MUTEX_IS_WIN32_SRWLOCK) +#if defined(MUTEX_IS_LOCK_COUNTER) + +Mutex::Mutex() : mutex_(0) { } +Mutex::~Mutex() { assert(mutex_ == 0); } +void Mutex::Lock() { assert(--mutex_ == -1); } +void Mutex::Unlock() { assert(mutex_++ == -1); } +void Mutex::ReaderLock() { assert(++mutex_ > 0); } +void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } + +#elif defined(MUTEX_IS_WIN32_SRWLOCK) -Mutex::Mutex() { InitializeSRWLock(&mutex_); } +Mutex::Mutex() : mutex_(SRWLOCK_INIT) { } Mutex::~Mutex() { } void Mutex::Lock() { AcquireSRWLockExclusive(&mutex_); } void Mutex::Unlock() { ReleaseSRWLockExclusive(&mutex_); } @@ -95,8 +111,8 @@ Mutex::~Mutex() { } void Mutex::Lock() { mutex_.lock(); } void Mutex::Unlock() { mutex_.unlock(); } -void Mutex::ReaderLock() { Lock(); } // C++11 doesn't have std::shared_mutex. -void Mutex::ReaderUnlock() { Unlock(); } +void Mutex::ReaderLock() { mutex_.lock_shared(); } +void Mutex::ReaderUnlock() { mutex_.unlock_shared(); } #endif diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/pcre.h src/util/pcre.h --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/pcre.h 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/pcre.h 2023-02-20 19:50:47.000000000 +0100 @@ -500,7 +500,7 @@ bool report_errors_; // Silences error logging if false int match_limit_; // Limit on execution resources int stack_limit_; // Limit on stack resources (bytes) - mutable int32_t hit_limit_; // Hit limit during execution (bool) + mutable int hit_limit_; // Hit limit during execution (bool) PCRE(const PCRE&) = delete; PCRE& operator=(const PCRE&) = delete; @@ -555,7 +555,7 @@ // 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 @@ #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) { } diff -Naur qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/rune.cc src/util/rune.cc --- qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/rune.cc 2021-01-20 02:18:42.000000000 +0100 +++ qtwebengine-5.15.9_p20230505/src/3rdparty/chromium/third_party/re2/src/util/rune.cc 2023-02-20 19:50:47.000000000 +0100 @@ -51,7 +51,7 @@ chartorune(Rune *rune, const char *str) { int c, c1, c2, c3; - long l; + Rune l; /* * one character sequence @@ -127,7 +127,7 @@ runetochar(char *str, const Rune *rune) { /* Runes are signed, so convert to unsigned for range check. */ - unsigned long c; + unsigned int c; /* * one character sequence @@ -212,7 +212,7 @@ utflen(const char *s) { int c; - long n; + int n; Rune rune; n = 0; @@ -232,7 +232,7 @@ char* utfrune(const char *s, Rune c) { - long c1; + int c1; Rune r; int n;