├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── COPYING ├── Cargo.toml ├── LICENSE-MIT ├── README.md ├── UNLICENSE ├── pcre2-sys ├── .gitignore ├── COPYING ├── Cargo.toml ├── LICENSE-MIT ├── README.md ├── UNLICENSE ├── build.rs ├── generate-bindings ├── src │ ├── bindings.rs │ ├── lib.rs │ └── tests.rs ├── update-pcre2 └── upstream │ ├── include │ ├── config.h │ └── pcre2.h │ └── src │ ├── pcre2_auto_possess.c │ ├── pcre2_chartables.c │ ├── pcre2_chkdint.c │ ├── pcre2_compile.c │ ├── pcre2_config.c │ ├── pcre2_context.c │ ├── pcre2_convert.c │ ├── pcre2_dfa_match.c │ ├── pcre2_error.c │ ├── pcre2_extuni.c │ ├── pcre2_find_bracket.c │ ├── pcre2_internal.h │ ├── pcre2_intmodedep.h │ ├── pcre2_jit_compile.c │ ├── pcre2_jit_match.c │ ├── pcre2_jit_misc.c │ ├── pcre2_jit_neon_inc.h │ ├── pcre2_jit_simd_inc.h │ ├── pcre2_maketables.c │ ├── pcre2_match.c │ ├── pcre2_match_data.c │ ├── pcre2_newline.c │ ├── pcre2_ord2utf.c │ ├── pcre2_pattern_info.c │ ├── pcre2_script_run.c │ ├── pcre2_serialize.c │ ├── pcre2_string_utils.c │ ├── pcre2_study.c │ ├── pcre2_substitute.c │ ├── pcre2_substring.c │ ├── pcre2_tables.c │ ├── pcre2_ucd.c │ ├── pcre2_ucp.h │ ├── pcre2_ucptables.c │ ├── pcre2_valid_utf.c │ ├── pcre2_xclass.c │ ├── pcre2posix.h │ └── sljit │ ├── allocator_src │ ├── sljitExecAllocatorApple.c │ ├── sljitExecAllocatorCore.c │ ├── sljitExecAllocatorFreeBSD.c │ ├── sljitExecAllocatorPosix.c │ ├── sljitExecAllocatorWindows.c │ ├── sljitProtExecAllocatorNetBSD.c │ ├── sljitProtExecAllocatorPosix.c │ ├── sljitWXExecAllocatorPosix.c │ └── sljitWXExecAllocatorWindows.c │ ├── sljitConfig.h │ ├── sljitConfigCPU.h │ ├── sljitConfigInternal.h │ ├── sljitLir.c │ ├── sljitLir.h │ ├── sljitNativeARM_32.c │ ├── sljitNativeARM_64.c │ ├── sljitNativeARM_T2_32.c │ ├── sljitNativeLOONGARCH_64.c │ ├── sljitNativeMIPS_32.c │ ├── sljitNativeMIPS_64.c │ ├── sljitNativeMIPS_common.c │ ├── sljitNativePPC_32.c │ ├── sljitNativePPC_64.c │ ├── sljitNativePPC_common.c │ ├── sljitNativeRISCV_32.c │ ├── sljitNativeRISCV_64.c │ ├── sljitNativeRISCV_common.c │ ├── sljitNativeS390X.c │ ├── sljitNativeX86_32.c │ ├── sljitNativeX86_64.c │ ├── sljitNativeX86_common.c │ └── sljitUtils.c ├── rustfmt.toml └── src ├── bytes.rs ├── error.rs ├── ffi.rs ├── lib.rs └── pool.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [BurntSushi] 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '00 01 * * *' 9 | jobs: 10 | test: 11 | name: test 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | build: 16 | - pinned 17 | - stable 18 | - beta 19 | - nightly 20 | - macos 21 | - win-msvc 22 | - win-gnu 23 | include: 24 | - build: pinned 25 | os: ubuntu-latest 26 | rust: 1.70.0 27 | - build: stable 28 | os: ubuntu-latest 29 | rust: stable 30 | - build: beta 31 | os: ubuntu-latest 32 | rust: beta 33 | - build: nightly 34 | os: ubuntu-latest 35 | rust: nightly 36 | - build: macos 37 | os: macos-latest 38 | rust: stable 39 | - build: win-msvc 40 | os: windows-latest 41 | rust: stable 42 | - build: win-gnu 43 | os: windows-latest 44 | rust: stable-x86_64-gnu 45 | steps: 46 | - name: Checkout repository 47 | uses: actions/checkout@v3 48 | - name: Install Rust 49 | uses: dtolnay/rust-toolchain@master 50 | with: 51 | toolchain: ${{ matrix.rust }} 52 | - name: Build 53 | run: cargo build --verbose --all 54 | - name: Build docs 55 | run: cargo doc --verbose --all 56 | - name: Run tests 57 | run: cargo test --verbose --all 58 | - name: Run tests with static build 59 | shell: bash 60 | run: PCRE2_SYS_STATIC=1 cargo test --verbose --all 61 | 62 | rustfmt: 63 | name: rustfmt 64 | runs-on: ubuntu-latest 65 | steps: 66 | - name: Checkout repository 67 | uses: actions/checkout@v3 68 | - name: Install Rust 69 | uses: dtolnay/rust-toolchain@master 70 | with: 71 | toolchain: stable 72 | components: rustfmt 73 | - name: Check formatting 74 | run: | 75 | cargo fmt --all -- --check 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /pcre2-sys/target 3 | **/*.rs.bk 4 | Cargo.lock 5 | tags 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BurntSushi/rust-pcre2/df0aff50040ed6159e04e0d8e0d9f2d15e1140cf/.gitmodules -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | This project is dual-licensed under the Unlicense and MIT licenses. 2 | 3 | You may use this code under the terms of either license. 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pcre2" 3 | version = "0.2.9" #:version 4 | authors = ["Andrew Gallant "] 5 | description = "High level wrapper library for PCRE2." 6 | documentation = "https://docs.rs/pcre2" 7 | homepage = "https://github.com/BurntSushi/rust-pcre2" 8 | repository = "https://github.com/BurntSushi/rust-pcre2" 9 | readme = "README.md" 10 | keywords = ["pcre", "pcre2", "regex", "jit", "perl"] 11 | license = "Unlicense OR MIT" 12 | categories = ["text-processing"] 13 | edition = "2021" 14 | 15 | [workspace] 16 | members = ["pcre2-sys"] 17 | 18 | [dependencies] 19 | libc = "0.2.146" 20 | log = "0.4.19" 21 | pcre2-sys = { version = "0.2.9", path = "pcre2-sys" } 22 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Andrew Gallant 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pcre2 2 | ===== 3 | A high level Rust wrapper library for [PCRE2](https://www.pcre.org/). 4 | 5 | [![Build status](https://github.com/BurntSushi/rust-pcre2/workflows/ci/badge.svg)](https://github.com/BurntSushi/rust-pcre2/actions) 6 | [![crates.io](https://img.shields.io/crates/v/pcre2.svg)](https://crates.io/crates/pcre2) 7 | 8 | Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/). 9 | 10 | 11 | ### Documentation 12 | 13 | https://docs.rs/pcre2 14 | 15 | 16 | ### Usage 17 | 18 | Run `cargo add pcre2` to add this crate to your `Cargo.toml` file. 19 | 20 | 21 | ### Notes 22 | 23 | Currently, this is a fairly light layer around PCRE2 itself and does not even 24 | come close to covering all of its functionality. There are no specific plans 25 | in place to build out the wrapper further, but PRs for making more of PCRE2 26 | available are welcome, although my bandwidth for maintenance is limited. If 27 | you're interested in sharing this maintenance burden, please reach out. 28 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /pcre2-sys/.gitignore: -------------------------------------------------------------------------------- 1 | /tmp 2 | -------------------------------------------------------------------------------- /pcre2-sys/COPYING: -------------------------------------------------------------------------------- 1 | This project is dual-licensed under the Unlicense and MIT licenses. 2 | 3 | You may use this code under the terms of either license. 4 | -------------------------------------------------------------------------------- /pcre2-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pcre2-sys" 3 | version = "0.2.9" #:version 4 | authors = ["Andrew Gallant "] 5 | description = "Low level bindings to PCRE2." 6 | documentation = "https://docs.rs/pcre2-sys" 7 | homepage = "https://github.com/BurntSushi/rust-pcre2" 8 | repository = "https://github.com/BurntSushi/rust-pcre2" 9 | readme = "README.md" 10 | keywords = ["pcre", "pcre2", "regex", "jit"] 11 | license = "Unlicense OR MIT" 12 | categories = ["external-ffi-bindings"] 13 | edition = "2021" 14 | 15 | [dependencies] 16 | libc = "0.2.146" 17 | 18 | [build-dependencies] 19 | cc = { version = "1.0.73", features = ["parallel"] } 20 | pkg-config = "0.3.27" 21 | -------------------------------------------------------------------------------- /pcre2-sys/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Andrew Gallant 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /pcre2-sys/README.md: -------------------------------------------------------------------------------- 1 | pcre2-sys 2 | ========= 3 | Bindings for [PCRE2](https://www.pcre.org/). 4 | 5 | [![Build status](https://github.com/BurntSushi/rust-pcre2/workflows/ci/badge.svg)](https://github.com/BurntSushi/rust-pcre2/actions) 6 | [![crates.io](https://img.shields.io/crates/v/pcre2-sys.svg)](https://crates.io/crates/pcre2-sys) 7 | 8 | Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/). 9 | 10 | 11 | ### Documentation 12 | 13 | https://docs.rs/pcre2-sys 14 | 15 | 16 | ### Usage 17 | 18 | Run `cargo add pcre2-sys` to add this crate to your `Cargo.toml` file. 19 | 20 | 21 | ### Notes 22 | 23 | As a `-sys` crate, this exposes only the bindings to PCRE2 based on the header 24 | file. The PCRE2 documentation itself should be consulted in order to use this 25 | crate. 26 | 27 | The bindings for this crate were generated for PCRE **10.42**. This crate 28 | intends to track the current release of PCRE2. 29 | 30 | The build script for this crate prefers dynamically linking with the host's 31 | PCRE2 system library. If that isn't available or if static linking is desired, 32 | then PCRE2 is built from source and statically linked. 33 | 34 | Static linking will automatically happen for MUSL targets, but can be forced by 35 | setting the `PCRE2_SYS_STATIC` environment variable to `1`. Similarly, if 36 | `PCRE2_SYS_STATIC` is set to `0`, then static linking will be forcefully 37 | disabled, even for MUSL targets. 38 | 39 | Currently, this crate only supports `libpcre-8` where 40 | `PCRE2_CODE_UNIT_WIDTH=8`. 41 | 42 | This crate has been tested to work on Windows, Linux and macOS. Other platforms 43 | may work, and PRs to support them are welcome. 44 | 45 | If you're compiling this crate on Windows with the GNU toolchain, then you'll 46 | need to make sure you have a compatible C compiler installed, such as the one 47 | provided by the [MinGW-w64](https://www.mingw-w64.org/) project. 48 | 49 | Set the `PCRE2_SYS_DEBUG` flag to forcefully enable debug symbols when doing a 50 | static build, even when compiling in release mode. 51 | -------------------------------------------------------------------------------- /pcre2-sys/UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /pcre2-sys/build.rs: -------------------------------------------------------------------------------- 1 | // The build for pcre2-sys currently does roughly the following: 2 | // 3 | // 1. Use the PCRE2 system library as reported by pkg-config if it exists 4 | // and only if we don't explicitly want a static build. 5 | // 2. Otherwise, statically build PCRE2 by hand. 6 | // 7 | // For step 1, we permit opting out of using the system library via either 8 | // explicitly setting the PCRE2_SYS_STATIC environment variable or if we 9 | // otherwise believe we want a static build (e.g., when building with MUSL). 10 | // 11 | // For step 2, we roughly follow the directions as laid out in 12 | // pcre2/NON-AUTOTOOLS-BUILD. It's pretty straight-forward: copy a few files, 13 | // set a few defines and then build it. We can get away with a pretty stripped 14 | // down setup here since the PCRE2 build setup also handles various command 15 | // line tools (like pcre2grep) and its test infrastructure, and we needn't 16 | // concern ourselves with that. 17 | // 18 | // It is plausible that this build script will need to evolve to do better 19 | // platform detection for the various PCRE2 settings, but this should work 20 | // as-is on Windows, Linux and macOS. 21 | 22 | use std::path::PathBuf; 23 | 24 | fn main() { 25 | println!("cargo:rerun-if-env-changed=PCRE2_SYS_STATIC"); 26 | 27 | let target = std::env::var("TARGET").unwrap(); 28 | // let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); 29 | let upstream = PathBuf::from("upstream"); 30 | 31 | // Don't link to a system library if we want a static build. 32 | let want_static = pcre2_sys_static().unwrap_or(target.contains("musl")); 33 | if !want_static && pkg_config::probe_library("libpcre2-8").is_ok() { 34 | return; 35 | } 36 | 37 | // Set some config options. We mostly just use the default values. We do 38 | // this in lieu of patching config.h since it's easier. 39 | let mut builder = cc::Build::new(); 40 | builder 41 | .define("PCRE2_CODE_UNIT_WIDTH", "8") 42 | .define("HAVE_STDLIB_H", "1") 43 | .define("HAVE_MEMMOVE", "1") 44 | .define("HAVE_CONFIG_H", "1") 45 | .define("PCRE2_STATIC", "1") 46 | .define("STDC_HEADERS", "1") 47 | .define("SUPPORT_PCRE2_8", "1") 48 | .define("SUPPORT_UNICODE", "1"); 49 | if target.contains("windows") { 50 | builder.define("HAVE_WINDOWS_H", "1"); 51 | } 52 | enable_jit(&target, &mut builder); 53 | 54 | builder.include(upstream.join("src")).include(upstream.join("include")); 55 | for result in std::fs::read_dir(upstream.join("src")).unwrap() { 56 | let dent = result.unwrap(); 57 | let path = dent.path(); 58 | if path.extension().map_or(true, |ext| ext != "c") { 59 | continue; 60 | } 61 | // Apparently PCRE2 doesn't want to compile these directly, but only as 62 | // included from pcre2_jit_compile.c. 63 | // 64 | // ... and also pcre2_ucptables.c, which is included by pcre2_tables.c. 65 | // This is despite NON-AUTOTOOLS-BUILD instructions saying that 66 | // pcre2_ucptables.c should be compiled directly. 67 | if path.ends_with("pcre2_jit_match.c") 68 | || path.ends_with("pcre2_jit_misc.c") 69 | || path.ends_with("pcre2_ucptables.c") 70 | { 71 | continue; 72 | } 73 | builder.file(path); 74 | } 75 | 76 | if std::env::var("PCRE2_SYS_DEBUG").unwrap_or(String::new()) == "1" 77 | || std::env::var("DEBUG").unwrap_or(String::new()) == "1" 78 | { 79 | builder.debug(true); 80 | } 81 | builder.compile("libpcre2.a"); 82 | } 83 | 84 | fn pcre2_sys_static() -> Option { 85 | match std::env::var("PCRE2_SYS_STATIC") { 86 | Err(_) => None, 87 | Ok(s) => { 88 | if s == "1" { 89 | Some(true) 90 | } else if s == "0" { 91 | Some(false) 92 | } else { 93 | None 94 | } 95 | } 96 | } 97 | } 98 | 99 | // On `aarch64-apple-ios` clang fails with the following error. 100 | // 101 | // Undefined symbols for architecture arm64: 102 | // "___clear_cache", referenced from: 103 | // _sljit_generate_code in libforeign.a(pcre2_jit_compile.o) 104 | // ld: symbol(s) not found for architecture arm64 105 | // 106 | // aarch64-apple-tvos https://bugreports.qt.io/browse/QTBUG-62993?gerritReviewStatus=All 107 | // aarch64-apple-darwin https://github.com/Homebrew/homebrew-core/pull/57419 108 | // x86_64-apple-ios disabled for device–simulator consistency (not tested) 109 | // x86_64-apple-tvos disabled for device–simulator consistency (not tested) 110 | // armv7-apple-ios assumed equivalent to aarch64-apple-ios (not tested) 111 | // armv7s-apple-ios assumed equivalent to aarch64-apple-ios (not tested) 112 | // i386-apple-ios assumed equivalent to aarch64-apple-ios (not tested) 113 | // x86_64-apple-ios-macabi disabled out of caution (not tested) (needs attention) 114 | // aarch64-linux-android does not build 115 | // armv7-linux-androideabi does not build 116 | // aarch64-unknown-linux-musl does not build 117 | // *-*-*-musleabi* does not build 118 | // 119 | // We may want to monitor developments on the `aarch64-apple-darwin` front as 120 | // they may end up propagating to all `aarch64`-based targets and the `x86_64` 121 | // equivalents. 122 | fn enable_jit(target: &str, builder: &mut cc::Build) { 123 | if target.starts_with("aarch64-apple") { 124 | return; 125 | } 126 | if target == "aarch64-linux-android" { 127 | return; 128 | } 129 | if target == "armv7-linux-androideabi" { 130 | return; 131 | } 132 | if target == "aarch64-unknown-linux-musl" { 133 | return; 134 | } 135 | if target.contains("musleabi") { 136 | return; 137 | } 138 | if target.contains("apple-ios") || target.contains("apple-tvos") { 139 | return; 140 | } 141 | builder.define("SUPPORT_JIT", "1"); 142 | } 143 | -------------------------------------------------------------------------------- /pcre2-sys/generate-bindings: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | : "${PCRE2SYS_HEADER:=/usr/include/pcre2.h}" 4 | : "${PCRE2SYS_BINDINGS:=./src/bindings.rs}" 5 | 6 | if ! command -V bindgen > /dev/null 2>&1; then 7 | echo "bindgen must be installed" >&2 8 | echo "to install: cargo install bindgen-cli" >&2 9 | exit 1 10 | fi 11 | if ! [ -f "$PCRE2SYS_HEADER" ]; then 12 | echo "PCRE2 header file at $PCRE2SYS_HEADER does not exist" >&2 13 | echo "Use the PCRE2SYS_HEADER environment variable to override path" >&2 14 | exit 1 15 | fi 16 | 17 | bindgen \ 18 | "$PCRE2SYS_HEADER" \ 19 | --ctypes-prefix '::libc' \ 20 | --allowlist-function '^pcre2_.*' \ 21 | --allowlist-type '^pcre2_.*' \ 22 | --allowlist-var '^PCRE2_.*' \ 23 | --blocklist-function '^.*_callout_.*' \ 24 | --blocklist-type '^.*_callout_.*' \ 25 | -- -DPCRE2_CODE_UNIT_WIDTH=8 > "$PCRE2SYS_BINDINGS" 26 | -------------------------------------------------------------------------------- /pcre2-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] 2 | 3 | pub use crate::bindings::*; 4 | 5 | mod bindings; 6 | #[cfg(test)] 7 | mod tests; 8 | 9 | // It is weird that this isn't caught by bindgen. Dunno why. 10 | pub const PCRE2_UNSET: usize = ::std::usize::MAX; 11 | -------------------------------------------------------------------------------- /pcre2-sys/src/tests.rs: -------------------------------------------------------------------------------- 1 | use std::ptr; 2 | 3 | use crate::bindings::*; 4 | 5 | #[test] 6 | fn itworks() { 7 | let mut error_code = 0; 8 | let mut error_offset = 0; 9 | let pattern = r"\w+"; 10 | let code = unsafe { 11 | pcre2_compile_8( 12 | pattern.as_ptr(), 13 | pattern.len(), 14 | PCRE2_UCP | PCRE2_UTF, 15 | &mut error_code, 16 | &mut error_offset, 17 | ptr::null_mut(), 18 | ) 19 | }; 20 | if code.is_null() { 21 | panic!( 22 | "compilation failed; error code: {:?}, offset: {:?}", 23 | error_code, error_offset 24 | ); 25 | } 26 | 27 | let match_data = unsafe { 28 | pcre2_match_data_create_from_pattern_8(code, ptr::null_mut()) 29 | }; 30 | if match_data.is_null() { 31 | unsafe { 32 | pcre2_code_free_8(code); 33 | } 34 | panic!("could not allocate match_data"); 35 | } 36 | 37 | let ovector = unsafe { pcre2_get_ovector_pointer_8(match_data) }; 38 | if ovector.is_null() { 39 | unsafe { 40 | pcre2_match_data_free_8(match_data); 41 | pcre2_code_free_8(code); 42 | } 43 | panic!("could not get ovector"); 44 | } 45 | 46 | let subject = " βabcβ foo"; 47 | let rc = unsafe { 48 | pcre2_match_8( 49 | code, 50 | subject.as_ptr(), 51 | subject.len(), 52 | 0, 53 | 0, 54 | match_data, 55 | ptr::null_mut(), 56 | ) 57 | }; 58 | if rc <= 0 { 59 | unsafe { 60 | pcre2_match_data_free_8(match_data); 61 | pcre2_code_free_8(code); 62 | } 63 | panic!("error executing match"); 64 | } 65 | 66 | let (s, e) = unsafe { (*ovector.offset(0), *ovector.offset(1)) }; 67 | unsafe { 68 | pcre2_match_data_free_8(match_data); 69 | pcre2_code_free_8(code); 70 | } 71 | 72 | assert_eq!("βabcβ", &subject[s..e]); 73 | } 74 | -------------------------------------------------------------------------------- /pcre2-sys/update-pcre2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script downloads a specific release of PCRE2, extracts it and copies 4 | # the necessary files to $dest. The actual compilation of PCRE2 happens in 5 | # build.rs. Note that a new release of PCRE2 may require more changes than 6 | # simply updating the version. Namely, we exhaustively enumerate the files that 7 | # need to be copied below. This way, we only vendor into source control what is 8 | # actually necessary for building PCRE2. 9 | 10 | pcre2_sys_dir="$(dirname "$0")" 11 | cd "$pcre2_sys_dir" 12 | 13 | dest="upstream" 14 | version="10.43" 15 | dir="pcre2-$version" 16 | archive="$dir.tar.gz" 17 | url="https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$version/$archive" 18 | work="tmp/updates/pcre2-$version" 19 | 20 | mkdir -p "$work" 21 | curl -L "$url" > "$work/$archive" 22 | (cd "$work" && tar xf "$archive") 23 | 24 | upstream="$work/$dir" 25 | rm -rf "$dest"/{src,include} 26 | mkdir -p "$dest"/{src,include} 27 | 28 | needed=( 29 | pcre2_auto_possess.c 30 | pcre2_chkdint.c 31 | pcre2_compile.c 32 | pcre2_config.c 33 | pcre2_context.c 34 | pcre2_convert.c 35 | pcre2_dfa_match.c 36 | pcre2_error.c 37 | pcre2_extuni.c 38 | pcre2_find_bracket.c 39 | pcre2_jit_compile.c 40 | pcre2_jit_match.c 41 | pcre2_jit_misc.c 42 | pcre2_maketables.c 43 | pcre2_match.c 44 | pcre2_match_data.c 45 | pcre2_newline.c 46 | pcre2_ord2utf.c 47 | pcre2_pattern_info.c 48 | pcre2_script_run.c 49 | pcre2_serialize.c 50 | pcre2_string_utils.c 51 | pcre2_study.c 52 | pcre2_substitute.c 53 | pcre2_substring.c 54 | pcre2_tables.c 55 | pcre2_ucd.c 56 | pcre2_ucptables.c 57 | pcre2_valid_utf.c 58 | pcre2_xclass.c 59 | 60 | pcre2_internal.h 61 | pcre2_intmodedep.h 62 | pcre2_jit_neon_inc.h 63 | pcre2_jit_simd_inc.h 64 | pcre2posix.h 65 | pcre2_ucp.h 66 | ) 67 | for name in "${needed[@]}"; do 68 | cp "$upstream/src/$name" "$dest/src/" 69 | done 70 | cp "$upstream/src/pcre2_chartables.c.dist" "$dest/src/pcre2_chartables.c" 71 | cp -a "$upstream/src/sljit" "$dest/src/" 72 | cp "$upstream/src/config.h.generic" "$dest/include/config.h" 73 | cp "$upstream/src/pcre2.h.generic" "$dest/include/pcre2.h" 74 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_chartables.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* This file was automatically written by the pcre2_dftables auxiliary 6 | program. It contains character tables that are used when no external 7 | tables are passed to PCRE2 by the application that calls it. The tables 8 | are used only for characters whose code values are less than 256, and 9 | only relevant if not in UCP mode. */ 10 | 11 | /* This set of tables was written in the C locale. */ 12 | 13 | /* The pcre2_ftables program (which is distributed with PCRE2) can be used 14 | to build alternative versions of this file. This is necessary if you are 15 | running in an EBCDIC environment, or if you want to default to a different 16 | encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates 17 | these tables in the "C" locale by default. This happens automatically if 18 | PCRE2 is configured with --enable-rebuild-chartables. However, you can run 19 | pcre2_dftables manually with the -L option to build tables using the LC_ALL 20 | locale. */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include "pcre2_internal.h" 27 | 28 | const uint8_t PRIV(default_tables)[] = { 29 | 30 | /* This table is a lower casing table. */ 31 | 32 | 0, 1, 2, 3, 4, 5, 6, 7, 33 | 8, 9, 10, 11, 12, 13, 14, 15, 34 | 16, 17, 18, 19, 20, 21, 22, 23, 35 | 24, 25, 26, 27, 28, 29, 30, 31, 36 | 32, 33, 34, 35, 36, 37, 38, 39, 37 | 40, 41, 42, 43, 44, 45, 46, 47, 38 | 48, 49, 50, 51, 52, 53, 54, 55, 39 | 56, 57, 58, 59, 60, 61, 62, 63, 40 | 64, 97, 98, 99,100,101,102,103, 41 | 104,105,106,107,108,109,110,111, 42 | 112,113,114,115,116,117,118,119, 43 | 120,121,122, 91, 92, 93, 94, 95, 44 | 96, 97, 98, 99,100,101,102,103, 45 | 104,105,106,107,108,109,110,111, 46 | 112,113,114,115,116,117,118,119, 47 | 120,121,122,123,124,125,126,127, 48 | 128,129,130,131,132,133,134,135, 49 | 136,137,138,139,140,141,142,143, 50 | 144,145,146,147,148,149,150,151, 51 | 152,153,154,155,156,157,158,159, 52 | 160,161,162,163,164,165,166,167, 53 | 168,169,170,171,172,173,174,175, 54 | 176,177,178,179,180,181,182,183, 55 | 184,185,186,187,188,189,190,191, 56 | 192,193,194,195,196,197,198,199, 57 | 200,201,202,203,204,205,206,207, 58 | 208,209,210,211,212,213,214,215, 59 | 216,217,218,219,220,221,222,223, 60 | 224,225,226,227,228,229,230,231, 61 | 232,233,234,235,236,237,238,239, 62 | 240,241,242,243,244,245,246,247, 63 | 248,249,250,251,252,253,254,255, 64 | 65 | /* This table is a case flipping table. */ 66 | 67 | 0, 1, 2, 3, 4, 5, 6, 7, 68 | 8, 9, 10, 11, 12, 13, 14, 15, 69 | 16, 17, 18, 19, 20, 21, 22, 23, 70 | 24, 25, 26, 27, 28, 29, 30, 31, 71 | 32, 33, 34, 35, 36, 37, 38, 39, 72 | 40, 41, 42, 43, 44, 45, 46, 47, 73 | 48, 49, 50, 51, 52, 53, 54, 55, 74 | 56, 57, 58, 59, 60, 61, 62, 63, 75 | 64, 97, 98, 99,100,101,102,103, 76 | 104,105,106,107,108,109,110,111, 77 | 112,113,114,115,116,117,118,119, 78 | 120,121,122, 91, 92, 93, 94, 95, 79 | 96, 65, 66, 67, 68, 69, 70, 71, 80 | 72, 73, 74, 75, 76, 77, 78, 79, 81 | 80, 81, 82, 83, 84, 85, 86, 87, 82 | 88, 89, 90,123,124,125,126,127, 83 | 128,129,130,131,132,133,134,135, 84 | 136,137,138,139,140,141,142,143, 85 | 144,145,146,147,148,149,150,151, 86 | 152,153,154,155,156,157,158,159, 87 | 160,161,162,163,164,165,166,167, 88 | 168,169,170,171,172,173,174,175, 89 | 176,177,178,179,180,181,182,183, 90 | 184,185,186,187,188,189,190,191, 91 | 192,193,194,195,196,197,198,199, 92 | 200,201,202,203,204,205,206,207, 93 | 208,209,210,211,212,213,214,215, 94 | 216,217,218,219,220,221,222,223, 95 | 224,225,226,227,228,229,230,231, 96 | 232,233,234,235,236,237,238,239, 97 | 240,241,242,243,244,245,246,247, 98 | 248,249,250,251,252,253,254,255, 99 | 100 | /* This table contains bit maps for various character classes. Each map is 32 101 | bytes long and the bits run from the least significant end of each byte. The 102 | classes that have their own maps are: space, xdigit, digit, upper, lower, word, 103 | graph, print, punct, and cntrl. Other classes are built from combinations. */ 104 | 105 | 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, /* space */ 106 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 107 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 108 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 109 | 110 | 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* xdigit */ 111 | 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 112 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 113 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 114 | 115 | 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* digit */ 116 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 117 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 118 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 119 | 120 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* upper */ 121 | 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 122 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 123 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 124 | 125 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* lower */ 126 | 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 127 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 128 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 129 | 130 | 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* word */ 131 | 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 132 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 133 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 134 | 135 | 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, /* graph */ 136 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 137 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 138 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 139 | 140 | 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, /* print */ 141 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 142 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 143 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 144 | 145 | 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, /* punct */ 146 | 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 147 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 148 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 149 | 150 | 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, /* cntrl */ 151 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 152 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 153 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 154 | 155 | /* This table identifies various classes of character by individual bits: 156 | 0x01 white space character 157 | 0x02 letter 158 | 0x04 lower case letter 159 | 0x08 decimal digit 160 | 0x10 word (alphanumeric or '_') 161 | */ 162 | 163 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 164 | 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ 165 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 166 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 167 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ 168 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ 169 | 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0 - 7 */ 170 | 0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ 171 | 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* @ - G */ 172 | 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 173 | 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 174 | 0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x10, /* X - _ */ 175 | 0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* ` - g */ 176 | 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* h - o */ 177 | 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* p - w */ 178 | 0x16,0x16,0x16,0x00,0x00,0x00,0x00,0x00, /* x -127 */ 179 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 180 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 181 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 182 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 183 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 184 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 185 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 186 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 187 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 188 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 189 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 190 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 191 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 192 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 193 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 194 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ 195 | 196 | /* End of pcre2_chartables.c */ 197 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_chkdint.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Copyright (c) 2023 University of Cambridge 10 | 11 | ----------------------------------------------------------------------------- 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, 16 | this list of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | 22 | * Neither the name of the University of Cambridge nor the names of its 23 | contributors may be used to endorse or promote products derived from 24 | this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 27 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 30 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | POSSIBILITY OF SUCH DAMAGE. 37 | ----------------------------------------------------------------------------- 38 | */ 39 | 40 | /* This file contains functions to implement checked integer operation */ 41 | 42 | #ifndef PCRE2_PCRE2TEST 43 | #ifdef HAVE_CONFIG_H 44 | #include "config.h" 45 | #endif 46 | 47 | #include "pcre2_internal.h" 48 | #endif 49 | 50 | /************************************************* 51 | * Checked Integer Multiplication * 52 | *************************************************/ 53 | 54 | /* 55 | Arguments: 56 | r A pointer to PCRE2_SIZE to store the answer 57 | a, b Two integers 58 | 59 | Returns: Bool indicating if the operation overflows 60 | 61 | It is modeled after C23's interface 62 | The INT64_OR_DOUBLE type is a 64-bit integer type when available, 63 | otherwise double. */ 64 | 65 | BOOL 66 | PRIV(ckd_smul)(PCRE2_SIZE *r, int a, int b) 67 | { 68 | #ifdef HAVE_BUILTIN_MUL_OVERFLOW 69 | PCRE2_SIZE m; 70 | 71 | if (__builtin_mul_overflow(a, b, &m)) return TRUE; 72 | 73 | *r = m; 74 | #else 75 | INT64_OR_DOUBLE m; 76 | 77 | #ifdef PCRE2_DEBUG 78 | if (a < 0 || b < 0) abort(); 79 | #endif 80 | 81 | m = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b; 82 | 83 | #if defined INT64_MAX || defined int64_t 84 | if (sizeof(m) > sizeof(*r) && m > (INT64_OR_DOUBLE)PCRE2_SIZE_MAX) return TRUE; 85 | *r = (PCRE2_SIZE)m; 86 | #else 87 | if (m > PCRE2_SIZE_MAX) return TRUE; 88 | *r = m; 89 | #endif 90 | 91 | #endif 92 | 93 | return FALSE; 94 | } 95 | 96 | /* End of pcre_chkdint.c */ 97 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_config.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2020 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | #ifdef HAVE_CONFIG_H 42 | #include "config.h" 43 | #endif 44 | 45 | /* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes 46 | its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to 47 | be in code units. */ 48 | 49 | static int configured_link_size = LINK_SIZE; 50 | 51 | #include "pcre2_internal.h" 52 | 53 | /* These macros are the standard way of turning unquoted text into C strings. 54 | They allow macros like PCRE2_MAJOR to be defined without quotes, which is 55 | convenient for user programs that want to test their values. */ 56 | 57 | #define STRING(a) # a 58 | #define XSTRING(s) STRING(s) 59 | 60 | 61 | /************************************************* 62 | * Return info about what features are configured * 63 | *************************************************/ 64 | 65 | /* If where is NULL, the length of memory required is returned. 66 | 67 | Arguments: 68 | what what information is required 69 | where where to put the information 70 | 71 | Returns: 0 if a numerical value is returned 72 | >= 0 if a string value 73 | PCRE2_ERROR_BADOPTION if "where" not recognized 74 | or JIT target requested when JIT not enabled 75 | */ 76 | 77 | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION 78 | pcre2_config(uint32_t what, void *where) 79 | { 80 | if (where == NULL) /* Requests a length */ 81 | { 82 | switch(what) 83 | { 84 | default: 85 | return PCRE2_ERROR_BADOPTION; 86 | 87 | case PCRE2_CONFIG_BSR: 88 | case PCRE2_CONFIG_COMPILED_WIDTHS: 89 | case PCRE2_CONFIG_DEPTHLIMIT: 90 | case PCRE2_CONFIG_HEAPLIMIT: 91 | case PCRE2_CONFIG_JIT: 92 | case PCRE2_CONFIG_LINKSIZE: 93 | case PCRE2_CONFIG_MATCHLIMIT: 94 | case PCRE2_CONFIG_NEVER_BACKSLASH_C: 95 | case PCRE2_CONFIG_NEWLINE: 96 | case PCRE2_CONFIG_PARENSLIMIT: 97 | case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */ 98 | case PCRE2_CONFIG_TABLES_LENGTH: 99 | case PCRE2_CONFIG_UNICODE: 100 | return sizeof(uint32_t); 101 | 102 | /* These are handled below */ 103 | 104 | case PCRE2_CONFIG_JITTARGET: 105 | case PCRE2_CONFIG_UNICODE_VERSION: 106 | case PCRE2_CONFIG_VERSION: 107 | break; 108 | } 109 | } 110 | 111 | switch (what) 112 | { 113 | default: 114 | return PCRE2_ERROR_BADOPTION; 115 | 116 | case PCRE2_CONFIG_BSR: 117 | #ifdef BSR_ANYCRLF 118 | *((uint32_t *)where) = PCRE2_BSR_ANYCRLF; 119 | #else 120 | *((uint32_t *)where) = PCRE2_BSR_UNICODE; 121 | #endif 122 | break; 123 | 124 | case PCRE2_CONFIG_COMPILED_WIDTHS: 125 | *((uint32_t *)where) = 0 126 | #ifdef SUPPORT_PCRE2_8 127 | + 1 128 | #endif 129 | #ifdef SUPPORT_PCRE2_16 130 | + 2 131 | #endif 132 | #ifdef SUPPORT_PCRE2_32 133 | + 4 134 | #endif 135 | ; 136 | break; 137 | 138 | case PCRE2_CONFIG_DEPTHLIMIT: 139 | *((uint32_t *)where) = MATCH_LIMIT_DEPTH; 140 | break; 141 | 142 | case PCRE2_CONFIG_HEAPLIMIT: 143 | *((uint32_t *)where) = HEAP_LIMIT; 144 | break; 145 | 146 | case PCRE2_CONFIG_JIT: 147 | #ifdef SUPPORT_JIT 148 | *((uint32_t *)where) = 1; 149 | #else 150 | *((uint32_t *)where) = 0; 151 | #endif 152 | break; 153 | 154 | case PCRE2_CONFIG_JITTARGET: 155 | #ifdef SUPPORT_JIT 156 | { 157 | const char *v = PRIV(jit_get_target)(); 158 | return (int)(1 + ((where == NULL)? 159 | strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v))); 160 | } 161 | #else 162 | return PCRE2_ERROR_BADOPTION; 163 | #endif 164 | 165 | case PCRE2_CONFIG_LINKSIZE: 166 | *((uint32_t *)where) = (uint32_t)configured_link_size; 167 | break; 168 | 169 | case PCRE2_CONFIG_MATCHLIMIT: 170 | *((uint32_t *)where) = MATCH_LIMIT; 171 | break; 172 | 173 | case PCRE2_CONFIG_NEWLINE: 174 | *((uint32_t *)where) = NEWLINE_DEFAULT; 175 | break; 176 | 177 | case PCRE2_CONFIG_NEVER_BACKSLASH_C: 178 | #ifdef NEVER_BACKSLASH_C 179 | *((uint32_t *)where) = 1; 180 | #else 181 | *((uint32_t *)where) = 0; 182 | #endif 183 | break; 184 | 185 | case PCRE2_CONFIG_PARENSLIMIT: 186 | *((uint32_t *)where) = PARENS_NEST_LIMIT; 187 | break; 188 | 189 | /* This is now obsolete. The stack is no longer used via recursion for 190 | handling backtracking in pcre2_match(). */ 191 | 192 | case PCRE2_CONFIG_STACKRECURSE: 193 | *((uint32_t *)where) = 0; 194 | break; 195 | 196 | case PCRE2_CONFIG_TABLES_LENGTH: 197 | *((uint32_t *)where) = TABLES_LENGTH; 198 | break; 199 | 200 | case PCRE2_CONFIG_UNICODE_VERSION: 201 | { 202 | #if defined SUPPORT_UNICODE 203 | const char *v = PRIV(unicode_version); 204 | #else 205 | const char *v = "Unicode not supported"; 206 | #endif 207 | return (int)(1 + ((where == NULL)? 208 | strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v))); 209 | } 210 | break; 211 | 212 | case PCRE2_CONFIG_UNICODE: 213 | #if defined SUPPORT_UNICODE 214 | *((uint32_t *)where) = 1; 215 | #else 216 | *((uint32_t *)where) = 0; 217 | #endif 218 | break; 219 | 220 | /* The hackery in setting "v" below is to cope with the case when 221 | PCRE2_PRERELEASE is set to an empty string (which it is for real releases). 222 | If the second alternative is used in this case, it does not leave a space 223 | before the date. On the other hand, if all four macros are put into a single 224 | XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted. 225 | There are problems using an "obvious" approach like this: 226 | 227 | XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR) 228 | XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE) 229 | 230 | because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion 231 | of STRING(). The C standard states: "If (before argument substitution) any 232 | argument consists of no preprocessing tokens, the behavior is undefined." It 233 | turns out the gcc treats this case as a single empty string - which is what 234 | we really want - but Visual C grumbles about the lack of an argument for the 235 | macro. Unfortunately, both are within their rights. As there seems to be no 236 | way to test for a macro's value being empty at compile time, we have to 237 | resort to a runtime test. */ 238 | 239 | case PCRE2_CONFIG_VERSION: 240 | { 241 | const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)? 242 | XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) : 243 | XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE); 244 | return (int)(1 + ((where == NULL)? 245 | strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v))); 246 | } 247 | } 248 | 249 | return 0; 250 | } 251 | 252 | /* End of pcre2_config.c */ 253 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_extuni.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2021 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | /* This module contains an internal function that is used to match a Unicode 42 | extended grapheme sequence. It is used by both pcre2_match() and 43 | pcre2_def_match(). However, it is called only when Unicode support is being 44 | compiled. Nevertheless, we provide a dummy function when there is no Unicode 45 | support, because some compilers do not like functionless source files. */ 46 | 47 | 48 | #ifdef HAVE_CONFIG_H 49 | #include "config.h" 50 | #endif 51 | 52 | 53 | #include "pcre2_internal.h" 54 | 55 | 56 | /* Dummy function */ 57 | 58 | #ifndef SUPPORT_UNICODE 59 | PCRE2_SPTR 60 | PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject, 61 | PCRE2_SPTR end_subject, BOOL utf, int *xcount) 62 | { 63 | (void)c; 64 | (void)eptr; 65 | (void)start_subject; 66 | (void)end_subject; 67 | (void)utf; 68 | (void)xcount; 69 | return NULL; 70 | } 71 | #else 72 | 73 | 74 | /************************************************* 75 | * Match an extended grapheme sequence * 76 | *************************************************/ 77 | 78 | /* 79 | Arguments: 80 | c the first character 81 | eptr pointer to next character 82 | start_subject pointer to start of subject 83 | end_subject pointer to end of subject 84 | utf TRUE if in UTF mode 85 | xcount pointer to count of additional characters, 86 | or NULL if count not needed 87 | 88 | Returns: pointer after the end of the sequence 89 | */ 90 | 91 | PCRE2_SPTR 92 | PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject, 93 | PCRE2_SPTR end_subject, BOOL utf, int *xcount) 94 | { 95 | int lgb = UCD_GRAPHBREAK(c); 96 | 97 | while (eptr < end_subject) 98 | { 99 | int rgb; 100 | int len = 1; 101 | if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } 102 | rgb = UCD_GRAPHBREAK(c); 103 | if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; 104 | 105 | /* Not breaking between Regional Indicators is allowed only if there 106 | are an even number of preceding RIs. */ 107 | 108 | if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) 109 | { 110 | int ricount = 0; 111 | PCRE2_SPTR bptr = eptr - 1; 112 | if (utf) BACKCHAR(bptr); 113 | 114 | /* bptr is pointing to the left-hand character */ 115 | 116 | while (bptr > start_subject) 117 | { 118 | bptr--; 119 | if (utf) 120 | { 121 | BACKCHAR(bptr); 122 | GETCHAR(c, bptr); 123 | } 124 | else 125 | c = *bptr; 126 | if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; 127 | ricount++; 128 | } 129 | if ((ricount & 1) != 0) break; /* Grapheme break required */ 130 | } 131 | 132 | /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this 133 | allows any number of them before a following Extended_Pictographic. */ 134 | 135 | if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) || 136 | lgb != ucp_gbExtended_Pictographic) 137 | lgb = rgb; 138 | 139 | eptr += len; 140 | if (xcount != NULL) *xcount += 1; 141 | } 142 | 143 | return eptr; 144 | } 145 | 146 | #endif /* SUPPORT_UNICODE */ 147 | 148 | /* End of pcre2_extuni.c */ 149 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_find_bracket.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2023 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | 42 | /* This module contains a single function that scans through a compiled pattern 43 | until it finds a capturing bracket with the given number, or, if the number is 44 | negative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The 45 | function is called from pcre2_compile.c and also from pcre2_study.c when 46 | finding the minimum matching length. */ 47 | 48 | 49 | #ifdef HAVE_CONFIG_H 50 | #include "config.h" 51 | #endif 52 | 53 | #include "pcre2_internal.h" 54 | 55 | 56 | /************************************************* 57 | * Scan compiled regex for specific bracket * 58 | *************************************************/ 59 | 60 | /* 61 | Arguments: 62 | code points to start of expression 63 | utf TRUE in UTF mode 64 | number the required bracket number or negative to find a lookbehind 65 | 66 | Returns: pointer to the opcode for the bracket, or NULL if not found 67 | */ 68 | 69 | PCRE2_SPTR 70 | PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number) 71 | { 72 | for (;;) 73 | { 74 | PCRE2_UCHAR c = *code; 75 | 76 | if (c == OP_END) return NULL; 77 | 78 | /* XCLASS is used for classes that cannot be represented just by a bit map. 79 | This includes negated single high-valued characters. CALLOUT_STR is used for 80 | callouts with string arguments. In both cases the length in the table is 81 | zero; the actual length is stored in the compiled code. */ 82 | 83 | if (c == OP_XCLASS) code += GET(code, 1); 84 | else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); 85 | 86 | /* Handle lookbehind */ 87 | 88 | else if (c == OP_REVERSE || c == OP_VREVERSE) 89 | { 90 | if (number < 0) return (PCRE2_UCHAR *)code; 91 | code += PRIV(OP_lengths)[c]; 92 | } 93 | 94 | /* Handle capturing bracket */ 95 | 96 | else if (c == OP_CBRA || c == OP_SCBRA || 97 | c == OP_CBRAPOS || c == OP_SCBRAPOS) 98 | { 99 | int n = (int)GET2(code, 1+LINK_SIZE); 100 | if (n == number) return (PCRE2_UCHAR *)code; 101 | code += PRIV(OP_lengths)[c]; 102 | } 103 | 104 | /* Otherwise, we can get the item's length from the table, except that for 105 | repeated character types, we have to test for \p and \P, which have an extra 106 | two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we 107 | must add in its length. */ 108 | 109 | else 110 | { 111 | switch(c) 112 | { 113 | case OP_TYPESTAR: 114 | case OP_TYPEMINSTAR: 115 | case OP_TYPEPLUS: 116 | case OP_TYPEMINPLUS: 117 | case OP_TYPEQUERY: 118 | case OP_TYPEMINQUERY: 119 | case OP_TYPEPOSSTAR: 120 | case OP_TYPEPOSPLUS: 121 | case OP_TYPEPOSQUERY: 122 | if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; 123 | break; 124 | 125 | case OP_TYPEUPTO: 126 | case OP_TYPEMINUPTO: 127 | case OP_TYPEEXACT: 128 | case OP_TYPEPOSUPTO: 129 | if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) 130 | code += 2; 131 | break; 132 | 133 | case OP_MARK: 134 | case OP_COMMIT_ARG: 135 | case OP_PRUNE_ARG: 136 | case OP_SKIP_ARG: 137 | case OP_THEN_ARG: 138 | code += code[1]; 139 | break; 140 | } 141 | 142 | /* Add in the fixed length from the table */ 143 | 144 | code += PRIV(OP_lengths)[c]; 145 | 146 | /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be 147 | followed by a multi-byte character. The length in the table is a minimum, so 148 | we have to arrange to skip the extra bytes. */ 149 | 150 | #ifdef MAYBE_UTF_MULTI 151 | if (utf) switch(c) 152 | { 153 | case OP_CHAR: 154 | case OP_CHARI: 155 | case OP_NOT: 156 | case OP_NOTI: 157 | case OP_EXACT: 158 | case OP_EXACTI: 159 | case OP_NOTEXACT: 160 | case OP_NOTEXACTI: 161 | case OP_UPTO: 162 | case OP_UPTOI: 163 | case OP_NOTUPTO: 164 | case OP_NOTUPTOI: 165 | case OP_MINUPTO: 166 | case OP_MINUPTOI: 167 | case OP_NOTMINUPTO: 168 | case OP_NOTMINUPTOI: 169 | case OP_POSUPTO: 170 | case OP_POSUPTOI: 171 | case OP_NOTPOSUPTO: 172 | case OP_NOTPOSUPTOI: 173 | case OP_STAR: 174 | case OP_STARI: 175 | case OP_NOTSTAR: 176 | case OP_NOTSTARI: 177 | case OP_MINSTAR: 178 | case OP_MINSTARI: 179 | case OP_NOTMINSTAR: 180 | case OP_NOTMINSTARI: 181 | case OP_POSSTAR: 182 | case OP_POSSTARI: 183 | case OP_NOTPOSSTAR: 184 | case OP_NOTPOSSTARI: 185 | case OP_PLUS: 186 | case OP_PLUSI: 187 | case OP_NOTPLUS: 188 | case OP_NOTPLUSI: 189 | case OP_MINPLUS: 190 | case OP_MINPLUSI: 191 | case OP_NOTMINPLUS: 192 | case OP_NOTMINPLUSI: 193 | case OP_POSPLUS: 194 | case OP_POSPLUSI: 195 | case OP_NOTPOSPLUS: 196 | case OP_NOTPOSPLUSI: 197 | case OP_QUERY: 198 | case OP_QUERYI: 199 | case OP_NOTQUERY: 200 | case OP_NOTQUERYI: 201 | case OP_MINQUERY: 202 | case OP_MINQUERYI: 203 | case OP_NOTMINQUERY: 204 | case OP_NOTMINQUERYI: 205 | case OP_POSQUERY: 206 | case OP_POSQUERYI: 207 | case OP_NOTPOSQUERY: 208 | case OP_NOTPOSQUERYI: 209 | if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); 210 | break; 211 | } 212 | #else 213 | (void)(utf); /* Keep compiler happy by referencing function argument */ 214 | #endif /* MAYBE_UTF_MULTI */ 215 | } 216 | } 217 | } 218 | 219 | /* End of pcre2_find_bracket.c */ 220 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_jit_match.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2023 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | #ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE 42 | #error This file must be included from pcre2_jit_compile.c. 43 | #endif 44 | 45 | #if defined(__has_feature) 46 | #if __has_feature(memory_sanitizer) 47 | #include 48 | #endif /* __has_feature(memory_sanitizer) */ 49 | #endif /* defined(__has_feature) */ 50 | 51 | #ifdef SUPPORT_JIT 52 | 53 | static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func) 54 | { 55 | sljit_u8 local_space[MACHINE_STACK_SIZE]; 56 | struct sljit_stack local_stack; 57 | 58 | local_stack.min_start = local_space; 59 | local_stack.start = local_space; 60 | local_stack.end = local_space + MACHINE_STACK_SIZE; 61 | local_stack.top = local_space + MACHINE_STACK_SIZE; 62 | arguments->stack = &local_stack; 63 | return executable_func(arguments); 64 | } 65 | 66 | #endif 67 | 68 | 69 | /************************************************* 70 | * Do a JIT pattern match * 71 | *************************************************/ 72 | 73 | /* This function runs a JIT pattern match. 74 | 75 | Arguments: 76 | code points to the compiled expression 77 | subject points to the subject string 78 | length length of subject string (may contain binary zeros) 79 | start_offset where to start in the subject string 80 | options option bits 81 | match_data points to a match_data block 82 | mcontext points to a match context 83 | 84 | Returns: > 0 => success; value is the number of ovector pairs filled 85 | = 0 => success, but ovector is not big enough 86 | -1 => failed to match (PCRE_ERROR_NOMATCH) 87 | < -1 => some kind of unexpected problem 88 | */ 89 | 90 | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION 91 | pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, 92 | PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, 93 | pcre2_match_context *mcontext) 94 | { 95 | #ifndef SUPPORT_JIT 96 | 97 | (void)code; 98 | (void)subject; 99 | (void)length; 100 | (void)start_offset; 101 | (void)options; 102 | (void)match_data; 103 | (void)mcontext; 104 | return PCRE2_ERROR_JIT_BADOPTION; 105 | 106 | #else /* SUPPORT_JIT */ 107 | 108 | pcre2_real_code *re = (pcre2_real_code *)code; 109 | executable_functions *functions = (executable_functions *)re->executable_jit; 110 | pcre2_jit_stack *jit_stack; 111 | uint32_t oveccount = match_data->oveccount; 112 | uint32_t max_oveccount; 113 | union { 114 | void *executable_func; 115 | jit_function call_executable_func; 116 | } convert_executable_func; 117 | jit_arguments arguments; 118 | int rc; 119 | int index = 0; 120 | 121 | if ((options & PCRE2_PARTIAL_HARD) != 0) 122 | index = 2; 123 | else if ((options & PCRE2_PARTIAL_SOFT) != 0) 124 | index = 1; 125 | 126 | if (functions == NULL || functions->executable_funcs[index] == NULL) 127 | return PCRE2_ERROR_JIT_BADOPTION; 128 | 129 | /* Sanity checks should be handled by pcre2_match. */ 130 | arguments.str = subject + start_offset; 131 | arguments.begin = subject; 132 | arguments.end = subject + length; 133 | arguments.match_data = match_data; 134 | arguments.startchar_ptr = subject; 135 | arguments.mark_ptr = NULL; 136 | arguments.options = options; 137 | 138 | if (mcontext != NULL) 139 | { 140 | arguments.callout = mcontext->callout; 141 | arguments.callout_data = mcontext->callout_data; 142 | arguments.offset_limit = mcontext->offset_limit; 143 | arguments.limit_match = (mcontext->match_limit < re->limit_match)? 144 | mcontext->match_limit : re->limit_match; 145 | if (mcontext->jit_callback != NULL) 146 | jit_stack = mcontext->jit_callback(mcontext->jit_callback_data); 147 | else 148 | jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data; 149 | } 150 | else 151 | { 152 | arguments.callout = NULL; 153 | arguments.callout_data = NULL; 154 | arguments.offset_limit = PCRE2_UNSET; 155 | arguments.limit_match = (MATCH_LIMIT < re->limit_match)? 156 | MATCH_LIMIT : re->limit_match; 157 | jit_stack = NULL; 158 | } 159 | 160 | 161 | max_oveccount = functions->top_bracket; 162 | if (oveccount > max_oveccount) 163 | oveccount = max_oveccount; 164 | arguments.oveccount = oveccount << 1; 165 | 166 | 167 | convert_executable_func.executable_func = functions->executable_funcs[index]; 168 | if (jit_stack != NULL) 169 | { 170 | arguments.stack = (struct sljit_stack *)(jit_stack->stack); 171 | rc = convert_executable_func.call_executable_func(&arguments); 172 | } 173 | else 174 | rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func); 175 | 176 | if (rc > (int)oveccount) 177 | rc = 0; 178 | match_data->code = re; 179 | match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL; 180 | match_data->subject_length = length; 181 | match_data->rc = rc; 182 | match_data->startchar = arguments.startchar_ptr - subject; 183 | match_data->leftchar = 0; 184 | match_data->rightchar = 0; 185 | match_data->mark = arguments.mark_ptr; 186 | match_data->matchedby = PCRE2_MATCHEDBY_JIT; 187 | 188 | #if defined(__has_feature) 189 | #if __has_feature(memory_sanitizer) 190 | if (rc > 0) 191 | __msan_unpoison(match_data->ovector, 2 * rc * sizeof(match_data->ovector[0])); 192 | #endif /* __has_feature(memory_sanitizer) */ 193 | #endif /* defined(__has_feature) */ 194 | 195 | return match_data->rc; 196 | 197 | #endif /* SUPPORT_JIT */ 198 | } 199 | 200 | /* End of pcre2_jit_match.c */ 201 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_jit_misc.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | 42 | #ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE 43 | #error This file must be included from pcre2_jit_compile.c. 44 | #endif 45 | 46 | 47 | 48 | /************************************************* 49 | * Free JIT read-only data * 50 | *************************************************/ 51 | 52 | void 53 | PRIV(jit_free_rodata)(void *current, void *allocator_data) 54 | { 55 | #ifndef SUPPORT_JIT 56 | (void)current; 57 | (void)allocator_data; 58 | #else /* SUPPORT_JIT */ 59 | void *next; 60 | 61 | SLJIT_UNUSED_ARG(allocator_data); 62 | 63 | while (current != NULL) 64 | { 65 | next = *(void**)current; 66 | SLJIT_FREE(current, allocator_data); 67 | current = next; 68 | } 69 | 70 | #endif /* SUPPORT_JIT */ 71 | } 72 | 73 | /************************************************* 74 | * Free JIT compiled code * 75 | *************************************************/ 76 | 77 | void 78 | PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl) 79 | { 80 | #ifndef SUPPORT_JIT 81 | (void)executable_jit; 82 | (void)memctl; 83 | #else /* SUPPORT_JIT */ 84 | 85 | executable_functions *functions = (executable_functions *)executable_jit; 86 | void *allocator_data = memctl; 87 | int i; 88 | 89 | for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) 90 | { 91 | if (functions->executable_funcs[i] != NULL) 92 | sljit_free_code(functions->executable_funcs[i], NULL); 93 | PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data); 94 | } 95 | 96 | SLJIT_FREE(functions, allocator_data); 97 | 98 | #endif /* SUPPORT_JIT */ 99 | } 100 | 101 | 102 | /************************************************* 103 | * Free unused JIT memory * 104 | *************************************************/ 105 | 106 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 107 | pcre2_jit_free_unused_memory(pcre2_general_context *gcontext) 108 | { 109 | #ifndef SUPPORT_JIT 110 | (void)gcontext; /* Suppress warning */ 111 | #else /* SUPPORT_JIT */ 112 | SLJIT_UNUSED_ARG(gcontext); 113 | #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 114 | sljit_free_unused_memory_exec(); 115 | #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ 116 | #endif /* SUPPORT_JIT */ 117 | } 118 | 119 | 120 | 121 | /************************************************* 122 | * Allocate a JIT stack * 123 | *************************************************/ 124 | 125 | PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION 126 | pcre2_jit_stack_create(size_t startsize, size_t maxsize, 127 | pcre2_general_context *gcontext) 128 | { 129 | #ifndef SUPPORT_JIT 130 | 131 | (void)gcontext; 132 | (void)startsize; 133 | (void)maxsize; 134 | return NULL; 135 | 136 | #else /* SUPPORT_JIT */ 137 | 138 | pcre2_jit_stack *jit_stack; 139 | 140 | if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE) 141 | return NULL; 142 | if (startsize > maxsize) 143 | startsize = maxsize; 144 | startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 145 | maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 146 | 147 | jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext); 148 | if (jit_stack == NULL) return NULL; 149 | jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl); 150 | if (jit_stack->stack == NULL) 151 | { 152 | jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); 153 | return NULL; 154 | } 155 | return jit_stack; 156 | 157 | #endif 158 | } 159 | 160 | 161 | /************************************************* 162 | * Assign a JIT stack to a pattern * 163 | *************************************************/ 164 | 165 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 166 | pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback, 167 | void *callback_data) 168 | { 169 | #ifndef SUPPORT_JIT 170 | (void)mcontext; 171 | (void)callback; 172 | (void)callback_data; 173 | #else /* SUPPORT_JIT */ 174 | 175 | if (mcontext == NULL) return; 176 | mcontext->jit_callback = callback; 177 | mcontext->jit_callback_data = callback_data; 178 | 179 | #endif /* SUPPORT_JIT */ 180 | } 181 | 182 | 183 | /************************************************* 184 | * Free a JIT stack * 185 | *************************************************/ 186 | 187 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 188 | pcre2_jit_stack_free(pcre2_jit_stack *jit_stack) 189 | { 190 | #ifndef SUPPORT_JIT 191 | (void)jit_stack; 192 | #else /* SUPPORT_JIT */ 193 | if (jit_stack != NULL) 194 | { 195 | sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl); 196 | jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); 197 | } 198 | #endif /* SUPPORT_JIT */ 199 | } 200 | 201 | 202 | /************************************************* 203 | * Get target CPU type * 204 | *************************************************/ 205 | 206 | const char* 207 | PRIV(jit_get_target)(void) 208 | { 209 | #ifndef SUPPORT_JIT 210 | return "JIT is not supported"; 211 | #else /* SUPPORT_JIT */ 212 | return sljit_get_platform_name(); 213 | #endif /* SUPPORT_JIT */ 214 | } 215 | 216 | 217 | /************************************************* 218 | * Get size of JIT code * 219 | *************************************************/ 220 | 221 | size_t 222 | PRIV(jit_get_size)(void *executable_jit) 223 | { 224 | #ifndef SUPPORT_JIT 225 | (void)executable_jit; 226 | return 0; 227 | #else /* SUPPORT_JIT */ 228 | sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes; 229 | SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed); 230 | return executable_sizes[0] + executable_sizes[1] + executable_sizes[2]; 231 | #endif 232 | } 233 | 234 | /* End of pcre2_jit_misc.c */ 235 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_jit_neon_inc.h: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | This module by Zoltan Herczeg and Sebastian Pop 10 | Original API code Copyright (c) 1997-2012 University of Cambridge 11 | New API code Copyright (c) 2016-2019 University of Cambridge 12 | 13 | ----------------------------------------------------------------------------- 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | 17 | * Redistributions of source code must retain the above copyright notice, 18 | this list of conditions and the following disclaimer. 19 | 20 | * Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in the 22 | documentation and/or other materials provided with the distribution. 23 | 24 | * Neither the name of the University of Cambridge nor the names of its 25 | contributors may be used to endorse or promote products derived from 26 | this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 32 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | POSSIBILITY OF SUCH DAMAGE. 39 | ----------------------------------------------------------------------------- 40 | */ 41 | 42 | # if defined(FFCS) 43 | # if defined(FF_UTF) 44 | # define FF_FUN ffcs_utf 45 | # else 46 | # define FF_FUN ffcs 47 | # endif 48 | 49 | # elif defined(FFCS_2) 50 | # if defined(FF_UTF) 51 | # define FF_FUN ffcs_2_utf 52 | # else 53 | # define FF_FUN ffcs_2 54 | # endif 55 | 56 | # elif defined(FFCS_MASK) 57 | # if defined(FF_UTF) 58 | # define FF_FUN ffcs_mask_utf 59 | # else 60 | # define FF_FUN ffcs_mask 61 | # endif 62 | 63 | # elif defined(FFCPS_0) 64 | # if defined (FF_UTF) 65 | # define FF_FUN ffcps_0_utf 66 | # else 67 | # define FF_FUN ffcps_0 68 | # endif 69 | 70 | # elif defined (FFCPS_1) 71 | # if defined (FF_UTF) 72 | # define FF_FUN ffcps_1_utf 73 | # else 74 | # define FF_FUN ffcps_1 75 | # endif 76 | 77 | # elif defined (FFCPS_DEFAULT) 78 | # if defined (FF_UTF) 79 | # define FF_FUN ffcps_default_utf 80 | # else 81 | # define FF_FUN ffcps_default 82 | # endif 83 | # endif 84 | 85 | #if (defined(__GNUC__) && __SANITIZE_ADDRESS__) \ 86 | || (defined(__clang__) \ 87 | && ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3))) 88 | __attribute__((no_sanitize_address)) 89 | #endif 90 | static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 **str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars) 91 | #undef FF_FUN 92 | { 93 | quad_word qw; 94 | int_char ic; 95 | 96 | SLJIT_UNUSED_ARG(offs1); 97 | SLJIT_UNUSED_ARG(offs2); 98 | 99 | ic.x = chars; 100 | 101 | #if defined(FFCS) 102 | sljit_u8 c1 = ic.c.c1; 103 | vect_t vc1 = VDUPQ(c1); 104 | 105 | #elif defined(FFCS_2) 106 | sljit_u8 c1 = ic.c.c1; 107 | vect_t vc1 = VDUPQ(c1); 108 | sljit_u8 c2 = ic.c.c2; 109 | vect_t vc2 = VDUPQ(c2); 110 | 111 | #elif defined(FFCS_MASK) 112 | sljit_u8 c1 = ic.c.c1; 113 | vect_t vc1 = VDUPQ(c1); 114 | sljit_u8 mask = ic.c.c2; 115 | vect_t vmask = VDUPQ(mask); 116 | #endif 117 | 118 | #if defined(FFCPS) 119 | compare_type compare1_type = compare_match1; 120 | compare_type compare2_type = compare_match1; 121 | vect_t cmp1a, cmp1b, cmp2a, cmp2b; 122 | const sljit_u32 diff = IN_UCHARS(offs1 - offs2); 123 | PCRE2_UCHAR char1a = ic.c.c1; 124 | PCRE2_UCHAR char2a = ic.c.c3; 125 | 126 | # ifdef FFCPS_CHAR1A2A 127 | cmp1a = VDUPQ(char1a); 128 | cmp2a = VDUPQ(char2a); 129 | cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ 130 | cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ 131 | # else 132 | PCRE2_UCHAR char1b = ic.c.c2; 133 | PCRE2_UCHAR char2b = ic.c.c4; 134 | if (char1a == char1b) 135 | { 136 | cmp1a = VDUPQ(char1a); 137 | cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ 138 | } 139 | else 140 | { 141 | sljit_u32 bit1 = char1a ^ char1b; 142 | if (is_powerof2(bit1)) 143 | { 144 | compare1_type = compare_match1i; 145 | cmp1a = VDUPQ(char1a | bit1); 146 | cmp1b = VDUPQ(bit1); 147 | } 148 | else 149 | { 150 | compare1_type = compare_match2; 151 | cmp1a = VDUPQ(char1a); 152 | cmp1b = VDUPQ(char1b); 153 | } 154 | } 155 | 156 | if (char2a == char2b) 157 | { 158 | cmp2a = VDUPQ(char2a); 159 | cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ 160 | } 161 | else 162 | { 163 | sljit_u32 bit2 = char2a ^ char2b; 164 | if (is_powerof2(bit2)) 165 | { 166 | compare2_type = compare_match1i; 167 | cmp2a = VDUPQ(char2a | bit2); 168 | cmp2b = VDUPQ(bit2); 169 | } 170 | else 171 | { 172 | compare2_type = compare_match2; 173 | cmp2a = VDUPQ(char2a); 174 | cmp2b = VDUPQ(char2b); 175 | } 176 | } 177 | # endif 178 | 179 | *str_ptr += IN_UCHARS(offs1); 180 | #endif 181 | 182 | #if PCRE2_CODE_UNIT_WIDTH != 8 183 | vect_t char_mask = VDUPQ(0xff); 184 | #endif 185 | 186 | #if defined(FF_UTF) 187 | restart:; 188 | #endif 189 | 190 | #if defined(FFCPS) 191 | if (*str_ptr >= str_end) 192 | return NULL; 193 | sljit_u8 *p1 = *str_ptr - diff; 194 | #endif 195 | sljit_s32 align_offset = ((uint64_t)*str_ptr & 0xf); 196 | *str_ptr = (sljit_u8 *) ((uint64_t)*str_ptr & ~0xf); 197 | vect_t data = VLD1Q(*str_ptr); 198 | #if PCRE2_CODE_UNIT_WIDTH != 8 199 | data = VANDQ(data, char_mask); 200 | #endif 201 | 202 | #if defined(FFCS) 203 | vect_t eq = VCEQQ(data, vc1); 204 | 205 | #elif defined(FFCS_2) 206 | vect_t eq1 = VCEQQ(data, vc1); 207 | vect_t eq2 = VCEQQ(data, vc2); 208 | vect_t eq = VORRQ(eq1, eq2); 209 | 210 | #elif defined(FFCS_MASK) 211 | vect_t eq = VORRQ(data, vmask); 212 | eq = VCEQQ(eq, vc1); 213 | 214 | #elif defined(FFCPS) 215 | # if defined(FFCPS_DIFF1) 216 | vect_t prev_data = data; 217 | # endif 218 | 219 | vect_t data2; 220 | if (p1 < *str_ptr) 221 | { 222 | data2 = VLD1Q(*str_ptr - diff); 223 | #if PCRE2_CODE_UNIT_WIDTH != 8 224 | data2 = VANDQ(data2, char_mask); 225 | #endif 226 | } 227 | else 228 | data2 = shift_left_n_lanes(data, offs1 - offs2); 229 | 230 | if (compare1_type == compare_match1) 231 | data = VCEQQ(data, cmp1a); 232 | else 233 | data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); 234 | 235 | if (compare2_type == compare_match1) 236 | data2 = VCEQQ(data2, cmp2a); 237 | else 238 | data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); 239 | 240 | vect_t eq = VANDQ(data, data2); 241 | #endif 242 | 243 | VST1Q(qw.mem, eq); 244 | /* Ignore matches before the first STR_PTR. */ 245 | if (align_offset < 8) 246 | { 247 | qw.dw[0] >>= align_offset * 8; 248 | if (qw.dw[0]) 249 | { 250 | *str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8; 251 | goto match; 252 | } 253 | if (qw.dw[1]) 254 | { 255 | *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; 256 | goto match; 257 | } 258 | } 259 | else 260 | { 261 | qw.dw[1] >>= (align_offset - 8) * 8; 262 | if (qw.dw[1]) 263 | { 264 | *str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8; 265 | goto match; 266 | } 267 | } 268 | *str_ptr += 16; 269 | 270 | while (*str_ptr < str_end) 271 | { 272 | vect_t orig_data = VLD1Q(*str_ptr); 273 | #if PCRE2_CODE_UNIT_WIDTH != 8 274 | orig_data = VANDQ(orig_data, char_mask); 275 | #endif 276 | data = orig_data; 277 | 278 | #if defined(FFCS) 279 | eq = VCEQQ(data, vc1); 280 | 281 | #elif defined(FFCS_2) 282 | eq1 = VCEQQ(data, vc1); 283 | eq2 = VCEQQ(data, vc2); 284 | eq = VORRQ(eq1, eq2); 285 | 286 | #elif defined(FFCS_MASK) 287 | eq = VORRQ(data, vmask); 288 | eq = VCEQQ(eq, vc1); 289 | #endif 290 | 291 | #if defined(FFCPS) 292 | # if defined (FFCPS_DIFF1) 293 | data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1); 294 | # else 295 | data2 = VLD1Q(*str_ptr - diff); 296 | # if PCRE2_CODE_UNIT_WIDTH != 8 297 | data2 = VANDQ(data2, char_mask); 298 | # endif 299 | # endif 300 | 301 | # ifdef FFCPS_CHAR1A2A 302 | data = VCEQQ(data, cmp1a); 303 | data2 = VCEQQ(data2, cmp2a); 304 | # else 305 | if (compare1_type == compare_match1) 306 | data = VCEQQ(data, cmp1a); 307 | else 308 | data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); 309 | if (compare2_type == compare_match1) 310 | data2 = VCEQQ(data2, cmp2a); 311 | else 312 | data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); 313 | # endif 314 | 315 | eq = VANDQ(data, data2); 316 | #endif 317 | 318 | VST1Q(qw.mem, eq); 319 | if (qw.dw[0]) 320 | *str_ptr += __builtin_ctzll(qw.dw[0]) / 8; 321 | else if (qw.dw[1]) 322 | *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; 323 | else { 324 | *str_ptr += 16; 325 | #if defined (FFCPS_DIFF1) 326 | prev_data = orig_data; 327 | #endif 328 | continue; 329 | } 330 | 331 | match:; 332 | if (*str_ptr >= str_end) 333 | /* Failed match. */ 334 | return NULL; 335 | 336 | #if defined(FF_UTF) 337 | if (utf_continue((PCRE2_SPTR)*str_ptr - offs1)) 338 | { 339 | /* Not a match. */ 340 | *str_ptr += IN_UCHARS(1); 341 | goto restart; 342 | } 343 | #endif 344 | 345 | /* Match. */ 346 | #if defined (FFCPS) 347 | *str_ptr -= IN_UCHARS(offs1); 348 | #endif 349 | return *str_ptr; 350 | } 351 | 352 | /* Failed match. */ 353 | return NULL; 354 | } 355 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_maketables.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2020 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | 42 | /* This module contains the external function pcre2_maketables(), which builds 43 | character tables for PCRE2 in the current locale. The file is compiled on its 44 | own as part of the PCRE2 library. It is also included in the compilation of 45 | pcre2_dftables.c as a freestanding program, in which case the macro 46 | PCRE2_DFTABLES is defined. */ 47 | 48 | #ifndef PCRE2_DFTABLES /* Compiling the library */ 49 | # ifdef HAVE_CONFIG_H 50 | # include "config.h" 51 | # endif 52 | # include "pcre2_internal.h" 53 | #endif 54 | 55 | /************************************************* 56 | * Create PCRE2 character tables * 57 | *************************************************/ 58 | 59 | /* This function builds a set of character tables for use by PCRE2 and returns 60 | a pointer to them. They are build using the ctype functions, and consequently 61 | their contents will depend upon the current locale setting. When compiled as 62 | part of the library, the store is obtained via a general context malloc, if 63 | supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables 64 | freestanding auxiliary program) malloc() is used, and the function has a 65 | different name so as not to clash with the prototype in pcre2.h. 66 | 67 | Arguments: none when PCRE2_DFTABLES is defined 68 | else a PCRE2 general context or NULL 69 | Returns: pointer to the contiguous block of data 70 | else NULL if memory allocation failed 71 | */ 72 | 73 | #ifdef PCRE2_DFTABLES /* Included in freestanding pcre2_dftables program */ 74 | static const uint8_t *maketables(void) 75 | { 76 | uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH); 77 | 78 | #else /* Not PCRE2_DFTABLES, that is, compiling the library */ 79 | PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION 80 | pcre2_maketables(pcre2_general_context *gcontext) 81 | { 82 | uint8_t *yield = (uint8_t *)((gcontext != NULL)? 83 | gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) : 84 | malloc(TABLES_LENGTH)); 85 | #endif /* PCRE2_DFTABLES */ 86 | 87 | int i; 88 | uint8_t *p; 89 | 90 | if (yield == NULL) return NULL; 91 | p = yield; 92 | 93 | /* First comes the lower casing table */ 94 | 95 | for (i = 0; i < 256; i++) *p++ = tolower(i); 96 | 97 | /* Next the case-flipping table */ 98 | 99 | for (i = 0; i < 256; i++) 100 | { 101 | int c = islower(i)? toupper(i) : tolower(i); 102 | *p++ = (c < 256)? c : i; 103 | } 104 | 105 | /* Then the character class tables. Don't try to be clever and save effort on 106 | exclusive ones - in some locales things may be different. 107 | 108 | Note that the table for "space" includes everything "isspace" gives, including 109 | VT in the default locale. This makes it work for the POSIX class [:space:]. 110 | From PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl 111 | space, because Perl added VT at release 5.18. 112 | 113 | Note also that it is possible for a character to be alnum or alpha without 114 | being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the 115 | fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must 116 | test for alnum specially. */ 117 | 118 | memset(p, 0, cbit_length); 119 | for (i = 0; i < 256; i++) 120 | { 121 | if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7); 122 | if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7); 123 | if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7); 124 | if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7); 125 | if (i == '_') p[cbit_word + i/8] |= 1u << (i&7); 126 | if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7); 127 | if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7); 128 | if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7); 129 | if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7); 130 | if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7); 131 | if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7); 132 | } 133 | p += cbit_length; 134 | 135 | /* Finally, the character type table. In this, we used to exclude VT from the 136 | white space chars, because Perl didn't recognize it as such for \s and for 137 | comments within regexes. However, Perl changed at release 5.18, so PCRE1 138 | changed at release 8.34 and it's always been this way for PCRE2. */ 139 | 140 | for (i = 0; i < 256; i++) 141 | { 142 | int x = 0; 143 | if (isspace(i)) x += ctype_space; 144 | if (isalpha(i)) x += ctype_letter; 145 | if (islower(i)) x += ctype_lcletter; 146 | if (isdigit(i)) x += ctype_digit; 147 | if (isalnum(i) || i == '_') x += ctype_word; 148 | *p++ = x; 149 | } 150 | 151 | return yield; 152 | } 153 | 154 | #ifndef PCRE2_DFTABLES /* Compiling the library */ 155 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 156 | pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables) 157 | { 158 | if (gcontext) 159 | gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data); 160 | else 161 | free((void *)tables); 162 | } 163 | #endif 164 | 165 | /* End of pcre2_maketables.c */ 166 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_match_data.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2022 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | 42 | #ifdef HAVE_CONFIG_H 43 | #include "config.h" 44 | #endif 45 | 46 | #include "pcre2_internal.h" 47 | 48 | 49 | 50 | /************************************************* 51 | * Create a match data block given ovector size * 52 | *************************************************/ 53 | 54 | /* A minimum of 1 is imposed on the number of ovector pairs. A maximum is also 55 | imposed because the oveccount field in a match data block is uintt6_t. */ 56 | 57 | PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION 58 | pcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext) 59 | { 60 | pcre2_match_data *yield; 61 | if (oveccount < 1) oveccount = 1; 62 | if (oveccount > UINT16_MAX) oveccount = UINT16_MAX; 63 | yield = PRIV(memctl_malloc)( 64 | offsetof(pcre2_match_data, ovector) + 2*oveccount*sizeof(PCRE2_SIZE), 65 | (pcre2_memctl *)gcontext); 66 | if (yield == NULL) return NULL; 67 | yield->oveccount = oveccount; 68 | yield->flags = 0; 69 | yield->heapframes = NULL; 70 | yield->heapframes_size = 0; 71 | return yield; 72 | } 73 | 74 | 75 | 76 | /************************************************* 77 | * Create a match data block using pattern data * 78 | *************************************************/ 79 | 80 | /* If no context is supplied, use the memory allocator from the code. */ 81 | 82 | PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION 83 | pcre2_match_data_create_from_pattern(const pcre2_code *code, 84 | pcre2_general_context *gcontext) 85 | { 86 | if (gcontext == NULL) gcontext = (pcre2_general_context *)code; 87 | return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1, 88 | gcontext); 89 | } 90 | 91 | 92 | 93 | /************************************************* 94 | * Free a match data block * 95 | *************************************************/ 96 | 97 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 98 | pcre2_match_data_free(pcre2_match_data *match_data) 99 | { 100 | if (match_data != NULL) 101 | { 102 | if (match_data->heapframes != NULL) 103 | match_data->memctl.free(match_data->heapframes, 104 | match_data->memctl.memory_data); 105 | if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0) 106 | match_data->memctl.free((void *)match_data->subject, 107 | match_data->memctl.memory_data); 108 | match_data->memctl.free(match_data, match_data->memctl.memory_data); 109 | } 110 | } 111 | 112 | 113 | 114 | /************************************************* 115 | * Get last mark in match * 116 | *************************************************/ 117 | 118 | PCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION 119 | pcre2_get_mark(pcre2_match_data *match_data) 120 | { 121 | return match_data->mark; 122 | } 123 | 124 | 125 | 126 | /************************************************* 127 | * Get pointer to ovector * 128 | *************************************************/ 129 | 130 | PCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION 131 | pcre2_get_ovector_pointer(pcre2_match_data *match_data) 132 | { 133 | return match_data->ovector; 134 | } 135 | 136 | 137 | 138 | /************************************************* 139 | * Get number of ovector slots * 140 | *************************************************/ 141 | 142 | PCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION 143 | pcre2_get_ovector_count(pcre2_match_data *match_data) 144 | { 145 | return match_data->oveccount; 146 | } 147 | 148 | 149 | 150 | /************************************************* 151 | * Get starting code unit in match * 152 | *************************************************/ 153 | 154 | PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION 155 | pcre2_get_startchar(pcre2_match_data *match_data) 156 | { 157 | return match_data->startchar; 158 | } 159 | 160 | 161 | 162 | /************************************************* 163 | * Get size of match data block * 164 | *************************************************/ 165 | 166 | PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION 167 | pcre2_get_match_data_size(pcre2_match_data *match_data) 168 | { 169 | return offsetof(pcre2_match_data, ovector) + 170 | 2 * (match_data->oveccount) * sizeof(PCRE2_SIZE); 171 | } 172 | 173 | 174 | 175 | /************************************************* 176 | * Get heapframes size * 177 | *************************************************/ 178 | 179 | PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION 180 | pcre2_get_match_data_heapframes_size(pcre2_match_data *match_data) 181 | { 182 | return match_data->heapframes_size; 183 | } 184 | 185 | /* End of pcre2_match_data.c */ 186 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_newline.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | 42 | /* This module contains internal functions for testing newlines when more than 43 | one kind of newline is to be recognized. When a newline is found, its length is 44 | returned. In principle, we could implement several newline "types", each 45 | referring to a different set of newline characters. At present, PCRE2 supports 46 | only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF, 47 | and NLTYPE_ANY. The full list of Unicode newline characters is taken from 48 | http://unicode.org/unicode/reports/tr18/. */ 49 | 50 | 51 | #ifdef HAVE_CONFIG_H 52 | #include "config.h" 53 | #endif 54 | 55 | #include "pcre2_internal.h" 56 | 57 | 58 | 59 | /************************************************* 60 | * Check for newline at given position * 61 | *************************************************/ 62 | 63 | /* This function is called only via the IS_NEWLINE macro, which does so only 64 | when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed 65 | newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit 66 | pointed to by ptr is less than the end of the string. 67 | 68 | Arguments: 69 | ptr pointer to possible newline 70 | type the newline type 71 | endptr pointer to the end of the string 72 | lenptr where to return the length 73 | utf TRUE if in utf mode 74 | 75 | Returns: TRUE or FALSE 76 | */ 77 | 78 | BOOL 79 | PRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr, 80 | uint32_t *lenptr, BOOL utf) 81 | { 82 | uint32_t c; 83 | 84 | #ifdef SUPPORT_UNICODE 85 | if (utf) { GETCHAR(c, ptr); } else c = *ptr; 86 | #else 87 | (void)utf; 88 | c = *ptr; 89 | #endif /* SUPPORT_UNICODE */ 90 | 91 | if (type == NLTYPE_ANYCRLF) switch(c) 92 | { 93 | case CHAR_LF: 94 | *lenptr = 1; 95 | return TRUE; 96 | 97 | case CHAR_CR: 98 | *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; 99 | return TRUE; 100 | 101 | default: 102 | return FALSE; 103 | } 104 | 105 | /* NLTYPE_ANY */ 106 | 107 | else switch(c) 108 | { 109 | #ifdef EBCDIC 110 | case CHAR_NEL: 111 | #endif 112 | case CHAR_LF: 113 | case CHAR_VT: 114 | case CHAR_FF: 115 | *lenptr = 1; 116 | return TRUE; 117 | 118 | case CHAR_CR: 119 | *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; 120 | return TRUE; 121 | 122 | #ifndef EBCDIC 123 | #if PCRE2_CODE_UNIT_WIDTH == 8 124 | case CHAR_NEL: 125 | *lenptr = utf? 2 : 1; 126 | return TRUE; 127 | 128 | case 0x2028: /* LS */ 129 | case 0x2029: /* PS */ 130 | *lenptr = 3; 131 | return TRUE; 132 | 133 | #else /* 16-bit or 32-bit code units */ 134 | case CHAR_NEL: 135 | case 0x2028: /* LS */ 136 | case 0x2029: /* PS */ 137 | *lenptr = 1; 138 | return TRUE; 139 | #endif 140 | #endif /* Not EBCDIC */ 141 | 142 | default: 143 | return FALSE; 144 | } 145 | } 146 | 147 | 148 | 149 | /************************************************* 150 | * Check for newline at previous position * 151 | *************************************************/ 152 | 153 | /* This function is called only via the WAS_NEWLINE macro, which does so only 154 | when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed 155 | newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial 156 | value of ptr is greater than the start of the string that is being processed. 157 | 158 | Arguments: 159 | ptr pointer to possible newline 160 | type the newline type 161 | startptr pointer to the start of the string 162 | lenptr where to return the length 163 | utf TRUE if in utf mode 164 | 165 | Returns: TRUE or FALSE 166 | */ 167 | 168 | BOOL 169 | PRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr, 170 | uint32_t *lenptr, BOOL utf) 171 | { 172 | uint32_t c; 173 | ptr--; 174 | 175 | #ifdef SUPPORT_UNICODE 176 | if (utf) 177 | { 178 | BACKCHAR(ptr); 179 | GETCHAR(c, ptr); 180 | } 181 | else c = *ptr; 182 | #else 183 | (void)utf; 184 | c = *ptr; 185 | #endif /* SUPPORT_UNICODE */ 186 | 187 | if (type == NLTYPE_ANYCRLF) switch(c) 188 | { 189 | case CHAR_LF: 190 | *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; 191 | return TRUE; 192 | 193 | case CHAR_CR: 194 | *lenptr = 1; 195 | return TRUE; 196 | 197 | default: 198 | return FALSE; 199 | } 200 | 201 | /* NLTYPE_ANY */ 202 | 203 | else switch(c) 204 | { 205 | case CHAR_LF: 206 | *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; 207 | return TRUE; 208 | 209 | #ifdef EBCDIC 210 | case CHAR_NEL: 211 | #endif 212 | case CHAR_VT: 213 | case CHAR_FF: 214 | case CHAR_CR: 215 | *lenptr = 1; 216 | return TRUE; 217 | 218 | #ifndef EBCDIC 219 | #if PCRE2_CODE_UNIT_WIDTH == 8 220 | case CHAR_NEL: 221 | *lenptr = utf? 2 : 1; 222 | return TRUE; 223 | 224 | case 0x2028: /* LS */ 225 | case 0x2029: /* PS */ 226 | *lenptr = 3; 227 | return TRUE; 228 | 229 | #else /* 16-bit or 32-bit code units */ 230 | case CHAR_NEL: 231 | case 0x2028: /* LS */ 232 | case 0x2029: /* PS */ 233 | *lenptr = 1; 234 | return TRUE; 235 | #endif 236 | #endif /* Not EBCDIC */ 237 | 238 | default: 239 | return FALSE; 240 | } 241 | } 242 | 243 | /* End of pcre2_newline.c */ 244 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_ord2utf.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | 42 | /* This file contains a function that converts a Unicode character code point 43 | into a UTF string. The behaviour is different for each code unit width. */ 44 | 45 | 46 | #ifdef HAVE_CONFIG_H 47 | #include "config.h" 48 | #endif 49 | 50 | #include "pcre2_internal.h" 51 | 52 | 53 | /* If SUPPORT_UNICODE is not defined, this function will never be called. 54 | Supply a dummy function because some compilers do not like empty source 55 | modules. */ 56 | 57 | #ifndef SUPPORT_UNICODE 58 | unsigned int 59 | PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer) 60 | { 61 | (void)(cvalue); 62 | (void)(buffer); 63 | return 0; 64 | } 65 | #else /* SUPPORT_UNICODE */ 66 | 67 | 68 | /************************************************* 69 | * Convert code point to UTF * 70 | *************************************************/ 71 | 72 | /* 73 | Arguments: 74 | cvalue the character value 75 | buffer pointer to buffer for result 76 | 77 | Returns: number of code units placed in the buffer 78 | */ 79 | 80 | unsigned int 81 | PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer) 82 | { 83 | /* Convert to UTF-8 */ 84 | 85 | #if PCRE2_CODE_UNIT_WIDTH == 8 86 | int i, j; 87 | for (i = 0; i < PRIV(utf8_table1_size); i++) 88 | if ((int)cvalue <= PRIV(utf8_table1)[i]) break; 89 | buffer += i; 90 | for (j = i; j > 0; j--) 91 | { 92 | *buffer-- = 0x80 | (cvalue & 0x3f); 93 | cvalue >>= 6; 94 | } 95 | *buffer = PRIV(utf8_table2)[i] | cvalue; 96 | return i + 1; 97 | 98 | /* Convert to UTF-16 */ 99 | 100 | #elif PCRE2_CODE_UNIT_WIDTH == 16 101 | if (cvalue <= 0xffff) 102 | { 103 | *buffer = (PCRE2_UCHAR)cvalue; 104 | return 1; 105 | } 106 | cvalue -= 0x10000; 107 | *buffer++ = 0xd800 | (cvalue >> 10); 108 | *buffer = 0xdc00 | (cvalue & 0x3ff); 109 | return 2; 110 | 111 | /* Convert to UTF-32 */ 112 | 113 | #else 114 | *buffer = (PCRE2_UCHAR)cvalue; 115 | return 1; 116 | #endif 117 | } 118 | #endif /* SUPPORT_UNICODE */ 119 | 120 | /* End of pcre_ord2utf.c */ 121 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_serialize.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2020 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | /* This module contains functions for serializing and deserializing 42 | a sequence of compiled codes. */ 43 | 44 | 45 | #ifdef HAVE_CONFIG_H 46 | #include "config.h" 47 | #endif 48 | 49 | 50 | #include "pcre2_internal.h" 51 | 52 | /* Magic number to provide a small check against being handed junk. */ 53 | 54 | #define SERIALIZED_DATA_MAGIC 0x50523253u 55 | 56 | /* Deserialization is limited to the current PCRE version and 57 | character width. */ 58 | 59 | #define SERIALIZED_DATA_VERSION \ 60 | ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16)) 61 | 62 | #define SERIALIZED_DATA_CONFIG \ 63 | (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16)) 64 | 65 | 66 | 67 | /************************************************* 68 | * Serialize compiled patterns * 69 | *************************************************/ 70 | 71 | PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION 72 | pcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes, 73 | uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size, 74 | pcre2_general_context *gcontext) 75 | { 76 | uint8_t *bytes; 77 | uint8_t *dst_bytes; 78 | int32_t i; 79 | PCRE2_SIZE total_size; 80 | const pcre2_real_code *re; 81 | const uint8_t *tables; 82 | pcre2_serialized_data *data; 83 | 84 | const pcre2_memctl *memctl = (gcontext != NULL) ? 85 | &gcontext->memctl : &PRIV(default_compile_context).memctl; 86 | 87 | if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL) 88 | return PCRE2_ERROR_NULL; 89 | 90 | if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; 91 | 92 | /* Compute total size. */ 93 | total_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH; 94 | tables = NULL; 95 | 96 | for (i = 0; i < number_of_codes; i++) 97 | { 98 | if (codes[i] == NULL) return PCRE2_ERROR_NULL; 99 | re = (const pcre2_real_code *)(codes[i]); 100 | if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; 101 | if (tables == NULL) 102 | tables = re->tables; 103 | else if (tables != re->tables) 104 | return PCRE2_ERROR_MIXEDTABLES; 105 | total_size += re->blocksize; 106 | } 107 | 108 | /* Initialize the byte stream. */ 109 | bytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data); 110 | if (bytes == NULL) return PCRE2_ERROR_NOMEMORY; 111 | 112 | /* The controller is stored as a hidden parameter. */ 113 | memcpy(bytes, memctl, sizeof(pcre2_memctl)); 114 | bytes += sizeof(pcre2_memctl); 115 | 116 | data = (pcre2_serialized_data *)bytes; 117 | data->magic = SERIALIZED_DATA_MAGIC; 118 | data->version = SERIALIZED_DATA_VERSION; 119 | data->config = SERIALIZED_DATA_CONFIG; 120 | data->number_of_codes = number_of_codes; 121 | 122 | /* Copy all compiled code data. */ 123 | dst_bytes = bytes + sizeof(pcre2_serialized_data); 124 | memcpy(dst_bytes, tables, TABLES_LENGTH); 125 | dst_bytes += TABLES_LENGTH; 126 | 127 | for (i = 0; i < number_of_codes; i++) 128 | { 129 | re = (const pcre2_real_code *)(codes[i]); 130 | (void)memcpy(dst_bytes, (char *)re, re->blocksize); 131 | 132 | /* Certain fields in the compiled code block are re-set during 133 | deserialization. In order to ensure that the serialized data stream is always 134 | the same for the same pattern, set them to zero here. We can't assume the 135 | copy of the pattern is correctly aligned for accessing the fields as part of 136 | a structure. Note the use of sizeof(void *) in the second of these, to 137 | specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a 138 | pointer to uint8_t), gcc gives a warning because the first argument is also a 139 | pointer to uint8_t. Casting the first argument to (void *) can stop this, but 140 | it didn't stop Coverity giving the same complaint. */ 141 | 142 | (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, 143 | sizeof(pcre2_memctl)); 144 | (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, 145 | sizeof(void *)); 146 | (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0, 147 | sizeof(void *)); 148 | 149 | dst_bytes += re->blocksize; 150 | } 151 | 152 | *serialized_bytes = bytes; 153 | *serialized_size = total_size; 154 | return number_of_codes; 155 | } 156 | 157 | 158 | /************************************************* 159 | * Deserialize compiled patterns * 160 | *************************************************/ 161 | 162 | PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION 163 | pcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes, 164 | const uint8_t *bytes, pcre2_general_context *gcontext) 165 | { 166 | const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes; 167 | const pcre2_memctl *memctl = (gcontext != NULL) ? 168 | &gcontext->memctl : &PRIV(default_compile_context).memctl; 169 | 170 | const uint8_t *src_bytes; 171 | pcre2_real_code *dst_re; 172 | uint8_t *tables; 173 | int32_t i, j; 174 | 175 | /* Sanity checks. */ 176 | 177 | if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL; 178 | if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; 179 | if (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA; 180 | if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; 181 | if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; 182 | if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; 183 | 184 | if (number_of_codes > data->number_of_codes) 185 | number_of_codes = data->number_of_codes; 186 | 187 | src_bytes = bytes + sizeof(pcre2_serialized_data); 188 | 189 | /* Decode tables. The reference count for the tables is stored immediately 190 | following them. */ 191 | 192 | tables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data); 193 | if (tables == NULL) return PCRE2_ERROR_NOMEMORY; 194 | 195 | memcpy(tables, src_bytes, TABLES_LENGTH); 196 | *(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes; 197 | src_bytes += TABLES_LENGTH; 198 | 199 | /* Decode the byte stream. We must not try to read the size from the compiled 200 | code block in the stream, because it might be unaligned, which causes errors on 201 | hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type 202 | of the blocksize field is given its own name to ensure that it is the same here 203 | as in the block. */ 204 | 205 | for (i = 0; i < number_of_codes; i++) 206 | { 207 | CODE_BLOCKSIZE_TYPE blocksize; 208 | memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize), 209 | sizeof(CODE_BLOCKSIZE_TYPE)); 210 | if (blocksize <= sizeof(pcre2_real_code)) 211 | return PCRE2_ERROR_BADSERIALIZEDDATA; 212 | 213 | /* The allocator provided by gcontext replaces the original one. */ 214 | 215 | dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize, 216 | (pcre2_memctl *)gcontext); 217 | if (dst_re == NULL) 218 | { 219 | memctl->free(tables, memctl->memory_data); 220 | for (j = 0; j < i; j++) 221 | { 222 | memctl->free(codes[j], memctl->memory_data); 223 | codes[j] = NULL; 224 | } 225 | return PCRE2_ERROR_NOMEMORY; 226 | } 227 | 228 | /* The new allocator must be preserved. */ 229 | 230 | memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl), 231 | src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl)); 232 | if (dst_re->magic_number != MAGIC_NUMBER || 233 | dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 || 234 | dst_re->name_count > MAX_NAME_COUNT) 235 | { 236 | memctl->free(dst_re, memctl->memory_data); 237 | return PCRE2_ERROR_BADSERIALIZEDDATA; 238 | } 239 | 240 | /* At the moment only one table is supported. */ 241 | 242 | dst_re->tables = tables; 243 | dst_re->executable_jit = NULL; 244 | dst_re->flags |= PCRE2_DEREF_TABLES; 245 | 246 | codes[i] = dst_re; 247 | src_bytes += blocksize; 248 | } 249 | 250 | return number_of_codes; 251 | } 252 | 253 | 254 | /************************************************* 255 | * Get the number of serialized patterns * 256 | *************************************************/ 257 | 258 | PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION 259 | pcre2_serialize_get_number_of_codes(const uint8_t *bytes) 260 | { 261 | const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes; 262 | 263 | if (data == NULL) return PCRE2_ERROR_NULL; 264 | if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; 265 | if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; 266 | if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; 267 | 268 | return data->number_of_codes; 269 | } 270 | 271 | 272 | /************************************************* 273 | * Free the allocated stream * 274 | *************************************************/ 275 | 276 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 277 | pcre2_serialize_free(uint8_t *bytes) 278 | { 279 | if (bytes != NULL) 280 | { 281 | pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl)); 282 | memctl->free(memctl, memctl->memory_data); 283 | } 284 | } 285 | 286 | /* End of pcre2_serialize.c */ 287 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_string_utils.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2018-2021 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | /* This module contains internal functions for comparing and finding the length 42 | of strings. These are used instead of strcmp() etc because the standard 43 | functions work only on 8-bit data. */ 44 | 45 | 46 | #ifdef HAVE_CONFIG_H 47 | #include "config.h" 48 | #endif 49 | 50 | #include "pcre2_internal.h" 51 | 52 | 53 | /************************************************* 54 | * Emulated memmove() for systems without it * 55 | *************************************************/ 56 | 57 | /* This function can make use of bcopy() if it is available. Otherwise do it by 58 | steam, as there some non-Unix environments that lack both memmove() and 59 | bcopy(). */ 60 | 61 | #if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE) 62 | void * 63 | PRIV(memmove)(void *d, const void *s, size_t n) 64 | { 65 | #ifdef HAVE_BCOPY 66 | bcopy(s, d, n); 67 | return d; 68 | #else 69 | size_t i; 70 | unsigned char *dest = (unsigned char *)d; 71 | const unsigned char *src = (const unsigned char *)s; 72 | if (dest > src) 73 | { 74 | dest += n; 75 | src += n; 76 | for (i = 0; i < n; ++i) *(--dest) = *(--src); 77 | return (void *)dest; 78 | } 79 | else 80 | { 81 | for (i = 0; i < n; ++i) *dest++ = *src++; 82 | return (void *)(dest - n); 83 | } 84 | #endif /* not HAVE_BCOPY */ 85 | } 86 | #endif /* not VPCOMPAT && not HAVE_MEMMOVE */ 87 | 88 | 89 | /************************************************* 90 | * Compare two zero-terminated PCRE2 strings * 91 | *************************************************/ 92 | 93 | /* 94 | Arguments: 95 | str1 first string 96 | str2 second string 97 | 98 | Returns: 0, 1, or -1 99 | */ 100 | 101 | int 102 | PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2) 103 | { 104 | PCRE2_UCHAR c1, c2; 105 | while (*str1 != '\0' || *str2 != '\0') 106 | { 107 | c1 = *str1++; 108 | c2 = *str2++; 109 | if (c1 != c2) return ((c1 > c2) << 1) - 1; 110 | } 111 | return 0; 112 | } 113 | 114 | 115 | /************************************************* 116 | * Compare zero-terminated PCRE2 & 8-bit strings * 117 | *************************************************/ 118 | 119 | /* As the 8-bit string is almost always a literal, its type is specified as 120 | const char *. 121 | 122 | Arguments: 123 | str1 first string 124 | str2 second string 125 | 126 | Returns: 0, 1, or -1 127 | */ 128 | 129 | int 130 | PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2) 131 | { 132 | PCRE2_UCHAR c1, c2; 133 | while (*str1 != '\0' || *str2 != '\0') 134 | { 135 | c1 = *str1++; 136 | c2 = *str2++; 137 | if (c1 != c2) return ((c1 > c2) << 1) - 1; 138 | } 139 | return 0; 140 | } 141 | 142 | 143 | /************************************************* 144 | * Compare two PCRE2 strings, given a length * 145 | *************************************************/ 146 | 147 | /* 148 | Arguments: 149 | str1 first string 150 | str2 second string 151 | len the length 152 | 153 | Returns: 0, 1, or -1 154 | */ 155 | 156 | int 157 | PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len) 158 | { 159 | PCRE2_UCHAR c1, c2; 160 | for (; len > 0; len--) 161 | { 162 | c1 = *str1++; 163 | c2 = *str2++; 164 | if (c1 != c2) return ((c1 > c2) << 1) - 1; 165 | } 166 | return 0; 167 | } 168 | 169 | 170 | /************************************************* 171 | * Compare PCRE2 string to 8-bit string by length * 172 | *************************************************/ 173 | 174 | /* As the 8-bit string is almost always a literal, its type is specified as 175 | const char *. 176 | 177 | Arguments: 178 | str1 first string 179 | str2 second string 180 | len the length 181 | 182 | Returns: 0, 1, or -1 183 | */ 184 | 185 | int 186 | PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len) 187 | { 188 | PCRE2_UCHAR c1, c2; 189 | for (; len > 0; len--) 190 | { 191 | c1 = *str1++; 192 | c2 = *str2++; 193 | if (c1 != c2) return ((c1 > c2) << 1) - 1; 194 | } 195 | return 0; 196 | } 197 | 198 | 199 | /************************************************* 200 | * Find the length of a PCRE2 string * 201 | *************************************************/ 202 | 203 | /* 204 | Argument: the string 205 | Returns: the length 206 | */ 207 | 208 | PCRE2_SIZE 209 | PRIV(strlen)(PCRE2_SPTR str) 210 | { 211 | PCRE2_SIZE c = 0; 212 | while (*str++ != 0) c++; 213 | return c; 214 | } 215 | 216 | 217 | /************************************************* 218 | * Copy 8-bit 0-terminated string to PCRE2 string * 219 | *************************************************/ 220 | 221 | /* Arguments: 222 | str1 buffer to receive the string 223 | str2 8-bit string to be copied 224 | 225 | Returns: the number of code units used (excluding trailing zero) 226 | */ 227 | 228 | PCRE2_SIZE 229 | PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2) 230 | { 231 | PCRE2_UCHAR *t = str1; 232 | while (*str2 != 0) *t++ = *str2++; 233 | *t = 0; 234 | return t - str1; 235 | } 236 | 237 | /* End of pcre2_string_utils.c */ 238 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2_tables.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. 7 | 8 | Written by Philip Hazel 9 | Original API code Copyright (c) 1997-2012 University of Cambridge 10 | New API code Copyright (c) 2016-2021 University of Cambridge 11 | 12 | ----------------------------------------------------------------------------- 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the University of Cambridge nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | POSSIBILITY OF SUCH DAMAGE. 38 | ----------------------------------------------------------------------------- 39 | */ 40 | 41 | /* This module contains some fixed tables that are used by more than one of the 42 | PCRE2 code modules. The tables are also #included by the pcre2test program, 43 | which uses macros to change their names from _pcre2_xxx to xxxx, thereby 44 | avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is 45 | defined. */ 46 | 47 | #ifndef PCRE2_PCRE2TEST /* We're compiling the library */ 48 | #ifdef HAVE_CONFIG_H 49 | #include "config.h" 50 | #endif 51 | #include "pcre2_internal.h" 52 | #endif /* PCRE2_PCRE2TEST */ 53 | 54 | /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that 55 | the definition is next to the definition of the opcodes in pcre2_internal.h. 56 | This is mode-dependent, so it is skipped when this file is included by 57 | pcre2test. */ 58 | 59 | #ifndef PCRE2_PCRE2TEST 60 | const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS }; 61 | #endif 62 | 63 | /* Tables of horizontal and vertical whitespace characters, suitable for 64 | adding to classes. */ 65 | 66 | const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST }; 67 | const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST }; 68 | 69 | /* These tables are the pairs of delimiters that are valid for callout string 70 | arguments. For each starting delimiter there must be a matching ending 71 | delimiter, which in fact is different only for bracket-like delimiters. */ 72 | 73 | const uint32_t PRIV(callout_start_delims)[] = { 74 | CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK, 75 | CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN, 76 | CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 }; 77 | 78 | const uint32_t PRIV(callout_end_delims[]) = { 79 | CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK, 80 | CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN, 81 | CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 }; 82 | 83 | 84 | /************************************************* 85 | * Tables for UTF-8 support * 86 | *************************************************/ 87 | 88 | /* These tables are required by pcre2test in 16- or 32-bit mode, as well 89 | as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for 90 | handling wide characters. */ 91 | 92 | #if defined PCRE2_PCRE2TEST || \ 93 | (defined SUPPORT_UNICODE && \ 94 | defined PCRE2_CODE_UNIT_WIDTH && \ 95 | PCRE2_CODE_UNIT_WIDTH == 8) 96 | 97 | /* These are the breakpoints for different numbers of bytes in a UTF-8 98 | character. */ 99 | 100 | const int PRIV(utf8_table1)[] = 101 | { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; 102 | 103 | const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int); 104 | 105 | /* These are the indicator bits and the mask for the data bits to set in the 106 | first byte of a character, indexed by the number of additional bytes. */ 107 | 108 | const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; 109 | const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; 110 | 111 | /* Table of the number of extra bytes, indexed by the first byte masked with 112 | 0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ 113 | 114 | const uint8_t PRIV(utf8_table4)[] = { 115 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 116 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 117 | 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 118 | 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; 119 | 120 | #endif /* UTF-8 support needed */ 121 | 122 | /* Tables concerned with Unicode properties are relevant only when Unicode 123 | support is enabled. See also the pcre2_ucptables.c file, which is generated by 124 | a Python script from Unicode data files. */ 125 | 126 | #ifdef SUPPORT_UNICODE 127 | 128 | /* Table to translate from particular type value to the general value. */ 129 | 130 | const uint32_t PRIV(ucp_gentype)[] = { 131 | ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ 132 | ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ 133 | ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ 134 | ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */ 135 | ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */ 136 | ucp_P, ucp_P, /* Ps, Po */ 137 | ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */ 138 | ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ 139 | }; 140 | 141 | /* This table encodes the rules for finding the end of an extended grapheme 142 | cluster. Every code point has a grapheme break property which is one of the 143 | ucp_gbXX values defined in pcre2_ucp.h. These changed between Unicode versions 144 | 10 and 11. The 2-dimensional table is indexed by the properties of two adjacent 145 | code points. The left property selects a word from the table, and the right 146 | property selects a bit from that word like this: 147 | 148 | PRIV(ucp_gbtable)[left-property] & (1u << right-property) 149 | 150 | The value is non-zero if a grapheme break is NOT permitted between the relevant 151 | two code points. The breaking rules are as follows: 152 | 153 | 1. Break at the start and end of text (pretty obviously). 154 | 155 | 2. Do not break between a CR and LF; otherwise, break before and after 156 | controls. 157 | 158 | 3. Do not break Hangul syllable sequences, the rules for which are: 159 | 160 | L may be followed by L, V, LV or LVT 161 | LV or V may be followed by V or T 162 | LVT or T may be followed by T 163 | 164 | 4. Do not break before extending characters or zero-width-joiner (ZWJ). 165 | 166 | The following rules are only for extended grapheme clusters (but that's what we 167 | are implementing). 168 | 169 | 5. Do not break before SpacingMarks. 170 | 171 | 6. Do not break after Prepend characters. 172 | 173 | 7. Do not break within emoji modifier sequences or emoji zwj sequences. That 174 | is, do not break between characters with the Extended_Pictographic property. 175 | Extend and ZWJ characters are allowed between the characters; this cannot be 176 | represented in this table, the code has to deal with it. 177 | 178 | 8. Do not break within emoji flag sequences. That is, do not break between 179 | regional indicator (RI) symbols if there are an odd number of RI characters 180 | before the break point. This table encodes "join RI characters"; the code 181 | has to deal with checking for previous adjoining RIs. 182 | 183 | 9. Otherwise, break everywhere. 184 | */ 185 | 186 | #define ESZ (1<= x && c <= y) return !negated; 131 | } 132 | 133 | #ifdef SUPPORT_UNICODE 134 | else /* XCL_PROP & XCL_NOTPROP */ 135 | { 136 | int chartype; 137 | const ucd_record *prop = GET_UCD(c); 138 | BOOL isprop = t == XCL_PROP; 139 | BOOL ok; 140 | 141 | switch(*data) 142 | { 143 | case PT_ANY: 144 | if (isprop) return !negated; 145 | break; 146 | 147 | case PT_LAMP: 148 | chartype = prop->chartype; 149 | if ((chartype == ucp_Lu || chartype == ucp_Ll || 150 | chartype == ucp_Lt) == isprop) return !negated; 151 | break; 152 | 153 | case PT_GC: 154 | if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop) 155 | return !negated; 156 | break; 157 | 158 | case PT_PC: 159 | if ((data[1] == prop->chartype) == isprop) return !negated; 160 | break; 161 | 162 | case PT_SC: 163 | if ((data[1] == prop->script) == isprop) return !negated; 164 | break; 165 | 166 | case PT_SCX: 167 | ok = (data[1] == prop->script || 168 | MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), data[1]) != 0); 169 | if (ok == isprop) return !negated; 170 | break; 171 | 172 | case PT_ALNUM: 173 | chartype = prop->chartype; 174 | if ((PRIV(ucp_gentype)[chartype] == ucp_L || 175 | PRIV(ucp_gentype)[chartype] == ucp_N) == isprop) 176 | return !negated; 177 | break; 178 | 179 | /* Perl space used to exclude VT, but from Perl 5.18 it is included, 180 | which means that Perl space and POSIX space are now identical. PCRE 181 | was changed at release 8.34. */ 182 | 183 | case PT_SPACE: /* Perl space */ 184 | case PT_PXSPACE: /* POSIX space */ 185 | switch(c) 186 | { 187 | HSPACE_CASES: 188 | VSPACE_CASES: 189 | if (isprop) return !negated; 190 | break; 191 | 192 | default: 193 | if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop) 194 | return !negated; 195 | break; 196 | } 197 | break; 198 | 199 | case PT_WORD: 200 | chartype = prop->chartype; 201 | if ((PRIV(ucp_gentype)[chartype] == ucp_L || 202 | PRIV(ucp_gentype)[chartype] == ucp_N || 203 | chartype == ucp_Mn || chartype == ucp_Pc) == isprop) 204 | return !negated; 205 | break; 206 | 207 | case PT_UCNC: 208 | if (c < 0xa0) 209 | { 210 | if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || 211 | c == CHAR_GRAVE_ACCENT) == isprop) 212 | return !negated; 213 | } 214 | else 215 | { 216 | if ((c < 0xd800 || c > 0xdfff) == isprop) 217 | return !negated; 218 | } 219 | break; 220 | 221 | case PT_BIDICL: 222 | if ((UCD_BIDICLASS_PROP(prop) == data[1]) == isprop) 223 | return !negated; 224 | break; 225 | 226 | case PT_BOOL: 227 | ok = MAPBIT(PRIV(ucd_boolprop_sets) + 228 | UCD_BPROPS_PROP(prop), data[1]) != 0; 229 | if (ok == isprop) return !negated; 230 | break; 231 | 232 | /* The following three properties can occur only in an XCLASS, as there 233 | is no \p or \P coding for them. */ 234 | 235 | /* Graphic character. Implement this as not Z (space or separator) and 236 | not C (other), except for Cf (format) with a few exceptions. This seems 237 | to be what Perl does. The exceptional characters are: 238 | 239 | U+061C Arabic Letter Mark 240 | U+180E Mongolian Vowel Separator 241 | U+2066 - U+2069 Various "isolate"s 242 | */ 243 | 244 | case PT_PXGRAPH: 245 | chartype = prop->chartype; 246 | if ((PRIV(ucp_gentype)[chartype] != ucp_Z && 247 | (PRIV(ucp_gentype)[chartype] != ucp_C || 248 | (chartype == ucp_Cf && 249 | c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) 250 | )) == isprop) 251 | return !negated; 252 | break; 253 | 254 | /* Printable character: same as graphic, with the addition of Zs, i.e. 255 | not Zl and not Zp, and U+180E. */ 256 | 257 | case PT_PXPRINT: 258 | chartype = prop->chartype; 259 | if ((chartype != ucp_Zl && 260 | chartype != ucp_Zp && 261 | (PRIV(ucp_gentype)[chartype] != ucp_C || 262 | (chartype == ucp_Cf && 263 | c != 0x061c && (c < 0x2066 || c > 0x2069)) 264 | )) == isprop) 265 | return !negated; 266 | break; 267 | 268 | /* Punctuation: all Unicode punctuation, plus ASCII characters that 269 | Unicode treats as symbols rather than punctuation, for Perl 270 | compatibility (these are $+<=>^`|~). */ 271 | 272 | case PT_PXPUNCT: 273 | chartype = prop->chartype; 274 | if ((PRIV(ucp_gentype)[chartype] == ucp_P || 275 | (c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop) 276 | return !negated; 277 | break; 278 | 279 | /* Perl has two sets of hex digits */ 280 | 281 | case PT_PXXDIGIT: 282 | if (((c >= CHAR_0 && c <= CHAR_9) || 283 | (c >= CHAR_A && c <= CHAR_F) || 284 | (c >= CHAR_a && c <= CHAR_f) || 285 | (c >= 0xff10 && c <= 0xff19) || /* Fullwidth digits */ 286 | (c >= 0xff21 && c <= 0xff26) || /* Fullwidth letters */ 287 | (c >= 0xff41 && c <= 0xff46)) == isprop) 288 | return !negated; 289 | break; 290 | 291 | /* This should never occur, but compilers may mutter if there is no 292 | default. */ 293 | 294 | default: 295 | return FALSE; 296 | } 297 | 298 | data += 2; 299 | } 300 | #else 301 | (void)utf; /* Avoid compiler warning */ 302 | #endif /* SUPPORT_UNICODE */ 303 | } 304 | 305 | return negated; /* char did not match */ 306 | } 307 | 308 | /* End of pcre2_xclass.c */ 309 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/pcre2posix.h: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* PCRE2 is a library of functions to support regular expressions whose syntax 6 | and semantics are as close as possible to those of the Perl 5 language. This is 7 | the public header file to be #included by applications that call PCRE2 via the 8 | POSIX wrapper interface. 9 | 10 | Written by Philip Hazel 11 | Original API code Copyright (c) 1997-2012 University of Cambridge 12 | New API code Copyright (c) 2016-2023 University of Cambridge 13 | 14 | ----------------------------------------------------------------------------- 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | * Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in the 23 | documentation and/or other materials provided with the distribution. 24 | 25 | * Neither the name of the University of Cambridge nor the names of its 26 | contributors may be used to endorse or promote products derived from 27 | this software without specific prior written permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 30 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 33 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 34 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 35 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 36 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 37 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 | POSSIBILITY OF SUCH DAMAGE. 40 | ----------------------------------------------------------------------------- 41 | */ 42 | 43 | #ifndef PCRE2POSIX_H_IDEMPOTENT_GUARD 44 | #define PCRE2POSIX_H_IDEMPOTENT_GUARD 45 | 46 | /* Have to include stdlib.h in order to ensure that size_t is defined. */ 47 | 48 | #include 49 | 50 | /* Allow for C++ users */ 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | /* Options, mostly defined by POSIX, but with some extras. */ 57 | 58 | #define REG_ICASE 0x0001 /* Maps to PCRE2_CASELESS */ 59 | #define REG_NEWLINE 0x0002 /* Maps to PCRE2_MULTILINE */ 60 | #define REG_NOTBOL 0x0004 /* Maps to PCRE2_NOTBOL */ 61 | #define REG_NOTEOL 0x0008 /* Maps to PCRE2_NOTEOL */ 62 | #define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE2_DOTALL */ 63 | #define REG_NOSUB 0x0020 /* Do not report what was matched */ 64 | #define REG_UTF 0x0040 /* NOT defined by POSIX; maps to PCRE2_UTF */ 65 | #define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */ 66 | #define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE2_NOTEMPTY */ 67 | #define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE2_UNGREEDY */ 68 | #define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE2_UCP */ 69 | #define REG_PEND 0x0800 /* GNU feature: pass end pattern by re_endp */ 70 | #define REG_NOSPEC 0x1000 /* Maps to PCRE2_LITERAL */ 71 | 72 | /* This is not used by PCRE2, but by defining it we make it easier 73 | to slot PCRE2 into existing programs that make POSIX calls. */ 74 | 75 | #define REG_EXTENDED 0 76 | 77 | /* Error values. Not all these are relevant or used by the wrapper. */ 78 | 79 | enum { 80 | REG_ASSERT = 1, /* internal error ? */ 81 | REG_BADBR, /* invalid repeat counts in {} */ 82 | REG_BADPAT, /* pattern error */ 83 | REG_BADRPT, /* ? * + invalid */ 84 | REG_EBRACE, /* unbalanced {} */ 85 | REG_EBRACK, /* unbalanced [] */ 86 | REG_ECOLLATE, /* collation error - not relevant */ 87 | REG_ECTYPE, /* bad class */ 88 | REG_EESCAPE, /* bad escape sequence */ 89 | REG_EMPTY, /* empty expression */ 90 | REG_EPAREN, /* unbalanced () */ 91 | REG_ERANGE, /* bad range inside [] */ 92 | REG_ESIZE, /* expression too big */ 93 | REG_ESPACE, /* failed to get memory */ 94 | REG_ESUBREG, /* bad back reference */ 95 | REG_INVARG, /* bad argument */ 96 | REG_NOMATCH /* match failed */ 97 | }; 98 | 99 | 100 | /* The structure representing a compiled regular expression. It is also used 101 | for passing the pattern end pointer when REG_PEND is set. */ 102 | 103 | typedef struct { 104 | void *re_pcre2_code; 105 | void *re_match_data; 106 | const char *re_endp; 107 | size_t re_nsub; 108 | size_t re_erroffset; 109 | int re_cflags; 110 | } regex_t; 111 | 112 | /* The structure in which a captured offset is returned. */ 113 | 114 | typedef int regoff_t; 115 | 116 | typedef struct { 117 | regoff_t rm_so; 118 | regoff_t rm_eo; 119 | } regmatch_t; 120 | 121 | /* When compiling with the MSVC compiler, it is sometimes necessary to include 122 | a "calling convention" before exported function names. (This is secondhand 123 | information; I know nothing about MSVC myself). For example, something like 124 | 125 | void __cdecl function(....) 126 | 127 | might be needed. In order to make this easy, all the exported functions have 128 | PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not 129 | set, we ensure here that it has no effect. */ 130 | 131 | #ifndef PCRE2_CALL_CONVENTION 132 | #define PCRE2_CALL_CONVENTION 133 | #endif 134 | 135 | #ifndef PCRE2_EXPORT 136 | #define PCRE2_EXPORT 137 | #endif 138 | 139 | /* When an application links to a PCRE2 DLL in Windows, the symbols that are 140 | imported have to be identified as such. When building PCRE2, the appropriate 141 | export settings are needed, and are set in pcre2posix.c before including this 142 | file. */ 143 | 144 | /* By default, we use the standard "extern" declarations. */ 145 | 146 | #ifndef PCRE2POSIX_EXP_DECL 147 | # if defined(_WIN32) && defined(PCRE2POSIX_SHARED) && !defined(PCRE2_STATIC) 148 | # define PCRE2POSIX_EXP_DECL extern __declspec(dllimport) 149 | # define PCRE2POSIX_EXP_DEFN __declspec(dllimport) 150 | # else 151 | # define PCRE2POSIX_EXP_DECL extern PCRE2_EXPORT 152 | # define PCRE2POSIX_EXP_DEFN 153 | # endif 154 | #endif 155 | 156 | /* The functions. The actual code is in functions with pcre2_xxx names for 157 | uniqueness. POSIX names are provided as macros for API compatibility with POSIX 158 | regex functions. It's done this way to ensure to they are always linked from 159 | the PCRE2 library and not by accident from elsewhere (regex_t differs in size 160 | elsewhere). */ 161 | 162 | PCRE2POSIX_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_regcomp(regex_t *, const char *, int); 163 | PCRE2POSIX_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_regexec(const regex_t *, const char *, size_t, 164 | regmatch_t *, int); 165 | PCRE2POSIX_EXP_DECL size_t PCRE2_CALL_CONVENTION pcre2_regerror(int, const regex_t *, char *, size_t); 166 | PCRE2POSIX_EXP_DECL void PCRE2_CALL_CONVENTION pcre2_regfree(regex_t *); 167 | 168 | #define regcomp pcre2_regcomp 169 | #define regexec pcre2_regexec 170 | #define regerror pcre2_regerror 171 | #define regfree pcre2_regfree 172 | 173 | /* Debian had a patch that used different names. These are now here to save 174 | them having to maintain their own patch, but are not documented by PCRE2. */ 175 | 176 | #define PCRE2regcomp pcre2_regcomp 177 | #define PCRE2regexec pcre2_regexec 178 | #define PCRE2regerror pcre2_regerror 179 | #define PCRE2regfree pcre2_regfree 180 | 181 | #ifdef __cplusplus 182 | } /* extern "C" */ 183 | #endif 184 | 185 | #endif /* PCRE2POSIX_H_IDEMPOTENT_GUARD */ 186 | 187 | /* End of pcre2posix.h */ 188 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitExecAllocatorApple.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | #include 29 | /* 30 | On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a 31 | version where it's OK to have more than one JIT block or where MAP_JIT is 32 | required. 33 | On non-macOS systems, returns MAP_JIT if it is defined. 34 | */ 35 | #include 36 | 37 | #if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (TARGET_OS_MAC && !TARGET_OS_IPHONE) 38 | 39 | #if defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86 40 | 41 | #include 42 | #include 43 | 44 | #define SLJIT_MAP_JIT (get_map_jit_flag()) 45 | #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) 46 | 47 | static SLJIT_INLINE int get_map_jit_flag(void) 48 | { 49 | size_t page_size; 50 | void *ptr; 51 | struct utsname name; 52 | static int map_jit_flag = -1; 53 | 54 | if (map_jit_flag < 0) { 55 | map_jit_flag = 0; 56 | uname(&name); 57 | 58 | /* Kernel version for 10.14.0 (Mojave) or later */ 59 | if (atoi(name.release) >= 18) { 60 | page_size = get_page_alignment() + 1; 61 | /* Only use MAP_JIT if a hardened runtime is used */ 62 | ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, 63 | MAP_PRIVATE | MAP_ANON, -1, 0); 64 | 65 | if (ptr != MAP_FAILED) 66 | munmap(ptr, page_size); 67 | else 68 | map_jit_flag = MAP_JIT; 69 | } 70 | } 71 | return map_jit_flag; 72 | } 73 | 74 | #elif defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM 75 | 76 | #include 77 | #include 78 | 79 | #define SLJIT_MAP_JIT (MAP_JIT) 80 | #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ 81 | apple_update_wx_flags(enable_exec) 82 | 83 | static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec) 84 | { 85 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 110000 86 | if (__builtin_available(macos 11, *)) 87 | #endif /* BigSur */ 88 | pthread_jit_write_protect_np(enable_exec); 89 | } 90 | 91 | #elif defined(SLJIT_CONFIG_PPC) && SLJIT_CONFIG_PPC 92 | 93 | #define SLJIT_MAP_JIT (0) 94 | #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) 95 | 96 | #else 97 | #error "Unsupported architecture" 98 | #endif /* SLJIT_CONFIG */ 99 | 100 | #else /* !TARGET_OS_OSX */ 101 | 102 | #ifdef MAP_JIT 103 | #define SLJIT_MAP_JIT (MAP_JIT) 104 | #else 105 | #define SLJIT_MAP_JIT (0) 106 | #endif 107 | 108 | #endif /* TARGET_OS_OSX */ 109 | 110 | static SLJIT_INLINE void* alloc_chunk(sljit_uw size) 111 | { 112 | void *retval; 113 | int prot = PROT_READ | PROT_WRITE | PROT_EXEC; 114 | int flags = MAP_PRIVATE; 115 | int fd = -1; 116 | 117 | flags |= MAP_ANON | SLJIT_MAP_JIT; 118 | 119 | retval = mmap(NULL, size, prot, flags, fd, 0); 120 | if (retval == MAP_FAILED) 121 | return NULL; 122 | 123 | SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0); 124 | 125 | return retval; 126 | } 127 | 128 | static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) 129 | { 130 | munmap(chunk, size); 131 | } 132 | 133 | #include "sljitExecAllocatorCore.c" 134 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #ifdef PROC_WXMAP_CTL 31 | static SLJIT_INLINE int sljit_is_wx_block(void) 32 | { 33 | static int wx_block = -1; 34 | if (wx_block < 0) { 35 | int sljit_wx_enable = PROC_WX_MAPPINGS_PERMIT; 36 | wx_block = !!procctl(P_PID, 0, PROC_WXMAP_CTL, &sljit_wx_enable); 37 | } 38 | return wx_block; 39 | } 40 | 41 | #define SLJIT_IS_WX_BLOCK sljit_is_wx_block() 42 | #else /* !PROC_WXMAP_CTL */ 43 | #define SLJIT_IS_WX_BLOCK (1) 44 | #endif /* PROC_WXMAP_CTL */ 45 | 46 | static SLJIT_INLINE void* alloc_chunk(sljit_uw size) 47 | { 48 | void *retval; 49 | int prot = PROT_READ | PROT_WRITE | PROT_EXEC; 50 | int flags = MAP_PRIVATE; 51 | int fd = -1; 52 | 53 | #ifdef PROT_MAX 54 | prot |= PROT_MAX(prot); 55 | #endif 56 | 57 | #ifdef MAP_ANON 58 | flags |= MAP_ANON; 59 | #else /* !MAP_ANON */ 60 | if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) 61 | return NULL; 62 | 63 | fd = dev_zero; 64 | #endif /* MAP_ANON */ 65 | 66 | retry: 67 | retval = mmap(NULL, size, prot, flags, fd, 0); 68 | if (retval == MAP_FAILED) { 69 | if (!SLJIT_IS_WX_BLOCK) 70 | goto retry; 71 | 72 | return NULL; 73 | } 74 | 75 | /* HardenedBSD's mmap lies, so check permissions again. */ 76 | if (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { 77 | munmap(retval, size); 78 | return NULL; 79 | } 80 | 81 | return retval; 82 | } 83 | 84 | static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) 85 | { 86 | munmap(chunk, size); 87 | } 88 | 89 | #include "sljitExecAllocatorCore.c" 90 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitExecAllocatorPosix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | static SLJIT_INLINE void* alloc_chunk(sljit_uw size) 31 | { 32 | void *retval; 33 | int prot = PROT_READ | PROT_WRITE | PROT_EXEC; 34 | int flags = MAP_PRIVATE; 35 | int fd = -1; 36 | 37 | #ifdef PROT_MAX 38 | prot |= PROT_MAX(prot); 39 | #endif 40 | 41 | #ifdef MAP_ANON 42 | flags |= MAP_ANON; 43 | #else /* !MAP_ANON */ 44 | if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) 45 | return NULL; 46 | 47 | fd = dev_zero; 48 | #endif /* MAP_ANON */ 49 | 50 | retval = mmap(NULL, size, prot, flags, fd, 0); 51 | if (retval == MAP_FAILED) 52 | return NULL; 53 | 54 | return retval; 55 | } 56 | 57 | static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) 58 | { 59 | munmap(chunk, size); 60 | } 61 | 62 | #include "sljitExecAllocatorCore.c" 63 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitExecAllocatorWindows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) 28 | 29 | static SLJIT_INLINE void* alloc_chunk(sljit_uw size) 30 | { 31 | return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 32 | } 33 | 34 | static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) 35 | { 36 | SLJIT_UNUSED_ARG(size); 37 | VirtualFree(chunk, 0, MEM_RELEASE); 38 | } 39 | 40 | #include "sljitExecAllocatorCore.c" 41 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #define SLJIT_HAS_CHUNK_HEADER 28 | #define SLJIT_HAS_EXECUTABLE_OFFSET 29 | 30 | struct sljit_chunk_header { 31 | void *executable; 32 | }; 33 | 34 | /* 35 | * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to 36 | * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed 37 | */ 38 | static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size) 39 | { 40 | struct sljit_chunk_header *retval; 41 | 42 | retval = (struct sljit_chunk_header *)mmap(NULL, size, 43 | PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC), 44 | MAP_ANON | MAP_SHARED, -1, 0); 45 | 46 | if (retval == MAP_FAILED) 47 | return NULL; 48 | 49 | retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP); 50 | if (retval->executable == MAP_FAILED) { 51 | munmap((void *)retval, size); 52 | return NULL; 53 | } 54 | 55 | if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) { 56 | munmap(retval->executable, size); 57 | munmap((void *)retval, size); 58 | return NULL; 59 | } 60 | 61 | return retval; 62 | } 63 | 64 | static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) 65 | { 66 | struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1; 67 | 68 | munmap(header->executable, size); 69 | munmap((void *)header, size); 70 | } 71 | 72 | #include "sljitExecAllocatorCore.c" 73 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #define SLJIT_HAS_CHUNK_HEADER 28 | #define SLJIT_HAS_EXECUTABLE_OFFSET 29 | 30 | struct sljit_chunk_header { 31 | void *executable; 32 | }; 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #ifndef O_NOATIME 40 | #define O_NOATIME 0 41 | #endif 42 | 43 | /* this is a linux extension available since kernel 3.11 */ 44 | #ifndef O_TMPFILE 45 | #define O_TMPFILE 0x404000 46 | #endif 47 | 48 | #ifndef _GNU_SOURCE 49 | char *secure_getenv(const char *name); 50 | int mkostemp(char *template, int flags); 51 | #endif 52 | 53 | static SLJIT_INLINE int create_tempfile(void) 54 | { 55 | int fd; 56 | char tmp_name[256]; 57 | size_t tmp_name_len = 0; 58 | char *dir; 59 | struct stat st; 60 | #if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED 61 | mode_t mode; 62 | #endif 63 | 64 | #ifdef HAVE_MEMFD_CREATE 65 | /* this is a GNU extension, make sure to use -D_GNU_SOURCE */ 66 | fd = memfd_create("sljit", MFD_CLOEXEC); 67 | if (fd != -1) { 68 | fchmod(fd, 0); 69 | return fd; 70 | } 71 | #endif 72 | 73 | dir = secure_getenv("TMPDIR"); 74 | 75 | if (dir) { 76 | size_t len = strlen(dir); 77 | if (len > 0 && len < sizeof(tmp_name)) { 78 | if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) { 79 | memcpy(tmp_name, dir, len + 1); 80 | tmp_name_len = len; 81 | } 82 | } 83 | } 84 | 85 | #ifdef P_tmpdir 86 | if (!tmp_name_len) { 87 | tmp_name_len = strlen(P_tmpdir); 88 | if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) 89 | strcpy(tmp_name, P_tmpdir); 90 | } 91 | #endif 92 | if (!tmp_name_len) { 93 | strcpy(tmp_name, "/tmp"); 94 | tmp_name_len = 4; 95 | } 96 | 97 | SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)); 98 | 99 | if (tmp_name_len > 1 && tmp_name[tmp_name_len - 1] == '/') 100 | tmp_name[--tmp_name_len] = '\0'; 101 | 102 | fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0); 103 | if (fd != -1) 104 | return fd; 105 | 106 | if (tmp_name_len >= sizeof(tmp_name) - 7) 107 | return -1; 108 | 109 | strcpy(tmp_name + tmp_name_len, "/XXXXXX"); 110 | #if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED 111 | mode = umask(0777); 112 | #endif 113 | fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME); 114 | #if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED 115 | umask(mode); 116 | #else 117 | fchmod(fd, 0); 118 | #endif 119 | 120 | if (fd == -1) 121 | return -1; 122 | 123 | if (unlink(tmp_name)) { 124 | close(fd); 125 | return -1; 126 | } 127 | 128 | return fd; 129 | } 130 | 131 | static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size) 132 | { 133 | struct sljit_chunk_header *retval; 134 | int fd; 135 | 136 | fd = create_tempfile(); 137 | if (fd == -1) 138 | return NULL; 139 | 140 | if (ftruncate(fd, (off_t)size)) { 141 | close(fd); 142 | return NULL; 143 | } 144 | 145 | retval = (struct sljit_chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 146 | 147 | if (retval == MAP_FAILED) { 148 | close(fd); 149 | return NULL; 150 | } 151 | 152 | retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); 153 | 154 | if (retval->executable == MAP_FAILED) { 155 | munmap((void *)retval, size); 156 | close(fd); 157 | return NULL; 158 | } 159 | 160 | close(fd); 161 | return retval; 162 | } 163 | 164 | static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) 165 | { 166 | struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1; 167 | 168 | munmap(header->executable, size); 169 | munmap((void *)header, size); 170 | } 171 | 172 | #include "sljitExecAllocatorCore.c" 173 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | /* 28 | This file contains a simple W^X executable memory allocator 29 | 30 | In *NIX, MAP_ANON is required (that is considered a feature) so make 31 | sure to set the right availability macros for your system or the code 32 | will fail to build. 33 | 34 | If your system doesn't support mapping of anonymous pages (ex: IRIX) it 35 | is also likely that it doesn't need this allocator and should be using 36 | the standard one instead. 37 | 38 | It allocates a separate map for each code block and may waste a lot of 39 | memory, because whatever was requested, will be rounded up to the page 40 | size (minimum 4KB, but could be even bigger). 41 | 42 | It changes the page permissions (RW <-> RX) as needed and therefore, if you 43 | will be updating the code after it has been generated, need to make sure to 44 | block any concurrent execution, or could result in a SIGBUS, that could 45 | even manifest itself at a different address than the one that was being 46 | modified. 47 | 48 | Only use if you are unable to use the regular allocator because of security 49 | restrictions and adding exceptions to your application or the system are 50 | not possible. 51 | */ 52 | 53 | #include 54 | #include 55 | 56 | #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ 57 | sljit_update_wx_flags((from), (to), (enable_exec)) 58 | 59 | #if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) 60 | #include 61 | #define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock) 62 | #define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock) 63 | #else 64 | #define SLJIT_SE_LOCK() 65 | #define SLJIT_SE_UNLOCK() 66 | #endif /* !SLJIT_SINGLE_THREADED */ 67 | 68 | #define SLJIT_WX_IS_BLOCK(ptr, size) generic_check_is_wx_block(ptr, size) 69 | 70 | static SLJIT_INLINE int generic_check_is_wx_block(void *ptr, sljit_uw size) 71 | { 72 | if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC))) 73 | return !!mprotect(ptr, size, PROT_READ | PROT_WRITE); 74 | 75 | return 1; 76 | } 77 | 78 | SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) 79 | { 80 | #if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) 81 | static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER; 82 | #endif 83 | static int wx_block = -1; 84 | int prot = PROT_READ | PROT_WRITE; 85 | sljit_uw* ptr; 86 | 87 | if (SLJIT_UNLIKELY(wx_block > 0)) 88 | return NULL; 89 | 90 | #ifdef PROT_MAX 91 | prot |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC); 92 | #endif 93 | 94 | size += sizeof(sljit_uw); 95 | ptr = (sljit_uw*)mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0); 96 | 97 | if (ptr == MAP_FAILED) 98 | return NULL; 99 | 100 | if (SLJIT_UNLIKELY(wx_block < 0)) { 101 | SLJIT_SE_LOCK(); 102 | wx_block = SLJIT_WX_IS_BLOCK(ptr, size); 103 | SLJIT_SE_UNLOCK(); 104 | if (SLJIT_UNLIKELY(wx_block)) { 105 | munmap((void *)ptr, size); 106 | return NULL; 107 | } 108 | } 109 | 110 | *ptr++ = size; 111 | return ptr; 112 | } 113 | 114 | #undef SLJIT_SE_UNLOCK 115 | #undef SLJIT_SE_LOCK 116 | 117 | SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) 118 | { 119 | sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1; 120 | munmap((void*)start_ptr, *start_ptr); 121 | } 122 | 123 | static void sljit_update_wx_flags(void *from, void *to, int enable_exec) 124 | { 125 | sljit_uw page_mask = (sljit_uw)get_page_alignment(); 126 | sljit_uw start = (sljit_uw)from; 127 | sljit_uw end = (sljit_uw)to; 128 | int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE); 129 | 130 | SLJIT_ASSERT(start < end); 131 | 132 | start &= ~page_mask; 133 | end = (end + page_mask) & ~page_mask; 134 | 135 | mprotect((void*)start, end - start, prot); 136 | } 137 | 138 | SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) 139 | { 140 | /* This allocator does not keep unused memory for future allocations. */ 141 | } 142 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | /* 28 | This file contains a simple W^X executable memory allocator 29 | 30 | In *NIX, MAP_ANON is required (that is considered a feature) so make 31 | sure to set the right availability macros for your system or the code 32 | will fail to build. 33 | 34 | If your system doesn't support mapping of anonymous pages (ex: IRIX) it 35 | is also likely that it doesn't need this allocator and should be using 36 | the standard one instead. 37 | 38 | It allocates a separate map for each code block and may waste a lot of 39 | memory, because whatever was requested, will be rounded up to the page 40 | size (minimum 4KB, but could be even bigger). 41 | 42 | It changes the page permissions (RW <-> RX) as needed and therefore, if you 43 | will be updating the code after it has been generated, need to make sure to 44 | block any concurrent execution, or could result in a SIGBUS, that could 45 | even manifest itself at a different address than the one that was being 46 | modified. 47 | 48 | Only use if you are unable to use the regular allocator because of security 49 | restrictions and adding exceptions to your application or the system are 50 | not possible. 51 | */ 52 | 53 | #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ 54 | sljit_update_wx_flags((from), (to), (enable_exec)) 55 | 56 | SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) 57 | { 58 | sljit_uw *ptr; 59 | 60 | size += sizeof(sljit_uw); 61 | ptr = (sljit_uw*)VirtualAlloc(NULL, size, 62 | MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 63 | 64 | if (!ptr) 65 | return NULL; 66 | 67 | *ptr++ = size; 68 | 69 | return ptr; 70 | } 71 | 72 | SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) 73 | { 74 | sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw); 75 | #if defined(SLJIT_DEBUG) && SLJIT_DEBUG 76 | sljit_uw page_mask = (sljit_uw)get_page_alignment(); 77 | 78 | SLJIT_ASSERT(!(start & page_mask)); 79 | #endif 80 | VirtualFree((void*)start, 0, MEM_RELEASE); 81 | } 82 | 83 | static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec) 84 | { 85 | DWORD oldprot; 86 | sljit_uw page_mask = (sljit_uw)get_page_alignment(); 87 | sljit_uw start = (sljit_uw)from; 88 | sljit_uw end = (sljit_uw)to; 89 | DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE; 90 | 91 | SLJIT_ASSERT(start < end); 92 | 93 | start &= ~page_mask; 94 | end = (end + page_mask) & ~page_mask; 95 | 96 | VirtualProtect((void*)start, end - start, prot, &oldprot); 97 | } 98 | 99 | SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) 100 | { 101 | /* This allocator does not keep unused memory for future allocations. */ 102 | } 103 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/sljitConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef SLJIT_CONFIG_H_ 28 | #define SLJIT_CONFIG_H_ 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* 35 | This file contains the basic configuration options for the SLJIT compiler 36 | and their default values. These options can be overridden in the 37 | sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a 38 | non-zero value. 39 | */ 40 | 41 | /* --------------------------------------------------------------------- */ 42 | /* Utilities */ 43 | /* --------------------------------------------------------------------- */ 44 | 45 | /* Implements a stack like data structure (by using mmap / VirtualAlloc */ 46 | /* or a custom allocator). */ 47 | #ifndef SLJIT_UTIL_STACK 48 | /* Enabled by default */ 49 | #define SLJIT_UTIL_STACK 1 50 | #endif 51 | 52 | /* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */ 53 | #ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 54 | /* Disabled by default */ 55 | #define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0 56 | #endif 57 | 58 | /* Single threaded application. Does not require any locks. */ 59 | #ifndef SLJIT_SINGLE_THREADED 60 | /* Disabled by default. */ 61 | #define SLJIT_SINGLE_THREADED 0 62 | #endif 63 | 64 | /* --------------------------------------------------------------------- */ 65 | /* Configuration */ 66 | /* --------------------------------------------------------------------- */ 67 | 68 | /* If SLJIT_STD_MACROS_DEFINED is not defined, the application should 69 | define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */ 70 | #ifndef SLJIT_STD_MACROS_DEFINED 71 | /* Disabled by default. */ 72 | #define SLJIT_STD_MACROS_DEFINED 0 73 | #endif 74 | 75 | /* Executable code allocation: 76 | If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should 77 | define SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. 78 | Optionally, depending on the implementation used for the allocator, 79 | SLJIT_EXEC_OFFSET and SLJIT_UPDATE_WX_FLAGS might also be needed. */ 80 | #ifndef SLJIT_EXECUTABLE_ALLOCATOR 81 | /* Enabled by default. */ 82 | #define SLJIT_EXECUTABLE_ALLOCATOR 1 83 | 84 | /* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses 85 | an allocator which does not set writable and executable 86 | permission flags at the same time. 87 | Instead, it creates a shared memory segment (usually backed by a file) 88 | and maps it twice, with different permissions, depending on the use 89 | case. 90 | The trade-off is increased use of virtual memory, incompatibility with 91 | fork(), and some possible additional security risks by the use of 92 | publicly accessible files for the generated code. */ 93 | #ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR 94 | /* Disabled by default. */ 95 | #define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0 96 | #endif 97 | 98 | /* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an 99 | allocator which does not set writable and executable permission 100 | flags at the same time. 101 | Instead, it creates a new independent map on each invocation and 102 | switches permissions at the underlying pages as needed. 103 | The trade-off is increased memory use and degraded performance. */ 104 | #ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR 105 | /* Disabled by default. */ 106 | #define SLJIT_WX_EXECUTABLE_ALLOCATOR 0 107 | #endif 108 | 109 | #endif /* !SLJIT_EXECUTABLE_ALLOCATOR */ 110 | 111 | /* Return with error when an invalid argument is passed. */ 112 | #ifndef SLJIT_ARGUMENT_CHECKS 113 | /* Disabled by default */ 114 | #define SLJIT_ARGUMENT_CHECKS 0 115 | #endif 116 | 117 | /* Debug checks (assertions, etc.). */ 118 | #ifndef SLJIT_DEBUG 119 | /* Enabled by default */ 120 | #define SLJIT_DEBUG 1 121 | #endif 122 | 123 | /* Verbose operations. */ 124 | #ifndef SLJIT_VERBOSE 125 | /* Enabled by default */ 126 | #define SLJIT_VERBOSE 1 127 | #endif 128 | 129 | /* 130 | SLJIT_IS_FPU_AVAILABLE 131 | The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE. 132 | zero value - FPU is NOT present. 133 | nonzero value - FPU is present. 134 | */ 135 | 136 | /* For further configurations, see the beginning of sljitConfigInternal.h */ 137 | 138 | #ifdef __cplusplus 139 | } /* extern "C" */ 140 | #endif 141 | 142 | #endif /* SLJIT_CONFIG_H_ */ 143 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/sljitConfigCPU.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef SLJIT_CONFIG_CPU_H_ 28 | #define SLJIT_CONFIG_CPU_H_ 29 | 30 | /* --------------------------------------------------------------------- */ 31 | /* Architecture */ 32 | /* --------------------------------------------------------------------- */ 33 | 34 | /* Architecture selection. */ 35 | /* #define SLJIT_CONFIG_X86_32 1 */ 36 | /* #define SLJIT_CONFIG_X86_64 1 */ 37 | /* #define SLJIT_CONFIG_ARM_V6 1 */ 38 | /* #define SLJIT_CONFIG_ARM_V7 1 */ 39 | /* #define SLJIT_CONFIG_ARM_THUMB2 1 */ 40 | /* #define SLJIT_CONFIG_ARM_64 1 */ 41 | /* #define SLJIT_CONFIG_PPC_32 1 */ 42 | /* #define SLJIT_CONFIG_PPC_64 1 */ 43 | /* #define SLJIT_CONFIG_MIPS_32 1 */ 44 | /* #define SLJIT_CONFIG_MIPS_64 1 */ 45 | /* #define SLJIT_CONFIG_RISCV_32 1 */ 46 | /* #define SLJIT_CONFIG_RISCV_64 1 */ 47 | /* #define SLJIT_CONFIG_S390X 1 */ 48 | /* #define SLJIT_CONFIG_LOONGARCH_64 */ 49 | 50 | /* #define SLJIT_CONFIG_AUTO 1 */ 51 | /* #define SLJIT_CONFIG_UNSUPPORTED 1 */ 52 | 53 | /*****************/ 54 | /* Sanity check. */ 55 | /*****************/ 56 | 57 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ 58 | + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ 59 | + (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \ 60 | + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ 61 | + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ 62 | + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ 63 | + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ 64 | + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ 65 | + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ 66 | + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ 67 | + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ 68 | + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ 69 | + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ 70 | + (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \ 71 | + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ 72 | + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 73 | #error "Multiple architectures are selected" 74 | #endif 75 | 76 | #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ 77 | && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ 78 | && !(defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \ 79 | && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ 80 | && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ 81 | && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ 82 | && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ 83 | && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ 84 | && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ 85 | && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ 86 | && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ 87 | && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ 88 | && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ 89 | && !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \ 90 | && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \ 91 | && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) 92 | #if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO 93 | #error "An architecture must be selected" 94 | #else /* SLJIT_CONFIG_AUTO */ 95 | #define SLJIT_CONFIG_AUTO 1 96 | #endif /* !SLJIT_CONFIG_AUTO */ 97 | #endif /* !SLJIT_CONFIG */ 98 | 99 | /********************************************************/ 100 | /* Automatic CPU detection (requires compiler support). */ 101 | /********************************************************/ 102 | 103 | #if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) 104 | #ifndef _WIN32 105 | 106 | #if defined(__i386__) || defined(__i386) 107 | #define SLJIT_CONFIG_X86_32 1 108 | #elif defined(__x86_64__) 109 | #define SLJIT_CONFIG_X86_64 1 110 | #elif defined(__aarch64__) 111 | #define SLJIT_CONFIG_ARM_64 1 112 | #elif defined(__thumb2__) 113 | #define SLJIT_CONFIG_ARM_THUMB2 1 114 | #elif (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \ 115 | ((defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__)) \ 116 | || (defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8R__)) \ 117 | || (defined(__ARM_ARCH_9A__))) 118 | #define SLJIT_CONFIG_ARM_V7 1 119 | #elif defined(__arm__) || defined (__ARM__) 120 | #define SLJIT_CONFIG_ARM_V6 1 121 | #elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__)) 122 | #define SLJIT_CONFIG_PPC_64 1 123 | #elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) 124 | #define SLJIT_CONFIG_PPC_32 1 125 | #elif defined(__mips__) && !defined(_LP64) 126 | #define SLJIT_CONFIG_MIPS_32 1 127 | #elif defined(__mips64) 128 | #define SLJIT_CONFIG_MIPS_64 1 129 | #elif defined (__riscv_xlen) && (__riscv_xlen == 32) 130 | #define SLJIT_CONFIG_RISCV_32 1 131 | #elif defined (__riscv_xlen) && (__riscv_xlen == 64) 132 | #define SLJIT_CONFIG_RISCV_64 1 133 | #elif defined (__loongarch_lp64) 134 | #define SLJIT_CONFIG_LOONGARCH_64 1 135 | #elif defined(__s390x__) 136 | #define SLJIT_CONFIG_S390X 1 137 | #else 138 | /* Unsupported architecture */ 139 | #define SLJIT_CONFIG_UNSUPPORTED 1 140 | #endif 141 | 142 | #else /* _WIN32 */ 143 | 144 | #if defined(_M_X64) || defined(__x86_64__) 145 | #define SLJIT_CONFIG_X86_64 1 146 | #elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__) 147 | #define SLJIT_CONFIG_ARM_THUMB2 1 148 | #elif (defined(_M_ARM) && _M_ARM >= 7) 149 | #define SLJIT_CONFIG_ARM_V7 1 150 | #elif defined(_ARM_) 151 | #define SLJIT_CONFIG_ARM_V6 1 152 | #elif defined(_M_ARM64) || defined(__aarch64__) 153 | #define SLJIT_CONFIG_ARM_64 1 154 | #else 155 | #define SLJIT_CONFIG_X86_32 1 156 | #endif 157 | 158 | #endif /* !_WIN32 */ 159 | #endif /* SLJIT_CONFIG_AUTO */ 160 | 161 | #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) 162 | #undef SLJIT_EXECUTABLE_ALLOCATOR 163 | #endif /* SLJIT_CONFIG_UNSUPPORTED */ 164 | 165 | /******************************/ 166 | /* CPU family type detection. */ 167 | /******************************/ 168 | 169 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ 170 | || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) 171 | #define SLJIT_CONFIG_ARM_32 1 172 | #endif 173 | 174 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) 175 | #define SLJIT_CONFIG_X86 1 176 | #elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) 177 | #define SLJIT_CONFIG_ARM 1 178 | #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 179 | #define SLJIT_CONFIG_PPC 1 180 | #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) 181 | #define SLJIT_CONFIG_MIPS 1 182 | #elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) 183 | #define SLJIT_CONFIG_RISCV 1 184 | #elif (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) 185 | #define SLJIT_CONFIG_LOONGARCH 1 186 | #endif 187 | 188 | #endif /* SLJIT_CONFIG_CPU_H_ */ 189 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/sljitNativeRISCV_32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r) 28 | { 29 | SLJIT_UNUSED_ARG(tmp_r); 30 | 31 | if (imm <= SIMM_MAX && imm >= SIMM_MIN) 32 | return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); 33 | 34 | if (imm & 0x800) 35 | imm += 0x1000; 36 | 37 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff))); 38 | 39 | if ((imm & 0xfff) == 0) 40 | return SLJIT_SUCCESS; 41 | 42 | return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); 43 | } 44 | 45 | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, 46 | sljit_s32 freg, sljit_f64 value) 47 | { 48 | union { 49 | sljit_s32 imm[2]; 50 | sljit_f64 value; 51 | } u; 52 | 53 | CHECK_ERROR(); 54 | CHECK(check_sljit_emit_fset64(compiler, freg, value)); 55 | 56 | u.value = value; 57 | 58 | if (u.imm[0] != 0) 59 | FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0], TMP_REG3)); 60 | if (u.imm[1] != 0) 61 | FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1], TMP_REG3)); 62 | 63 | FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16))); 64 | FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | (8 << 7))); 65 | FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | (12 << 7))); 66 | FAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8))); 67 | return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16)); 68 | } 69 | 70 | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, 71 | sljit_s32 freg, sljit_s32 reg) 72 | { 73 | sljit_ins inst; 74 | sljit_s32 reg2 = 0; 75 | 76 | CHECK_ERROR(); 77 | CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); 78 | 79 | if (op & SLJIT_32) { 80 | if (op == SLJIT_COPY32_TO_F32) 81 | inst = FMV_W_X | RS1(reg) | FRD(freg); 82 | else 83 | inst = FMV_X_W | FRS1(freg) | RD(reg); 84 | 85 | return push_inst(compiler, inst); 86 | } 87 | 88 | FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16))); 89 | 90 | if (reg & REG_PAIR_MASK) { 91 | reg2 = REG_PAIR_SECOND(reg); 92 | reg = REG_PAIR_FIRST(reg); 93 | } 94 | 95 | if (op == SLJIT_COPY_TO_F64) { 96 | if (reg2 != 0) 97 | FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg2) | (8 << 7))); 98 | else 99 | FAIL_IF(push_inst(compiler, FSW | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7))); 100 | 101 | FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg) | (12 << 7))); 102 | FAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8))); 103 | } else { 104 | FAIL_IF(push_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7))); 105 | 106 | if (reg2 != 0) 107 | FAIL_IF(push_inst(compiler, FMV_X_W | FRS1(freg) | RD(reg2))); 108 | 109 | FAIL_IF(push_inst(compiler, LW | RD(reg) | RS1(SLJIT_SP) | IMM_I(12))); 110 | } 111 | 112 | return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16)); 113 | } 114 | 115 | static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) 116 | { 117 | if ((init_value & 0x800) != 0) 118 | init_value += 0x1000; 119 | 120 | FAIL_IF(push_inst(compiler, LUI | RD(dst) | (sljit_ins)(init_value & ~0xfff))); 121 | return push_inst(compiler, last_ins | RS1(dst) | IMM_I(init_value)); 122 | } 123 | 124 | SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) 125 | { 126 | sljit_ins *inst = (sljit_ins*)addr; 127 | SLJIT_UNUSED_ARG(executable_offset); 128 | 129 | if ((new_target & 0x800) != 0) 130 | new_target += 0x1000; 131 | 132 | SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0); 133 | 134 | SLJIT_ASSERT((inst[0] & 0x7f) == LUI); 135 | inst[0] = (inst[0] & 0xfff) | (sljit_ins)((sljit_sw)new_target & ~0xfff); 136 | SLJIT_ASSERT((inst[1] & 0x707f) == ADDI || (inst[1] & 0x707f) == JALR); 137 | inst[1] = (inst[1] & 0xfffff) | IMM_I(new_target); 138 | 139 | SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1); 140 | inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); 141 | SLJIT_CACHE_FLUSH(inst, inst + 5); 142 | } 143 | -------------------------------------------------------------------------------- /pcre2-sys/upstream/src/sljit/sljitNativeRISCV_64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stack-less Just-In-Time compiler 3 | * 4 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are 7 | * permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of 10 | * conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r) 28 | { 29 | sljit_sw high; 30 | 31 | if (imm <= SIMM_MAX && imm >= SIMM_MIN) 32 | return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); 33 | 34 | if (imm <= 0x7fffffffl && imm >= S32_MIN) { 35 | if (imm > S32_MAX) { 36 | SLJIT_ASSERT((imm & 0x800) != 0); 37 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u)); 38 | return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); 39 | } 40 | 41 | if ((imm & 0x800) != 0) 42 | imm += 0x1000; 43 | 44 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff))); 45 | 46 | if ((imm & 0xfff) == 0) 47 | return SLJIT_SUCCESS; 48 | 49 | return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); 50 | } 51 | 52 | /* Trailing zeroes could be used to produce shifted immediates. */ 53 | 54 | if (imm <= 0x7ffffffffffl && imm >= -0x80000000000l) { 55 | high = imm >> 12; 56 | 57 | if (imm & 0x800) 58 | high = ~high; 59 | 60 | if (high > S32_MAX) { 61 | SLJIT_ASSERT((high & 0x800) != 0); 62 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u)); 63 | FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(high))); 64 | } else { 65 | if ((high & 0x800) != 0) 66 | high += 0x1000; 67 | 68 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(high & ~0xfff))); 69 | 70 | if ((high & 0xfff) != 0) 71 | FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(high))); 72 | } 73 | 74 | FAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12))); 75 | 76 | if ((imm & 0xfff) != 0) 77 | return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); 78 | 79 | return SLJIT_SUCCESS; 80 | } 81 | 82 | SLJIT_ASSERT(dst_r != tmp_r); 83 | 84 | high = imm >> 32; 85 | imm = (sljit_s32)imm; 86 | 87 | if ((imm & 0x80000000l) != 0) 88 | high = ~high; 89 | 90 | if (high <= 0x7ffff && high >= -0x80000) { 91 | FAIL_IF(push_inst(compiler, LUI | RD(tmp_r) | (sljit_ins)(high << 12))); 92 | high = 0x1000; 93 | } else { 94 | if ((high & 0x800) != 0) 95 | high += 0x1000; 96 | 97 | FAIL_IF(push_inst(compiler, LUI | RD(tmp_r) | (sljit_ins)(high & ~0xfff))); 98 | high &= 0xfff; 99 | } 100 | 101 | if (imm <= SIMM_MAX && imm >= SIMM_MIN) { 102 | FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm))); 103 | imm = 0; 104 | } else if (imm > S32_MAX) { 105 | SLJIT_ASSERT((imm & 0x800) != 0); 106 | 107 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u)); 108 | imm = 0x1000 | (imm & 0xfff); 109 | } else { 110 | if ((imm & 0x800) != 0) 111 | imm += 0x1000; 112 | 113 | FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff))); 114 | imm &= 0xfff; 115 | } 116 | 117 | if ((high & 0xfff) != 0) 118 | FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high))); 119 | 120 | if (imm & 0x1000) 121 | FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm))); 122 | else if (imm != 0) 123 | FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm))); 124 | 125 | FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32))); 126 | return push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r)); 127 | } 128 | 129 | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, 130 | sljit_s32 freg, sljit_f64 value) 131 | { 132 | union { 133 | sljit_sw imm; 134 | sljit_f64 value; 135 | } u; 136 | 137 | CHECK_ERROR(); 138 | CHECK(check_sljit_emit_fset64(compiler, freg, value)); 139 | 140 | u.value = value; 141 | 142 | if (u.imm == 0) 143 | return push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_ZERO) | FRD(freg)); 144 | 145 | FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3)); 146 | return push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_REG1) | FRD(freg)); 147 | } 148 | 149 | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, 150 | sljit_s32 freg, sljit_s32 reg) 151 | { 152 | sljit_ins inst; 153 | 154 | CHECK_ERROR(); 155 | CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); 156 | 157 | if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) 158 | inst = FMV_W_X | RS1(reg) | FRD(freg); 159 | else 160 | inst = FMV_X_W | FRS1(freg) | RD(reg); 161 | 162 | if (!(op & SLJIT_32)) 163 | inst |= (sljit_ins)1 << 25; 164 | 165 | return push_inst(compiler, inst); 166 | } 167 | 168 | static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) 169 | { 170 | sljit_sw high; 171 | 172 | if ((init_value & 0x800) != 0) 173 | init_value += 0x1000; 174 | 175 | high = init_value >> 32; 176 | 177 | if ((init_value & 0x80000000l) != 0) 178 | high = ~high; 179 | 180 | if ((high & 0x800) != 0) 181 | high += 0x1000; 182 | 183 | FAIL_IF(push_inst(compiler, LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff))); 184 | FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high))); 185 | FAIL_IF(push_inst(compiler, LUI | RD(dst) | (sljit_ins)(init_value & ~0xfff))); 186 | FAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(32))); 187 | FAIL_IF(push_inst(compiler, XOR | RD(dst) | RS1(dst) | RS2(TMP_REG3))); 188 | return push_inst(compiler, last_ins | RS1(dst) | IMM_I(init_value)); 189 | } 190 | 191 | SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) 192 | { 193 | sljit_ins *inst = (sljit_ins*)addr; 194 | sljit_sw high; 195 | SLJIT_UNUSED_ARG(executable_offset); 196 | 197 | if ((new_target & 0x800) != 0) 198 | new_target += 0x1000; 199 | 200 | high = (sljit_sw)new_target >> 32; 201 | 202 | if ((new_target & 0x80000000l) != 0) 203 | high = ~high; 204 | 205 | if ((high & 0x800) != 0) 206 | high += 0x1000; 207 | 208 | SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0); 209 | 210 | SLJIT_ASSERT((inst[0] & 0x7f) == LUI); 211 | inst[0] = (inst[0] & 0xfff) | (sljit_ins)(high & ~0xfff); 212 | SLJIT_ASSERT((inst[1] & 0x707f) == ADDI); 213 | inst[1] = (inst[1] & 0xfffff) | IMM_I(high); 214 | SLJIT_ASSERT((inst[2] & 0x7f) == LUI); 215 | inst[2] = (inst[2] & 0xfff) | (sljit_ins)((sljit_sw)new_target & ~0xfff); 216 | SLJIT_ASSERT((inst[5] & 0x707f) == ADDI || (inst[5] & 0x707f) == JALR); 217 | inst[5] = (inst[5] & 0xfffff) | IMM_I(new_target); 218 | SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1); 219 | 220 | inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); 221 | SLJIT_CACHE_FLUSH(inst, inst + 5); 222 | } 223 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 79 2 | use_small_heuristics = "max" 3 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use { 2 | libc::c_int, 3 | pcre2_sys::{ 4 | pcre2_get_error_message_8, PCRE2_ERROR_BADDATA, PCRE2_ERROR_NOMEMORY, 5 | }, 6 | }; 7 | 8 | /// A PCRE2 error. 9 | /// 10 | /// An error can occur during compilation or during matching. The kind of this 11 | /// error indicates the type of operation being performed when the error 12 | /// occurred. 13 | #[derive(Clone)] 14 | pub struct Error { 15 | kind: ErrorKind, 16 | code: c_int, 17 | offset: Option, 18 | } 19 | 20 | /// The kind of an error indicates the type of operation that was attempted 21 | /// that resulted in an error. 22 | /// 23 | /// This enum may expand over time. 24 | #[derive(Clone, Debug)] 25 | #[non_exhaustive] 26 | pub enum ErrorKind { 27 | /// An error occurred during compilation of a regex. 28 | Compile, 29 | /// An error occurred during JIT compilation of a regex. 30 | JIT, 31 | /// An error occurred while matching. 32 | Match, 33 | /// An error occurred while querying a compiled regex for info. 34 | Info, 35 | /// An error occurred while setting an option. 36 | Option, 37 | } 38 | 39 | impl Error { 40 | /// Create a new compilation error. 41 | pub(crate) fn compile(code: c_int, offset: usize) -> Error { 42 | Error { kind: ErrorKind::Compile, code, offset: Some(offset) } 43 | } 44 | 45 | /// Create a new JIT compilation error. 46 | pub(crate) fn jit(code: c_int) -> Error { 47 | Error { kind: ErrorKind::JIT, code, offset: None } 48 | } 49 | 50 | /// Create a new matching error. 51 | pub(crate) fn matching(code: c_int) -> Error { 52 | Error { kind: ErrorKind::Match, code, offset: None } 53 | } 54 | 55 | /// Create a new info error. 56 | pub(crate) fn info(code: c_int) -> Error { 57 | Error { kind: ErrorKind::Info, code, offset: None } 58 | } 59 | 60 | /// Create a new option error. 61 | pub(crate) fn option(code: c_int) -> Error { 62 | Error { kind: ErrorKind::Option, code, offset: None } 63 | } 64 | 65 | /// Return the kind of this error. 66 | /// 67 | /// The kind indicates the type of operation that was attempted which 68 | /// resulted in this error. 69 | pub fn kind(&self) -> &ErrorKind { 70 | &self.kind 71 | } 72 | 73 | /// Return the raw underlying PCRE2 error code. 74 | /// 75 | /// This can be useful if one needs to determine exactly which error 76 | /// occurred, which can be done with case analysis over the constants 77 | /// exported in the `pcre2-sys` crate. 78 | pub fn code(&self) -> c_int { 79 | self.code 80 | } 81 | 82 | /// Return the underlying offset associated with this error, if one exists. 83 | /// 84 | /// The offset is typically only available for compile time errors, and 85 | /// is supposed to indicate the general position in the pattern where an 86 | /// error occurred. 87 | pub fn offset(&self) -> Option { 88 | self.offset 89 | } 90 | 91 | /// Returns the error message from PCRE2. 92 | fn error_message(&self) -> String { 93 | // PCRE2 docs say a buffer size of 120 bytes is enough, but we're 94 | // cautious and double it. 95 | let mut buf = [0u8; 240]; 96 | let rc = unsafe { 97 | pcre2_get_error_message_8(self.code, buf.as_mut_ptr(), buf.len()) 98 | }; 99 | // Errors are only ever constructed from codes reported by PCRE2, so 100 | // our code should always be valid. 101 | assert!(rc != PCRE2_ERROR_BADDATA, "used an invalid error code"); 102 | // PCRE2 docs claim 120 bytes is enough, and we use more, so... 103 | assert!(rc != PCRE2_ERROR_NOMEMORY, "buffer size too small"); 104 | // Sanity check that we do indeed have a non-negative result. 0 is OK. 105 | assert!(rc >= 0, "expected non-negative but got {}", rc); 106 | String::from_utf8(buf[..rc as usize].to_vec()).expect("valid UTF-8") 107 | } 108 | } 109 | 110 | impl std::error::Error for Error { 111 | fn description(&self) -> &str { 112 | "pcre2 error" 113 | } 114 | } 115 | 116 | impl std::fmt::Display for Error { 117 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 118 | let msg = self.error_message(); 119 | match self.kind { 120 | ErrorKind::Compile => match self.offset { 121 | None => { 122 | write!(f, "PCRE2: error compiling pattern: {}", msg) 123 | } 124 | Some(offset) => { 125 | write!( 126 | f, 127 | "PCRE2: error compiling pattern at offset {}: {}", 128 | offset, msg 129 | ) 130 | } 131 | }, 132 | ErrorKind::JIT => { 133 | write!(f, "PCRE2: error JIT compiling pattern: {}", msg) 134 | } 135 | ErrorKind::Match => { 136 | write!(f, "PCRE2: error matching: {}", msg) 137 | } 138 | ErrorKind::Info => { 139 | write!(f, "PCRE2: error getting info: {}", msg) 140 | } 141 | ErrorKind::Option => { 142 | write!(f, "PCRE2: error setting option: {}", msg) 143 | } 144 | } 145 | } 146 | } 147 | 148 | impl std::fmt::Debug for Error { 149 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 150 | // We include the error message in the debug representation since 151 | // most humans probably don't have PCRE2 error codes memorized. 152 | f.debug_struct("Error") 153 | .field("kind", &self.kind) 154 | .field("code", &self.code) 155 | .field("offset", &self.offset) 156 | .field("message", &self.error_message()) 157 | .finish() 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | /*! 2 | This crate provides a safe high level Rust binding to 3 | [PCRE2](https://www.pcre.org/). 4 | 5 | The API of this crate attempts to correspond closely to the API of Rust's 6 | [`regex`](https://docs.rs/regex) 7 | crate. The API provided by this crate neither matches the full API of Rust's 8 | regex crate nor does it expose the full functionality of PCRE2. Contributions 9 | are welcome to improve this. 10 | */ 11 | 12 | #![deny(missing_docs)] 13 | 14 | extern crate alloc; 15 | 16 | pub use crate::{ 17 | error::{Error, ErrorKind}, 18 | ffi::{escape, is_jit_available, version}, 19 | }; 20 | 21 | /** 22 | PCRE2 regular expressions for matching on arbitrary bytes. 23 | */ 24 | pub mod bytes; 25 | mod error; 26 | mod ffi; 27 | mod pool; 28 | --------------------------------------------------------------------------------