├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── premake ├── mm-linux.lua ├── mm-windows.lua ├── spdlog.lua └── utils.lua ├── premake5.lua ├── schema.json ├── src ├── actions │ ├── actions.cpp │ └── actions.h ├── extension.cpp ├── extension.h ├── hook.cpp ├── hook.h ├── network_connection.pb.h ├── providers │ ├── base_provider.cpp │ ├── base_provider.h │ ├── json │ │ └── json_actions.cpp │ ├── json_provider.cpp │ └── json_provider.h └── utils │ ├── module.h │ ├── plat.h │ ├── plat_unix.cpp │ └── plat_win.cpp └── vendor ├── funchook ├── LICENSE ├── README.md ├── include │ └── funchook.h └── lib │ ├── Debug │ ├── distorm.lib │ ├── distorm.pdb │ ├── funchook.lib │ ├── funchook.pdb │ ├── libdistorm.a │ └── libfunchook.a │ └── Release │ ├── distorm.lib │ ├── funchook.lib │ ├── libdistorm.a │ └── libfunchook.a ├── nlohmann ├── json.hpp └── json_fwd.hpp └── pcre ├── config.h ├── pcre2.h ├── 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_dftables.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_printint.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 ├── pcre2grep.c ├── pcre2posix.c ├── pcre2posix.h ├── pcre2posix_test.c ├── pcre2test.c ├── premake5.lua └── 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 /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /build/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/spdlog"] 2 | path = vendor/spdlog 3 | url = https://github.com/gabime/spdlog 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # StripperCS2 3 | 4 | A Metamod plugin that allows server operators to manage map lump data similarly to how [Stripper:Source](https://www.bailopan.net/stripper/) worked. 5 | 6 | ## Folder structure 7 | Unlike Source, Source2 allows maps to include multiple lumps in the maps and reference each other. For example all entity templates will be turned into a new lump file. Stripper has to then also follow this. 8 | 9 | The folder structure consists of 3 main parts, the map, the world name and the lump name. To avoid conflicts I have intentionally scoped all of the configs to maps, the world name and lump name come as a requirement from the engine. 10 | 11 | The template of a stripper config file looks like `addons/StripperCS2/maps///.jsonc` 12 | 13 | You can view all of the lumps a map has by using the `entity_lump_list` command 14 | 15 | > [!CAUTION] 16 | > `entity_lump_list` is a defensive command, it has to be either unlocked by a metamod plugin like CS2Fixes or defensive commands have to be disabled in the csgo_core/gameinfo.gi configuration 17 | 18 | ![image](https://github.com/Source2ZE/StripperCS2/assets/45881722/2ccacaf2-8a78-4ccb-99e5-14781465fd2e) 19 | 20 | You can also see all the lumps in the map vpks under the `maps//entities` folder and read the raw keyvalues through [Source2Viewer](https://valveresourceformat.github.io/) 21 | 22 | From the image above, if you wanted to edit entities inside the de_vertigo default_ents lump, you would have to create a `default_ents.jsonc` file under the `addons/StripperCS2/maps/de_vertigo` path. If you would want to edit the `default_ents` from `prefabs\misc\end_of_match` you would have to put the file inside `addons/StripperCS2/maps/de_vertigo/prefabs/misc/end_of_match` 23 | 24 | ## Configuration 25 | 26 | StripperCS2 uses the JSON format instead of a custom config parser like Stripper:Source. Actions such as `filter`, `add`, `modify` are root arrays or objects. To facilitate organizing large configs, duplicate action keys are permitted. 27 | 28 | You can use per map configs as explained in [Folder structure](#folder-structure) or you can use the global config in `addons/StripperCS2/global.jsonc` which will apply all the rules to every loaded lump. 29 | 30 | ### Filter 31 | ```json 32 | { 33 | "filter": [ 34 | { 35 | "classname": "/.*/" 36 | } 37 | ] 38 | } 39 | ``` 40 | 41 | Similarly to Stripper:Source, each keyvalue is a string representation of its value, for example a color vector would be written as "255 0 0". Each key in the object is a keyvalue. 42 | Every value can be either a string or a Perl regexp using the `/regex/` syntax. 43 | 44 | #### Outputs 45 | 46 | In StripperCS2 outputs are natively supported. An output is represented as an object under the reserved "io" field. 47 | 48 | ```json 49 | { 50 | "filter": [ 51 | { 52 | "io": [ 53 | { 54 | "outputname": "OnMapStart" 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | ``` 61 | 62 | This would filter all entities that have an OnMapStart output, the available keys are: `outputname`, `inputname`, `targetname`, `overrideparam`, `delay` (float), `timestofire` (int), `targettype` (int/EntityIOTargetType_t). 63 | The enum for targettype can be acquired from the hl2sdk. 64 | ```c 65 | enum EntityIOTargetType_t 66 | { 67 | ENTITY_IO_TARGET_INVALID = -1, 68 | ENTITY_IO_TARGET_CLASSNAME = 0, 69 | ENTITY_IO_TARGET_CLASSNAME_DERIVES_FROM = 1, 70 | ENTITY_IO_TARGET_ENTITYNAME = 2, 71 | ENTITY_IO_TARGET_CONTAINS_COMPONENT = 3, 72 | ENTITY_IO_TARGET_SPECIAL_ACTIVATOR = 4, 73 | ENTITY_IO_TARGET_SPECIAL_CALLER = 5, 74 | ENTITY_IO_TARGET_EHANDLE = 6, 75 | ENTITY_IO_TARGET_ENTITYNAME_OR_CLASSNAME = 7, 76 | } 77 | ``` 78 | 79 | ### Add 80 | 81 | ```jsonc 82 | { 83 | "add": [ 84 | { 85 | "classname": "func_button", 86 | // ... other keyvalues 87 | "io": [ 88 | { 89 | "outputname": "OnPressed", 90 | "targetname": "lockable_door", 91 | "inputname": "Lock" 92 | }, 93 | // ... more io 94 | ] 95 | } 96 | ] 97 | } 98 | ``` 99 | 100 | Adding new entities matches the exact system as `filter`, except instead of using the keyvalues for matching it adds them as a new entity, `io` array turns into a list of all the outputs that will be added. Regex values will be ignored. 101 | 102 | ### Modify 103 | 104 | Modify is a more complex action that allows you to edit an already existing entity. 105 | It has 4 sub objects matching Stripper:Source's behavior. 106 | 107 | - `match`: All values in this objects will be used as a requirement for an entity to match, regular expressions are allowed for every value. `io` array can be used the same way as in `filter` action 108 | - `replace`: Entity that passes the match requirements can have any of its keyvalues replaced with this sub object. Any keyvalue entered in here will be replaced with the right hand value. `io` **object** can also be used here, see [Replace Outputs](#replace-outputs) section 109 | - `delete`: Deletes all they keyvalues that match their value with the right hand value in the json, this means you can match a single classname and then decide here whether a keyvalue will always be removed or only if it matches a value 110 | - `insert`: Adds new keyvalues to the entity, works exactly the same as `add` action. 111 | 112 | #### Replace Outputs 113 | 114 | ```jsonc 115 | { 116 | "modify": [ 117 | { 118 | "match": 119 | { 120 | // in this example this classname will match an entity with 3 outputs, OnFullyClosed, OnOpen and OnFullyOpen 121 | "classname": "func_door_rotating", 122 | // this array is not exhaustive, it will match any entity with at least these outputs 123 | // all these matched outputs will be then replaced with the replace object below 124 | "io": [ 125 | { 126 | "outputname": "OnFullyClosed" 127 | }, 128 | { 129 | "outputname": "OnOpen" 130 | } 131 | ] 132 | }, 133 | "replace": 134 | { 135 | "io": 136 | // NOT ARRAY, ALL MATCHED IOs WILL BE REPLACED WITH THIS SINGLE OBJECT 137 | { 138 | // replaces only OnFullyClosed and OnOpen because they are in the match array, OnFullyOpen will be left alone 139 | "outputname": "CustomOutputName" 140 | } 141 | } 142 | } 143 | ] 144 | } 145 | ``` 146 | 147 | Unlike Stripper:Source you don't need to delete and insert an output to modify it. You can use the `io` **OBJECT not array** to replace any value of the output. Note that this object is tightly connected with the match sub object. `replace` will only replace outputs that are explicitly matched inside the `io` array in the `match` sub object 148 | 149 | 150 | ### Config example 151 | 152 | ```jsonc 153 | { 154 | "filter": [ 155 | { 156 | // no terrorists >:( 157 | "classname": "info_player_terrorist" 158 | } 159 | ], 160 | 161 | "modify": [ 162 | { 163 | "match": 164 | { 165 | "classname": "func_door_rotating", 166 | "io": [ 167 | { 168 | "outputname": "OnFullyClosed" 169 | } 170 | ] 171 | }, 172 | "replace": 173 | { 174 | "targetname": "yippe", 175 | "io": 176 | { 177 | "outputname": "OnClose" 178 | } 179 | }, 180 | "insert": 181 | { 182 | "renderamt": "100", 183 | "io": [ 184 | { 185 | "outputname": "OnFullyOpened", 186 | "inputname": "Lock", 187 | "targetname": "lockable_door" 188 | } 189 | ] 190 | }, 191 | "delete": 192 | { 193 | "model": "models/bruh.mdl", 194 | } 195 | } 196 | ], 197 | 198 | "add": [ 199 | { 200 | "classname": "func_button", 201 | "origin": "100 10 500" 202 | // ... 203 | } 204 | ], 205 | 206 | // Optional single object style, instead of using array 207 | "add": { 208 | "classname": "trigger_multiple", 209 | "origin": "500 80 1000" 210 | // ... 211 | } 212 | } 213 | ``` 214 | -------------------------------------------------------------------------------- /premake/mm-linux.lua: -------------------------------------------------------------------------------- 1 | files { 2 | path.join(SDK_PATH, "public", "tier0", "memoverride.cpp"), 3 | path.join(SDK_PATH, "tier1", "convar.cpp"), 4 | path.join(SDK_PATH, "tier1", "generichash.cpp"), 5 | path.join(SDK_PATH, "entity2", "entitysystem.cpp"), 6 | path.join(SDK_PATH, "entity2", "entityidentity.cpp"), 7 | path.join(SDK_PATH, "entity2", "entitykeyvalues.cpp"), 8 | path.join(SDK_PATH, "tier1", "keyvalues3.cpp"), 9 | path.join(MM_PATH, "core", "sourcehook", "sourcehook.cpp"), 10 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_chookidman.cpp"), 11 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_chookmaninfo.cpp"), 12 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_cvfnptr.cpp"), 13 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_cproto.cpp"), 14 | } 15 | 16 | libdirs { 17 | path.join(SDK_PATH, "lib", "linux64"), 18 | } 19 | 20 | linkoptions { 21 | "-l:libtier0.so", 22 | "-l:tier1.a", 23 | "-l:interfaces.a", 24 | "-l:mathlib.a", 25 | } 26 | 27 | includedirs { 28 | _MAIN_SCRIPT_DIR, 29 | -- sdk 30 | path.join(SDK_PATH, "thirdparty", "protobuf-3.21.8", "src"), 31 | path.join(SDK_PATH, "common"), 32 | path.join(SDK_PATH, "game", "shared"), 33 | path.join(SDK_PATH, "game", "server"), 34 | path.join(SDK_PATH, "public"), 35 | path.join(SDK_PATH, "public", "engine"), 36 | path.join(SDK_PATH, "public", "mathlib"), 37 | path.join(SDK_PATH, "public", "tier0"), 38 | path.join(SDK_PATH, "public", "tier1"), 39 | path.join(SDK_PATH, "public", "entity2"), 40 | path.join(SDK_PATH, "public", "game", "server"), 41 | path.join(SDK_PATH, "public", "public", "entity2"), 42 | -- metamod 43 | path.join(MM_PATH, "core"), 44 | path.join(MM_PATH, "core", "sourcehook"), 45 | } 46 | 47 | defines { 48 | "_LINUX", 49 | "LINUX", 50 | "POSIX", 51 | "GNUC", 52 | "COMPILER_GCC", 53 | "PLATFORM_64BITS", 54 | "_GLIBCXX_USE_CXX11_ABI=0" 55 | } 56 | 57 | characterset "MBCS" -------------------------------------------------------------------------------- /premake/mm-windows.lua: -------------------------------------------------------------------------------- 1 | files { 2 | path.join(SDK_PATH, "public", "tier0", "memoverride.cpp"), 3 | path.join(SDK_PATH, "tier1", "convar.cpp"), 4 | path.join(SDK_PATH, "tier1", "generichash.cpp"), 5 | path.join(SDK_PATH, "entity2", "entitysystem.cpp"), 6 | path.join(SDK_PATH, "entity2", "entityidentity.cpp"), 7 | path.join(SDK_PATH, "entity2", "entitykeyvalues.cpp"), 8 | path.join(SDK_PATH, "tier1", "keyvalues3.cpp"), 9 | path.join(MM_PATH, "core", "sourcehook", "sourcehook.cpp"), 10 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_chookidman.cpp"), 11 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_chookmaninfo.cpp"), 12 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_cvfnptr.cpp"), 13 | path.join(MM_PATH, "core", "sourcehook", "sourcehook_impl_cproto.cpp"), 14 | } 15 | 16 | links { 17 | path.join(SDK_PATH, "lib", "public", "win64", "tier0.lib"), 18 | path.join(SDK_PATH, "lib", "public", "win64", "tier1.lib"), 19 | path.join(SDK_PATH, "lib", "public", "win64", "interfaces.lib"), 20 | path.join(SDK_PATH, "lib", "public", "win64", "mathlib.lib") 21 | } 22 | 23 | includedirs { 24 | _MAIN_SCRIPT_DIR, 25 | -- sdk 26 | SDK_PATH, 27 | path.join(SDK_PATH, "thirdparty", "protobuf-3.21.8", "src"), 28 | path.join(SDK_PATH, "common"), 29 | path.join(SDK_PATH, "game", "shared"), 30 | path.join(SDK_PATH, "game", "server"), 31 | path.join(SDK_PATH, "public"), 32 | path.join(SDK_PATH, "public", "engine"), 33 | path.join(SDK_PATH, "public", "mathlib"), 34 | path.join(SDK_PATH, "public", "tier0"), 35 | path.join(SDK_PATH, "public", "tier1"), 36 | path.join(SDK_PATH, "public", "entity2"), 37 | path.join(SDK_PATH, "public", "game", "server"), 38 | path.join(SDK_PATH, "public", "public", "entity2"), 39 | -- metamod 40 | path.join(MM_PATH, "core"), 41 | path.join(MM_PATH, "core", "sourcehook"), 42 | } 43 | 44 | defines { 45 | "COMPILER_MSVC", 46 | "COMPILER_MSVC64", 47 | "PLATFORM_64BITS", 48 | "X64BITS", 49 | "WIN32", 50 | "WINDOWS", 51 | "CRT_SECURE_NO_WARNINGS", 52 | "CRT_SECURE_NO_DEPRECATE", 53 | "CRT_NONSTDC_NO_DEPRECATE" 54 | } 55 | 56 | characterset "MBCS" -------------------------------------------------------------------------------- /premake/spdlog.lua: -------------------------------------------------------------------------------- 1 | project "spdlog" 2 | kind "StaticLib" 3 | language "C++" 4 | 5 | includedirs { 6 | path.join(_MAIN_SCRIPT_DIR, "vendor", "spdlog", "include") 7 | } 8 | 9 | defines { 10 | "SPDLOG_COMPILED_LIB", 11 | } 12 | 13 | files { 14 | path.join(_MAIN_SCRIPT_DIR, "vendor", "spdlog", "src", "**.cpp") 15 | } 16 | 17 | pic "On" -------------------------------------------------------------------------------- /premake/utils.lua: -------------------------------------------------------------------------------- 1 | function GetOS() 2 | return package.config:sub(1,1) == "\\" and "win" or "unix" 3 | end -------------------------------------------------------------------------------- /premake5.lua: -------------------------------------------------------------------------------- 1 | include("premake/utils") 2 | 3 | SDK_PATH = os.getenv("HL2SDKCS2") 4 | MM_PATH = os.getenv("MMSOURCE112") 5 | 6 | if(SDK_PATH == nil) then 7 | error("INVALID HL2SDK PATH") 8 | end 9 | 10 | if(MM_PATH == nil) then 11 | error("INVALID METAMOD PATH") 12 | end 13 | 14 | workspace "StripperCS2" 15 | configurations { "Debug", "Release" } 16 | platforms { 17 | "win64", 18 | "linux64" 19 | } 20 | location "build" 21 | 22 | project "StripperCS2" 23 | kind "SharedLib" 24 | language "C++" 25 | targetdir "bin/%{cfg.buildcfg}" 26 | location "build/StripperCS2" 27 | visibility "Hidden" 28 | targetprefix "" 29 | 30 | files { "src/**.h", "src/**.cpp" } 31 | 32 | vpaths { 33 | ["Headers/*"] = "src/**.h", 34 | ["Sources/*"] = "src/**.cpp" 35 | } 36 | 37 | filter "configurations:Debug" 38 | defines { "DEBUG" } 39 | symbols "On" 40 | libdirs { 41 | path.join("vendor", "funchook", "lib", "Debug"), 42 | } 43 | 44 | filter "configurations:Release" 45 | defines { "NDEBUG" } 46 | optimize "On" 47 | libdirs { 48 | path.join("vendor", "funchook", "lib", "Release"), 49 | } 50 | 51 | filter "system:windows" 52 | cppdialect "c++20" 53 | include("premake/mm-windows.lua") 54 | links { "psapi" } 55 | staticruntime "On" 56 | 57 | filter "system:linux" 58 | cppdialect "c++2a" 59 | include("premake/mm-linux.lua") 60 | links { "pthread", "z"} 61 | linkoptions { '-static-libstdc++', '-static-libgcc' } 62 | disablewarnings { "register" } 63 | 64 | filter {} 65 | 66 | defines { "META_IS_SOURCE2", "PCRE2_CODE_UNIT_WIDTH=8", "PCRE2_STATIC" } 67 | 68 | flags { "MultiProcessorCompile" } 69 | pic "On" 70 | 71 | links { 72 | "funchook", 73 | "distorm", 74 | "pcre", 75 | "spdlog" 76 | } 77 | 78 | includedirs { 79 | path.join("vendor", "nlohmann"), 80 | path.join("vendor", "funchook", "include"), 81 | path.join("vendor", "spdlog", "include"), 82 | path.join("vendor"), 83 | path.join("src"), 84 | } 85 | 86 | include "vendor/pcre" 87 | include "premake/spdlog" -------------------------------------------------------------------------------- /schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "title": "StripperCS2 schema", 4 | "type": "object", 5 | "properties": { 6 | "$schema": { 7 | "type": "string", 8 | "format": "uri" 9 | }, 10 | "filter": { 11 | "anyOf": [ 12 | { 13 | "type": "array", 14 | "items": { 15 | "$ref": "#/definitions/filterData" 16 | } 17 | }, 18 | { 19 | "type": "object", 20 | "$ref": "#/definitions/filterData" 21 | } 22 | ] 23 | }, 24 | "add": { 25 | "anyOf": [ 26 | { 27 | "type": "array", 28 | "items": { 29 | "$ref": "#/definitions/addData" 30 | } 31 | }, 32 | { 33 | "type": "object", 34 | "$ref": "#/definitions/addData" 35 | } 36 | ] 37 | }, 38 | "modify": { 39 | "anyOf": [ 40 | { 41 | "type": "array", 42 | "items": { 43 | "$ref": "#/definitions/modifyData" 44 | } 45 | }, 46 | { 47 | "type": "object", 48 | "$ref": "#/definitions/modifyData" 49 | } 50 | ] 51 | } 52 | }, 53 | "additionalProperties": false, 54 | 55 | "definitions": { 56 | "ioConnection": { 57 | "type": "object", 58 | "properties": { 59 | "outputname": { 60 | "type": "string" 61 | }, 62 | "targetname": { 63 | "type": "string" 64 | }, 65 | "inputname": { 66 | "type": "string" 67 | }, 68 | "overrideparam": { 69 | "type": "string" 70 | }, 71 | "delay": { 72 | "type": "number" 73 | }, 74 | "timestofire": { 75 | "type": "number" 76 | }, 77 | "targettype": { 78 | "type": "number" 79 | } 80 | }, 81 | "additionalProperties": false 82 | }, 83 | "filterData": { 84 | "type": "object", 85 | "properties": { 86 | "io": { 87 | "type": "array", 88 | "items": { 89 | "$ref": "#/definitions/ioConnection" 90 | } 91 | } 92 | } 93 | }, 94 | "addData": { 95 | "type": "object", 96 | "properties": { 97 | "io": { 98 | "type": "array", 99 | "items": { 100 | "$ref": "#/definitions/ioConnection" 101 | } 102 | } 103 | } 104 | }, 105 | "modifyData": { 106 | "type": "object", 107 | "additionalProperties": false, 108 | "properties": { 109 | "match": { 110 | "type": "object", 111 | "properties": { 112 | "io": { 113 | "type": "array", 114 | "items": { 115 | "$ref": "#/definitions/ioConnection" 116 | } 117 | } 118 | } 119 | }, 120 | "replace": { 121 | "type": "object", 122 | "properties": { 123 | "io": { 124 | "type": "object", 125 | "$ref": "#/definitions/ioConnection" 126 | } 127 | } 128 | }, 129 | "delete": { 130 | "type": "object", 131 | "properties": { 132 | "io": { 133 | "type": "array", 134 | "items": { 135 | "$ref": "#/definitions/ioConnection" 136 | } 137 | } 138 | } 139 | }, 140 | "insert": { 141 | "type": "object", 142 | "properties": { 143 | "io": { 144 | "type": "array", 145 | "items": { 146 | "$ref": "#/definitions/ioConnection" 147 | } 148 | } 149 | } 150 | } 151 | } 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /src/actions/actions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #pragma once 21 | #include 22 | #include 23 | #include "entitykeyvalues.h" 24 | #include "pcre/pcre2.h" 25 | #include 26 | #include 27 | #include 28 | 29 | struct IOConnection; 30 | 31 | typedef std::variant ActionVariant_t; 32 | typedef std::variant IOConnectionVariant_t; 33 | 34 | enum ActionType_t 35 | { 36 | Filter, 37 | Modify, 38 | Add 39 | }; 40 | 41 | struct IOConnection 42 | { 43 | IOConnection() = default; 44 | ~IOConnection() 45 | { 46 | if (auto pRegex = std::get_if(&m_pszOutputName)) 47 | pcre2_code_free(*pRegex); 48 | 49 | if (auto pRegex = std::get_if(&m_pszTargetName)) 50 | pcre2_code_free(*pRegex); 51 | 52 | if (auto pRegex = std::get_if(&m_pszInputName)) 53 | pcre2_code_free(*pRegex); 54 | 55 | if (auto pRegex = std::get_if(&m_pszOverrideParam)) 56 | pcre2_code_free(*pRegex); 57 | } 58 | 59 | IOConnection(IOConnection&& other) noexcept : m_pszOutputName(std::move(other.m_pszOutputName)), m_eTargetType(std::move(other.m_eTargetType)), 60 | m_pszTargetName(std::move(other.m_pszTargetName)), m_pszInputName(std::move(other.m_pszInputName)), 61 | m_pszOverrideParam(std::move(other.m_pszOverrideParam)), m_flDelay(std::move(other.m_flDelay)), m_nTimesToFire(std::move(other.m_nTimesToFire)) 62 | { 63 | other.m_pszOutputName = std::monostate{}; 64 | other.m_pszTargetName = std::monostate{}; 65 | other.m_pszInputName = std::monostate{}; 66 | other.m_pszOverrideParam = std::monostate{}; 67 | } 68 | 69 | IOConnection& operator=(IOConnection&& other) noexcept 70 | { 71 | if (this != &other) 72 | { 73 | m_pszOutputName = std::move(other.m_pszOutputName); 74 | m_eTargetType = std::move(other.m_eTargetType); 75 | m_flDelay = std::move(other.m_flDelay); 76 | m_nTimesToFire = std::move(other.m_nTimesToFire); 77 | m_pszTargetName = std::move(other.m_pszOutputName); 78 | m_pszInputName = std::move(other.m_pszOutputName); 79 | m_pszOverrideParam = std::move(other.m_pszOutputName); 80 | other.m_pszOutputName = std::monostate{}; 81 | other.m_pszTargetName = std::monostate{}; 82 | other.m_pszInputName = std::monostate{}; 83 | other.m_pszOverrideParam = std::monostate{}; 84 | } 85 | return *this; 86 | } 87 | 88 | // fuck copying 89 | IOConnection(const IOConnection&) = delete; 90 | IOConnection& operator=(const IOConnection&) = delete; 91 | 92 | IOConnectionVariant_t m_pszOutputName; 93 | std::optional m_eTargetType; 94 | IOConnectionVariant_t m_pszTargetName; 95 | IOConnectionVariant_t m_pszInputName; 96 | IOConnectionVariant_t m_pszOverrideParam; 97 | std::optional m_flDelay; 98 | std::optional m_nTimesToFire; 99 | }; 100 | 101 | 102 | struct ActionEntry 103 | { 104 | ActionEntry() = default; 105 | ~ActionEntry() 106 | { 107 | if (auto pRegex = std::get_if(&m_Value)) 108 | pcre2_code_free(*pRegex); 109 | } 110 | 111 | ActionEntry(ActionEntry&& other) noexcept : m_strName(std::move(other.m_strName)), m_Value(std::move(other.m_Value)) 112 | { 113 | other.m_Value = std::monostate{}; 114 | } 115 | 116 | ActionEntry& operator=(ActionEntry&& other) noexcept 117 | { 118 | if (this != &other) 119 | { 120 | m_strName = std::move(other.m_strName); 121 | m_Value = std::move(other.m_Value); 122 | other.m_Value = std::monostate{}; 123 | } 124 | return *this; 125 | } 126 | 127 | // fuck copying 128 | ActionEntry(const ActionEntry&) = delete; 129 | ActionEntry& operator=(const ActionEntry&) = delete; 130 | 131 | std::string m_strName; 132 | ActionVariant_t m_Value; 133 | }; 134 | 135 | class BaseAction 136 | { 137 | public: 138 | virtual ~BaseAction() = default; 139 | virtual ActionType_t GetType() const = 0; 140 | }; 141 | 142 | class FilterAction : public BaseAction 143 | { 144 | public: 145 | FilterAction() = default; 146 | ActionType_t GetType() const override { return ActionType_t::Filter; } 147 | public: 148 | std::vector m_vecMatches; 149 | }; 150 | 151 | class ModifyAction : public BaseAction 152 | { 153 | public: 154 | ModifyAction() = default; 155 | ActionType_t GetType() const override { return ActionType_t::Modify; } 156 | public: 157 | std::vector m_vecMatches; 158 | std::vector m_vecReplacements; 159 | std::vector m_vecDeletions; 160 | std::vector m_vecInsertions; 161 | }; 162 | 163 | class AddAction : public BaseAction 164 | { 165 | public: 166 | AddAction() = default; 167 | ActionType_t GetType() const override { return ActionType_t::Add; } 168 | public: 169 | std::vector m_vecInsertions; 170 | }; 171 | 172 | template 173 | T VariantOrDefault(V variant, T defaultValue) 174 | { 175 | if (auto val = std::get_if(&variant)) 176 | return *val; 177 | 178 | return defaultValue; 179 | } 180 | 181 | struct LumpData 182 | { 183 | CUtlString m_name; 184 | char pad[0x18]; 185 | CKeyValues3Context* m_allocatorContext; 186 | }; 187 | 188 | void ApplyMapOverride(std::vector>& actions, CUtlVector* vecEntityKeyValues, LumpData* lumpData); 189 | -------------------------------------------------------------------------------- /src/extension.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #include 21 | #include "extension.h" 22 | #include "iserver.h" 23 | #include 24 | #include "hook.h" 25 | #include 26 | #include "providers/json_provider.h" 27 | #include 28 | #include 29 | 30 | StripperCS2 g_StripperCS2; 31 | IServerGameDLL* server = NULL; 32 | IServerGameClients* gameclients = NULL; 33 | IVEngineServer* engine = NULL; 34 | IGameEventManager2* gameevents = NULL; 35 | ICvar* icvar = NULL; 36 | 37 | // Should only be called within the active game loop (i e map should be loaded and active) 38 | // otherwise that'll be nullptr! 39 | CGlobalVars* GetGameGlobals() 40 | { 41 | INetworkGameServer* server = g_pNetworkServerService->GetIGameServer(); 42 | 43 | if (!server) 44 | return nullptr; 45 | 46 | return g_pNetworkServerService->GetIGameServer()->GetGlobals(); 47 | } 48 | 49 | CGameEntitySystem* GameEntitySystem() 50 | { 51 | return nullptr; 52 | } 53 | 54 | std::map, std::vector>> g_mapOverrides; 55 | 56 | PLUGIN_EXPOSE(StripperCS2, g_StripperCS2); 57 | bool StripperCS2::Load(PluginId id, ISmmAPI* ismm, char* error, size_t maxlen, bool late) 58 | { 59 | spdlog::set_pattern("%^[%T] [StripperCS2] [%l] %v%$"); 60 | 61 | PLUGIN_SAVEVARS(); 62 | 63 | GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); 64 | GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION); 65 | GET_V_IFACE_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); 66 | GET_V_IFACE_ANY(GetServerFactory, gameclients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); 67 | GET_V_IFACE_ANY(GetEngineFactory, g_pNetworkServerService, INetworkServerService, NETWORKSERVERSERVICE_INTERFACE_VERSION); 68 | GET_V_IFACE_ANY(GetEngineFactory, g_pWorldRendererMgr, IWorldRendererMgr, WORLD_RENDERER_MGR_INTERFACE_VERSION); 69 | 70 | // Required to get the IMetamodListener events 71 | g_SMAPI->AddListener(this, this); 72 | 73 | if (!Hook::SetupHook()) 74 | { 75 | spdlog::critical("Failed to setup hook!"); 76 | return false; 77 | } 78 | 79 | g_pCVar = icvar; 80 | ConVar_Register(FCVAR_RELEASE | FCVAR_CLIENT_CAN_EXECUTE | FCVAR_GAMEDLL); 81 | 82 | spdlog::info("Stripper loaded"); 83 | 84 | return true; 85 | } 86 | 87 | bool StripperCS2::Unload(char* error, size_t maxlen) 88 | { 89 | Hook::Cleanup(); 90 | 91 | return true; 92 | } 93 | 94 | void StripperCS2::AllPluginsLoaded() 95 | { 96 | } 97 | 98 | void StripperCS2::OnLevelInit(char const* pMapName, 99 | char const* pMapEntities, 100 | char const* pOldLevel, 101 | char const* pLandmarkName, 102 | bool loadGame, 103 | bool background) 104 | { 105 | g_mapOverrides.clear(); 106 | 107 | std::filesystem::path path(Plat_GetGameDirectory()); 108 | auto globalFilePath = path / "csgo/addons/StripperCS2/global.jsonc"; 109 | 110 | if (std::filesystem::exists(globalFilePath)) 111 | { 112 | Providers::JsonProvider provider; 113 | 114 | try { 115 | g_mapOverrides[std::make_pair("GLOBALOVERRIDE", "")] = provider.Load(globalFilePath.string()); 116 | } 117 | catch (const std::exception& e) 118 | { 119 | spdlog::error("Provider failed to parse {}: {}", globalFilePath.string(), e.what()); 120 | } 121 | } 122 | 123 | path /= "csgo/addons/StripperCS2/maps"; 124 | path /= pMapName; 125 | 126 | if (!std::filesystem::exists(path)) 127 | { 128 | spdlog::warn("No map overrides found for {}", pMapName); 129 | return; 130 | } 131 | 132 | for (const auto& entry : std::filesystem::recursive_directory_iterator(path)) 133 | { 134 | if (entry.is_regular_file()) 135 | { 136 | std::filesystem::path filePath = entry.path(); 137 | 138 | std::filesystem::path cleanPath = filePath.lexically_relative(path); 139 | 140 | ConMsg("Loading: %s\n", cleanPath.string().c_str()); 141 | 142 | if (filePath.extension() == ".jsonc") 143 | { 144 | std::string worldName = cleanPath.has_parent_path() ? cleanPath.parent_path().string() : pMapName; 145 | std::string lumpName = cleanPath.stem().string(); 146 | 147 | ConMsg("%s %s\n", worldName.c_str(), lumpName.c_str()); 148 | ConMsg("%s\n", cleanPath.string().c_str()); 149 | 150 | Providers::JsonProvider provider; 151 | 152 | try { 153 | g_mapOverrides[std::make_pair(worldName, lumpName)] = provider.Load(filePath.string()); 154 | } 155 | catch (const std::exception& e) 156 | { 157 | spdlog::error("Provider failed to parse {}: {}", filePath.string(), e.what()); 158 | } 159 | } 160 | } 161 | } 162 | 163 | META_CONPRINTF("OnLevelInit(%s)\n", pMapName); 164 | } 165 | 166 | void StripperCS2::OnLevelShutdown() 167 | { 168 | META_CONPRINTF("OnLevelShutdown()\n"); 169 | } 170 | 171 | bool StripperCS2::Pause(char* error, size_t maxlen) 172 | { 173 | return true; 174 | } 175 | 176 | bool StripperCS2::Unpause(char* error, size_t maxlen) 177 | { 178 | return true; 179 | } 180 | 181 | const char* StripperCS2::GetLicense() 182 | { 183 | return "GPLv3"; 184 | } 185 | 186 | const char* StripperCS2::GetVersion() 187 | { 188 | return "1.0.5"; 189 | } 190 | 191 | const char* StripperCS2::GetDate() 192 | { 193 | return __DATE__; 194 | } 195 | 196 | const char* StripperCS2::GetLogTag() 197 | { 198 | return "STRIPPER"; 199 | } 200 | 201 | const char* StripperCS2::GetAuthor() 202 | { 203 | return "Poggu"; 204 | } 205 | 206 | const char* StripperCS2::GetDescription() 207 | { 208 | return "CS2 Map Lump Editor"; 209 | } 210 | 211 | const char* StripperCS2::GetName() 212 | { 213 | return "StripperCS2"; 214 | } 215 | 216 | const char* StripperCS2::GetURL() 217 | { 218 | return "https://poggu.me"; 219 | } -------------------------------------------------------------------------------- /src/extension.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 21 | #define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | class StripperCS2 : public ISmmPlugin, public IMetamodListener 28 | { 29 | public: 30 | bool Load(PluginId id, ISmmAPI* ismm, char* error, size_t maxlen, bool late); 31 | bool Unload(char* error, size_t maxlen); 32 | bool Pause(char* error, size_t maxlen); 33 | bool Unpause(char* error, size_t maxlen); 34 | void AllPluginsLoaded(); 35 | public: //hooks 36 | void OnLevelInit(char const* pMapName, 37 | char const* pMapEntities, 38 | char const* pOldLevel, 39 | char const* pLandmarkName, 40 | bool loadGame, 41 | bool background); 42 | void OnLevelShutdown(); 43 | public: 44 | const char* GetAuthor(); 45 | const char* GetName(); 46 | const char* GetDescription(); 47 | const char* GetURL(); 48 | const char* GetLicense(); 49 | const char* GetVersion(); 50 | const char* GetDate(); 51 | const char* GetLogTag(); 52 | }; 53 | 54 | extern StripperCS2 g_StripperCS2; 55 | 56 | PLUGIN_GLOBALVARS(); 57 | 58 | #endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ -------------------------------------------------------------------------------- /src/hook.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #include "hook.h" 21 | #include 22 | #include "utils/module.h" 23 | #include 24 | #include 25 | #include 26 | #include "actions/actions.h" 27 | #include "extension.h" 28 | #include 29 | 30 | #ifdef _WIN32 31 | #define ROOTBIN "/bin/win64/" 32 | #define GAMEBIN "/csgo/bin/win64/" 33 | #else 34 | #define ROOTBIN "/bin/linuxsteamrt64/" 35 | #define GAMEBIN "/csgo/bin/linuxsteamrt64/" 36 | #endif 37 | 38 | #include 39 | 40 | class Timer 41 | { 42 | public: 43 | Timer() 44 | { 45 | m_StartTime = std::chrono::high_resolution_clock::now(); 46 | } 47 | 48 | ~Timer() 49 | { 50 | Stop(); 51 | } 52 | 53 | void Stop() 54 | { 55 | auto endTime = std::chrono::high_resolution_clock::now(); 56 | auto start = std::chrono::time_point_cast(m_StartTime).time_since_epoch().count(); 57 | auto end = std::chrono::time_point_cast(endTime).time_since_epoch().count(); 58 | 59 | auto duration = end - start; 60 | double ms = duration * 0.001; 61 | 62 | spdlog::info("Took {} us ({} ms)", duration, ms); 63 | } 64 | private: 65 | std::chrono::time_point m_StartTime; 66 | }; 67 | 68 | extern std::map, std::vector>> g_mapOverrides; 69 | 70 | namespace Hook 71 | { 72 | 73 | CSingleWorldRep* Detour_CreateWorldInternal(IWorldRendererMgr* pThis, CSingleWorldRep* singleWorld) 74 | { 75 | // The world can fail to be created and the function will return nullptr. 76 | if (!g_pCreateWorldInternal(pThis, singleWorld)) 77 | return nullptr; 78 | 79 | auto pWorld = singleWorld->m_pCWorld; 80 | 81 | { 82 | Timer timer; 83 | auto vecLumpData = (CUtlVector*)((uint8_t*)pWorld + 0x1B8);; 84 | 85 | FOR_EACH_VEC(*vecLumpData, i) 86 | { 87 | auto& lump = (*vecLumpData)[i]; 88 | auto lumpData = *(LumpData**)lump; 89 | 90 | auto vecEntityKeyValues = (CUtlVector*)((uint8_t*)lumpData + 0x1220); 91 | 92 | if (g_mapOverrides.find({ singleWorld->m_name.Get(), lumpData->m_name.Get() }) != g_mapOverrides.end()) 93 | { 94 | spdlog::info("Map override applying {} {}", singleWorld->m_name.Get(), lumpData->m_name.Get()); 95 | ApplyMapOverride(g_mapOverrides[{singleWorld->m_name.Get(), lumpData->m_name.Get()}], vecEntityKeyValues, lumpData); 96 | } 97 | 98 | if (g_mapOverrides.find({ "GLOBALOVERRIDE", "" }) != g_mapOverrides.end()) 99 | { 100 | spdlog::info("Map override applying global rules"); 101 | ApplyMapOverride(g_mapOverrides[{"GLOBALOVERRIDE", ""}], vecEntityKeyValues, lumpData); 102 | } 103 | } 104 | } 105 | 106 | return singleWorld; 107 | } 108 | 109 | bool SetupHook() 110 | { 111 | auto serverModule = new CModule(ROOTBIN, "worldrenderer"); 112 | 113 | int err; 114 | #ifdef WIN32 115 | const byte sig[] = "\x48\x89\x54\x24\x10\x53\x55\x56\x57\x48\x81\xEC\x98\x00\x00\x00"; 116 | #else 117 | const byte sig[] = "\x55\x48\x89\xE5\x41\x56\x41\x55\x41\x54\x49\x89\xFC\x53\x48\x89\xF3"; 118 | #endif 119 | g_pCreateWorldInternal = (CreateWorldInternal_t)serverModule->FindSignature((byte*)sig, sizeof(sig) - 1, err); 120 | 121 | if (err) 122 | { 123 | spdlog::critical("Failed to find CWorldRendererMgr::CreateWorld_Internal signature: {}", err); 124 | return false; 125 | } 126 | 127 | auto g_pHook = funchook_create(); 128 | funchook_prepare(g_pHook, (void**)&g_pCreateWorldInternal, (void*)Detour_CreateWorldInternal); 129 | funchook_install(g_pHook, 0); 130 | 131 | return true; 132 | } 133 | 134 | void Cleanup() 135 | { 136 | if (g_pHook) 137 | { 138 | funchook_uninstall(g_pHook, 0); 139 | funchook_destroy(g_pHook); 140 | g_pHook = nullptr; 141 | } 142 | } 143 | 144 | } // namespace Hook 145 | -------------------------------------------------------------------------------- /src/hook.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | namespace Hook 26 | { 27 | 28 | class IWorldRendererMgr; 29 | 30 | class CSingleWorldRep 31 | { 32 | private: 33 | void* vtable; 34 | public: 35 | CUtlString m_name; 36 | char pad[0x20]; 37 | void* m_pCWorld; 38 | }; 39 | 40 | typedef int (*CreateWorldInternal_t)(IWorldRendererMgr* pThis, CSingleWorldRep* singleWorld); 41 | inline CreateWorldInternal_t g_pCreateWorldInternal = nullptr; 42 | inline funchook_t* g_pHook = nullptr; 43 | 44 | void Detour_WorldInit(IWorldRendererMgr* pThis, CSingleWorldRep* singleWorld); 45 | bool SetupHook(); 46 | void Cleanup(); 47 | 48 | } // namespace Hook 49 | -------------------------------------------------------------------------------- /src/network_connection.pb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | typedef int ENetworkDisconnectionReason; -------------------------------------------------------------------------------- /src/providers/base_provider.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ -------------------------------------------------------------------------------- /src/providers/base_provider.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #pragma once 21 | 22 | namespace Providers 23 | { 24 | 25 | class BaseProvider 26 | { 27 | public: 28 | BaseProvider() = default; 29 | virtual ~BaseProvider() = default; 30 | private: 31 | }; 32 | 33 | } // namespace Providers -------------------------------------------------------------------------------- /src/providers/json/json_actions.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #include 21 | #include "actions/actions.h" 22 | #include "providers/json_provider.h" 23 | #include "pcre/pcre2.h" 24 | 25 | using json = nlohmann::json; 26 | 27 | namespace Providers::JSON 28 | { 29 | 30 | template 31 | void SetEntityField(T& variant, std::string&& value) 32 | { 33 | // precompile regex if it starts and ends with '/', this will result in m_strValue being empty 34 | if (value.length() >= 3 && value.front() == '/' && value.back() == '/') 35 | { 36 | value = value.substr(1, value.length() - 2); 37 | size_t nErrorOffset; 38 | int nErrorNumber; 39 | 40 | ConMsg("REGISTERED REGEX: %s\n", value.c_str()); 41 | 42 | auto re = pcre2_compile((PCRE2_SPTR)value.c_str(), value.length(), PCRE2_CASELESS, &nErrorNumber, &nErrorOffset, nullptr); 43 | 44 | if (!re) 45 | { 46 | PCRE2_UCHAR buffer[256]; 47 | pcre2_get_error_message(nErrorNumber, buffer, sizeof(buffer)); 48 | ConMsg("PCRE2 compilation failed at offset %d: %s\n", (int)nErrorOffset, buffer); 49 | throw std::runtime_error("PCRE2 compilation failed on value: " + value); 50 | } 51 | 52 | variant = re; 53 | } 54 | else 55 | variant = value; 56 | } 57 | 58 | void ParseEntry(nlohmann::detail::iteration_proxy&& items, std::vector& vecEntries, bool isIOArray) 59 | { 60 | for (auto& [key, value] : items) 61 | { 62 | if (key == "io") 63 | { 64 | auto ParseIOFields = [&vecEntries](const json& j) { 65 | ActionEntry entry; 66 | 67 | IOConnection ioDesc; 68 | for (auto& [ioKey, ioValue] : j.items()) 69 | { 70 | if (ioKey == "inputname") 71 | SetEntityField(ioDesc.m_pszInputName, ioValue.get()); 72 | else if (ioKey == "outputname") 73 | SetEntityField(ioDesc.m_pszOutputName, ioValue.get()); 74 | else if (ioKey == "targetname") 75 | SetEntityField(ioDesc.m_pszTargetName, ioValue.get()); 76 | else if (ioKey == "overrideparam") 77 | SetEntityField(ioDesc.m_pszOverrideParam, ioValue.get()); 78 | else if (ioKey == "delay") 79 | ioDesc.m_flDelay = ioValue.get(); 80 | else if (ioKey == "timestofire") 81 | ioDesc.m_nTimesToFire = ioValue.get(); 82 | else if (ioKey == "targettype") 83 | ioDesc.m_eTargetType = ioValue.get(); 84 | } 85 | 86 | entry.m_Value = std::move(ioDesc); 87 | vecEntries.push_back(std::move(entry)); 88 | }; 89 | 90 | if (isIOArray) 91 | { 92 | for (auto& io : value) 93 | ParseIOFields(io); 94 | } 95 | else 96 | ParseIOFields(value); 97 | } 98 | else 99 | { 100 | auto strValue = value.get(); 101 | ActionEntry entry; 102 | entry.m_strName = key; 103 | 104 | SetEntityField(entry.m_Value, std::move(strValue)); 105 | vecEntries.push_back(std::move(entry)); 106 | } 107 | } 108 | } 109 | 110 | void ParseFilters(const json& j, std::vector>& actions) 111 | { 112 | auto& filter = j["filter"]; 113 | for (auto& filterAction : filter) 114 | { 115 | auto action = std::make_unique(); 116 | 117 | ParseEntry(filterAction.items(), action->m_vecMatches); 118 | 119 | actions.push_back(std::move(action)); 120 | } 121 | } 122 | 123 | void ParseModify(const json& j, std::vector>& actions) 124 | { 125 | auto& filter = j["modify"]; 126 | for (auto& modifyAction : filter) 127 | { 128 | auto action = std::make_unique(); 129 | 130 | for (auto& [key, value] : modifyAction.items()) 131 | { 132 | if (key == "match") 133 | ParseEntry(value.items(), action->m_vecMatches); 134 | else if (key == "replace") 135 | ParseEntry(value.items(), action->m_vecReplacements, false); 136 | else if (key == "delete") 137 | ParseEntry(value.items(), action->m_vecDeletions); 138 | else if (key == "insert") 139 | ParseEntry(value.items(), action->m_vecInsertions); 140 | } 141 | 142 | 143 | actions.push_back(std::move(action)); 144 | } 145 | } 146 | 147 | void ParseAdd(const json& j, std::vector>& actions) 148 | { 149 | auto& filter = j["add"]; 150 | for (auto& addAction : filter) 151 | { 152 | auto action = std::make_unique(); 153 | 154 | ParseEntry(addAction.items(), action->m_vecInsertions); 155 | 156 | actions.push_back(std::move(action)); 157 | } 158 | } 159 | 160 | } // namespace Providers::JSON -------------------------------------------------------------------------------- /src/providers/json_provider.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #include "json_provider.h" 21 | #include "json.hpp" 22 | #include "actions/actions.h" 23 | #include 24 | 25 | namespace Providers 26 | { 27 | 28 | std::vector> JsonProvider::Load(const std::string& path) 29 | { 30 | std::ifstream i(path); 31 | 32 | if (!i.is_open()) 33 | throw std::runtime_error("Failed to open file: " + path); 34 | 35 | json::parse(i, std::bind(&JsonProvider::ParserCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), true, true); 36 | i.close(); 37 | 38 | std::vector> actions; 39 | 40 | if (m_json.find("filter") != m_json.end()) 41 | JSON::ParseFilters(m_json, actions); 42 | 43 | if (m_json.find("add") != m_json.end()) 44 | JSON::ParseAdd(m_json, actions); 45 | 46 | if (m_json.find("modify") != m_json.end()) 47 | JSON::ParseModify(m_json, actions); 48 | 49 | return actions; 50 | 51 | } 52 | 53 | // Our custom JSON parser, which retains the full config even when duplicate top-level keys are used (default parser does not do this) 54 | bool JsonProvider::ParserCallback(int depth, json::parse_event_t event, json& parsed) 55 | { 56 | if (depth != 1) 57 | return true; 58 | 59 | switch (event) 60 | { 61 | case json::parse_event_t::key: 62 | m_sCurrentKey = parsed.get(); 63 | break; 64 | case json::parse_event_t::array_end: 65 | for (json item : parsed) 66 | m_json[m_sCurrentKey].push_back(item); 67 | break; 68 | // Also allow using a single object instead of an array 69 | case json::parse_event_t::object_end: 70 | m_json[m_sCurrentKey].push_back(parsed); 71 | break; 72 | } 73 | 74 | return true; 75 | } 76 | 77 | } // namespace Providers -------------------------------------------------------------------------------- /src/providers/json_provider.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================ = 3 | * StripperCS2 4 | * Copyright(C) 2023 - 2024 Source2ZE 5 | * ============================================================================ = 6 | * 7 | *This program is free software; you can redistribute it and /or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program.If not, see < http://www.gnu.org/licenses/>. 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "base_provider.h" 23 | #include "actions/actions.h" 24 | #include 25 | #include 26 | 27 | using json = nlohmann::json; 28 | 29 | namespace Providers 30 | { 31 | 32 | class JsonProvider : public BaseProvider 33 | { 34 | public: 35 | JsonProvider() = default; 36 | ~JsonProvider() = default; 37 | 38 | std::vector> Load(const std::string& path); 39 | bool ParserCallback(int depth, json::parse_event_t event, json& parsed); 40 | private: 41 | std::string m_sCurrentKey; 42 | json m_json; 43 | }; 44 | 45 | namespace JSON 46 | { 47 | 48 | void ParseEntry(nlohmann::detail::iteration_proxy&& items, std::vector& vecEntries, bool isIOArray = true); 49 | void ParseFilters(const nlohmann::json& j, std::vector>& actions); 50 | void ParseModify(const nlohmann::json& j, std::vector>& actions); 51 | void ParseAdd(const nlohmann::json& j, std::vector>& actions); 52 | 53 | } // namespace JSON 54 | 55 | } // namespace Providers -------------------------------------------------------------------------------- /src/utils/module.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================= 3 | * StripperCS2 4 | * Copyright (C) 2023 Source2ZE 5 | * ============================================================================= 6 | * 7 | * This program is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "dbg.h" 22 | #include "interface.h" 23 | #include "strtools.h" 24 | #include "plat.h" 25 | 26 | #ifdef _WIN32 27 | #include 28 | #endif 29 | 30 | enum SigError 31 | { 32 | SIG_OK, 33 | SIG_NOT_FOUND, 34 | SIG_FOUND_MULTIPLE, 35 | }; 36 | 37 | class CModule 38 | { 39 | public: 40 | CModule(const char *path, const char *module) : 41 | m_pszModule(module), m_pszPath(path) 42 | { 43 | char szModule[MAX_PATH]; 44 | 45 | V_snprintf(szModule, MAX_PATH, "%s%s%s%s%s", Plat_GetGameDirectory(), path, MODULE_PREFIX, m_pszModule, MODULE_EXT); 46 | 47 | m_hModule = dlmount(szModule); 48 | 49 | if (!m_hModule) 50 | Error("Could not find %s\n", szModule); 51 | 52 | #ifdef _WIN32 53 | MODULEINFO m_hModuleInfo; 54 | GetModuleInformation(GetCurrentProcess(), m_hModule, &m_hModuleInfo, sizeof(m_hModuleInfo)); 55 | 56 | m_base = (void *)m_hModuleInfo.lpBaseOfDll; 57 | m_size = m_hModuleInfo.SizeOfImage; 58 | #else 59 | if (int e = GetModuleInformation(m_hModule, &m_base, &m_size)) 60 | Error("Failed to get module info for %s, error %d\n", szModule, e); 61 | #endif 62 | 63 | ConMsg("Initialized module %s base: 0x%p | size: %lu\n", m_pszModule, m_base, m_size); 64 | } 65 | 66 | void *FindSignature(const byte *pData, size_t iSigLength, int &error) 67 | { 68 | unsigned char *pMemory; 69 | void *return_addr = nullptr; 70 | error = 0; 71 | 72 | pMemory = (byte*)m_base; 73 | 74 | for (size_t i = 0; i < m_size; i++) 75 | { 76 | size_t Matches = 0; 77 | while (*(pMemory + i + Matches) == pData[Matches] || pData[Matches] == '\x2A') 78 | { 79 | Matches++; 80 | if (Matches == iSigLength) 81 | { 82 | if (return_addr) 83 | { 84 | error = SIG_FOUND_MULTIPLE; 85 | return return_addr; 86 | } 87 | 88 | return_addr = (void *)(pMemory + i); 89 | } 90 | } 91 | } 92 | 93 | if (!return_addr) 94 | error = SIG_NOT_FOUND; 95 | 96 | return return_addr; 97 | } 98 | 99 | void *FindInterface(const char *name) 100 | { 101 | CreateInterfaceFn fn = (CreateInterfaceFn)dlsym(m_hModule, "CreateInterface"); 102 | 103 | if (!fn) 104 | Error("Could not find CreateInterface in %s\n", m_pszModule); 105 | 106 | void *pInterface = fn(name, nullptr); 107 | 108 | if (!pInterface) 109 | Error("Could not find %s in %s\n", name, m_pszModule); 110 | 111 | ConMsg("Found interface %s in %s\n", name, m_pszModule); 112 | 113 | return pInterface; 114 | } 115 | 116 | const char *m_pszModule; 117 | const char* m_pszPath; 118 | HINSTANCE m_hModule; 119 | void* m_base; 120 | size_t m_size; 121 | }; -------------------------------------------------------------------------------- /src/utils/plat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================= 3 | * StripperCS2 4 | * Copyright (C) 2023 Source2ZE 5 | * ============================================================================= 6 | * 7 | * This program is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include 22 | #include "metamod_oslink.h" 23 | 24 | struct Module 25 | { 26 | #ifndef _WIN32 27 | void* pHandle; 28 | #endif 29 | uint8_t* pBase; 30 | unsigned int nSize; 31 | }; 32 | 33 | #ifndef _WIN32 34 | int GetModuleInformation(HINSTANCE module, void** base, size_t* length); 35 | #endif 36 | 37 | #ifdef _WIN32 38 | #define MODULE_PREFIX "" 39 | #define MODULE_EXT ".dll" 40 | #else 41 | #define MODULE_PREFIX "lib" 42 | #define MODULE_EXT ".so" 43 | #endif 44 | 45 | void Plat_WriteMemory(void* pPatchAddress, uint8_t *pPatch, int iPatchSize); -------------------------------------------------------------------------------- /src/utils/plat_unix.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================= 3 | * StripperCS2 4 | * Copyright (C) 2023 Source2ZE 5 | * ============================================================================= 6 | * 7 | * This program is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program. If not, see . 18 | */ 19 | 20 | #ifdef __linux__ 21 | #include "plat.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "sys/mman.h" 27 | #include 28 | #include 29 | #include 30 | #include "dbg.h" 31 | 32 | #include "tier0/memdbgon.h" 33 | 34 | #define PAGE_SIZE 4096 35 | #define PAGE_ALIGN_UP(x) ((x + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) 36 | 37 | struct ModuleInfo 38 | { 39 | const char* path; // in 40 | uint8_t* base; // out 41 | uint size; // out 42 | }; 43 | 44 | // https://github.com/alliedmodders/sourcemod/blob/master/core/logic/MemoryUtils.cpp#L502-L587 45 | int GetModuleInformation(HINSTANCE hModule, void** base, size_t* length) 46 | { 47 | struct link_map* dlmap = (struct link_map*)hModule; 48 | Dl_info info; 49 | Elf64_Ehdr* file; 50 | Elf64_Phdr* phdr; 51 | uint16_t phdrCount; 52 | 53 | if (!dladdr((void*)dlmap->l_addr, &info)) 54 | { 55 | return 1; 56 | } 57 | 58 | if (!info.dli_fbase || !info.dli_fname) 59 | { 60 | return 2; 61 | } 62 | 63 | /* This is for our insane sanity checks :o */ 64 | uintptr_t baseAddr = reinterpret_cast(info.dli_fbase); 65 | file = reinterpret_cast(baseAddr); 66 | 67 | /* Check ELF magic */ 68 | if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0) 69 | { 70 | return 3; 71 | } 72 | 73 | /* Check ELF version */ 74 | if (file->e_ident[EI_VERSION] != EV_CURRENT) 75 | { 76 | return 4; 77 | } 78 | 79 | /* Check ELF endianness */ 80 | if (file->e_ident[EI_DATA] != ELFDATA2LSB) 81 | { 82 | return 5; 83 | } 84 | 85 | /* Check ELF architecture */ 86 | if (file->e_ident[EI_CLASS] != ELFCLASS64 || file->e_machine != EM_X86_64) 87 | { 88 | return 6; 89 | } 90 | 91 | /* For our purposes, this must be a dynamic library/shared object */ 92 | if (file->e_type != ET_DYN) 93 | { 94 | return 7; 95 | } 96 | 97 | phdrCount = file->e_phnum; 98 | phdr = reinterpret_cast(baseAddr + file->e_phoff); 99 | 100 | for (uint16_t i = 0; i < phdrCount; i++) 101 | { 102 | Elf64_Phdr& hdr = phdr[i]; 103 | 104 | /* We only really care about the segment with executable code */ 105 | if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X | PF_R)) 106 | { 107 | /* From glibc, elf/dl-load.c: 108 | * c->mapend = ((ph->p_vaddr + ph->p_filesz + GLRO(dl_pagesize) - 1) 109 | * & ~(GLRO(dl_pagesize) - 1)); 110 | * 111 | * In glibc, the segment file size is aligned up to the nearest page size and 112 | * added to the virtual address of the segment. We just want the size here. 113 | */ 114 | //lib.memorySize = PAGE_ALIGN_UP(hdr.p_filesz); 115 | *length = PAGE_ALIGN_UP(hdr.p_filesz); 116 | *base = (void*)(baseAddr + hdr.p_paddr); 117 | 118 | break; 119 | } 120 | } 121 | 122 | return 0; 123 | } 124 | 125 | static int parse_prot(const char* s) 126 | { 127 | int prot = 0; 128 | 129 | for (; *s; s++) 130 | { 131 | switch (*s) 132 | { 133 | case '-': 134 | break; 135 | case 'r': 136 | prot |= PROT_READ; 137 | break; 138 | case 'w': 139 | prot |= PROT_WRITE; 140 | break; 141 | case 'x': 142 | prot |= PROT_EXEC; 143 | break; 144 | case 's': 145 | break; 146 | case 'p': 147 | break; 148 | default: 149 | break; 150 | } 151 | } 152 | 153 | return prot; 154 | } 155 | 156 | static int get_prot(void* pAddr, size_t nSize) 157 | { 158 | FILE* f = fopen("/proc/self/maps", "r"); 159 | 160 | uintptr_t nAddr = (uintptr_t)pAddr; 161 | 162 | char line[512]; 163 | while (fgets(line, sizeof(line), f)) 164 | { 165 | char start[16]; 166 | char end[16]; 167 | char prot[16]; 168 | 169 | const char* src = line; 170 | 171 | char* dst = start; 172 | while (*src != '-') 173 | *dst++ = *src++; 174 | *dst = 0; 175 | 176 | src++; // skip "-"" 177 | 178 | dst = end; 179 | while (!isspace(*src)) 180 | *dst++ = *src++; 181 | *dst = 0; 182 | 183 | src++; // skip space 184 | 185 | dst = prot; 186 | while (!isspace(*src)) 187 | *dst++ = *src++; 188 | *dst = 0; 189 | 190 | uintptr_t nStart = (uintptr_t)strtoul(start, nullptr, 16); 191 | uintptr_t nEnd = (uintptr_t)strtoul(end, nullptr, 16); 192 | 193 | if (nStart < nAddr && nEnd >(nAddr + nSize)) 194 | { 195 | fclose(f); 196 | return parse_prot(prot); 197 | } 198 | } 199 | 200 | fclose(f); 201 | return 0; 202 | } 203 | 204 | void Plat_WriteMemory(void* pPatchAddress, uint8_t* pPatch, int iPatchSize) 205 | { 206 | int old_prot = get_prot(pPatchAddress, iPatchSize); 207 | 208 | uintptr_t page_size = sysconf(_SC_PAGESIZE); 209 | uint8_t* align_addr = (uint8_t*)((uintptr_t)pPatchAddress & ~(page_size - 1)); 210 | 211 | uint8_t* end = (uint8_t*)pPatchAddress + iPatchSize; 212 | uintptr_t align_size = end - align_addr; 213 | 214 | int result = mprotect(align_addr, align_size, PROT_READ | PROT_WRITE); 215 | 216 | memcpy(pPatchAddress, pPatch, iPatchSize); 217 | 218 | result = mprotect(align_addr, align_size, old_prot); 219 | } 220 | #endif 221 | 222 | -------------------------------------------------------------------------------- /src/utils/plat_win.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ============================================================================= 3 | * StripperCS2 4 | * Copyright (C) 2023 Source2ZE 5 | * ============================================================================= 6 | * 7 | * This program is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU General Public License, version 3.0, as published by the 9 | * Free Software Foundation. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program. If not, see . 18 | */ 19 | 20 | #ifdef WIN32 21 | 22 | #include "plat.h" 23 | 24 | #include "tier0/memdbgon.h" 25 | 26 | void Plat_WriteMemory(void* pPatchAddress, uint8_t* pPatch, int iPatchSize) 27 | { 28 | WriteProcessMemory(GetCurrentProcess(), pPatchAddress, (void*)pPatch, iPatchSize, nullptr); 29 | } 30 | 31 | #endif -------------------------------------------------------------------------------- /vendor/funchook/include/funchook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Funchook. 3 | * https://github.com/kubo/funchook 4 | * 5 | * Funchook is free software: you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation, either version 2 of the License, or (at your 8 | * option) any later version. 9 | * 10 | * As a special exception, the copyright holders of this library give you 11 | * permission to link this library with independent modules to produce an 12 | * executable, regardless of the license terms of these independent 13 | * modules, and to copy and distribute the resulting executable under 14 | * terms of your choice, provided that you also meet, for each linked 15 | * independent module, the terms and conditions of the license of that 16 | * module. An independent module is a module which is not derived from or 17 | * based on this library. If you modify this library, you may extend this 18 | * exception to your version of the library, but you are not obliged to 19 | * do so. If you do not wish to do so, delete this exception statement 20 | * from your version. 21 | * 22 | * Funchook is distributed in the hope that it will be useful, but WITHOUT 23 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25 | * for more details. 26 | * 27 | * You should have received a copy of the GNU General Public License 28 | * along with Funchook. If not, see . 29 | */ 30 | #ifndef FUNCHOOK_H 31 | #define FUNCHOOK_H 1 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* 38 | * Only functions with FUNCHOOK_EXPORT are visible from outside of funchook.dll 39 | * or libfunchook.so. Others are invisible. 40 | */ 41 | #ifdef FUNCHOOK_EXPORTS 42 | #if defined(_WIN32) 43 | #define FUNCHOOK_EXPORT __declspec(dllexport) 44 | #elif defined(__GNUC__) 45 | #define FUNCHOOK_EXPORT __attribute__((visibility("default"))) 46 | #endif 47 | #endif /* FUNCHOOK_EXPORTS */ 48 | #ifndef FUNCHOOK_EXPORT 49 | #define FUNCHOOK_EXPORT 50 | #endif 51 | 52 | typedef struct funchook funchook_t; 53 | 54 | #define FUNCHOOK_ERROR_INTERNAL_ERROR -1 55 | #define FUNCHOOK_ERROR_SUCCESS 0 56 | #define FUNCHOOK_ERROR_OUT_OF_MEMORY 1 57 | #define FUNCHOOK_ERROR_ALREADY_INSTALLED 2 58 | #define FUNCHOOK_ERROR_DISASSEMBLY 3 59 | #define FUNCHOOK_ERROR_IP_RELATIVE_OFFSET 4 60 | #define FUNCHOOK_ERROR_CANNOT_FIX_IP_RELATIVE 5 61 | #define FUNCHOOK_ERROR_FOUND_BACK_JUMP 6 62 | #define FUNCHOOK_ERROR_TOO_SHORT_INSTRUCTIONS 7 63 | #define FUNCHOOK_ERROR_MEMORY_ALLOCATION 8 /* memory allocation error */ 64 | #define FUNCHOOK_ERROR_MEMORY_FUNCTION 9 /* other memory function errors */ 65 | #define FUNCHOOK_ERROR_NOT_INSTALLED 10 66 | #define FUNCHOOK_ERROR_NO_AVAILABLE_REGISTERS 11 67 | #define FUNCHOOK_ERROR_NO_SPACE_NEAR_TARGET_ADDR 12 68 | 69 | #define FUNCHOOK_FLAG_THISCALL (1u << 0) 70 | #define FUNCHOOK_FLAG_FASTCALL (1u << 1) 71 | 72 | typedef struct funchook_arg_handle funchook_arg_handle_t; 73 | 74 | typedef struct funchook_info { 75 | void *original_target_func; 76 | void *target_func; 77 | void *trampoline_func; 78 | void *hook_func; 79 | void *user_data; 80 | funchook_arg_handle_t *arg_handle; 81 | } funchook_info_t; 82 | 83 | typedef void (*funchook_hook_t)(funchook_info_t *fi); 84 | 85 | typedef struct { 86 | void *hook_func; 87 | funchook_hook_t prehook; 88 | void *user_data; 89 | unsigned int flags; 90 | } funchook_params_t; 91 | 92 | /** 93 | * Create a funchook handle 94 | * 95 | * @return allocated funchook handle. NULL when out-of-memory. 96 | */ 97 | FUNCHOOK_EXPORT funchook_t *funchook_create(void); 98 | 99 | /** 100 | * Prepare hooking 101 | * 102 | * @param funchook a funchook handle created by funchook_create() 103 | * @param target_func function pointer to be intercepted. The pointer to trampoline function is set on success. 104 | * @param hook_func function pointer which is called istead of target_func 105 | * @return error code. one of FUNCHOOK_ERROR_*. 106 | */ 107 | FUNCHOOK_EXPORT int funchook_prepare(funchook_t *funchook, void **target_func, void *hook_func); 108 | 109 | FUNCHOOK_EXPORT int funchook_prepare_with_params(funchook_t *funchook, 110 | void **target_func, const funchook_params_t *params); 111 | 112 | /** 113 | * Install hooks prepared by funchook_prepare(). 114 | * 115 | * @param funchook a funchook handle created by funchook_create() 116 | * @param flags reserved. Set zero. 117 | * @return error code. one of FUNCHOOK_ERROR_*. 118 | */ 119 | FUNCHOOK_EXPORT int funchook_install(funchook_t *funchook, int flags); 120 | 121 | /** 122 | * Uninstall hooks installed by funchook_install(). 123 | * 124 | * @param funchook a funchook handle created by funchook_create() 125 | * @param flags reserved. Set zero. 126 | * @return error code. one of FUNCHOOK_ERROR_*. 127 | */ 128 | FUNCHOOK_EXPORT int funchook_uninstall(funchook_t *funchook, int flags); 129 | 130 | /** 131 | * Destroy a funchook handle 132 | * 133 | * @param funchook a funchook handle created by funchook_create() 134 | * @return error code. one of FUNCHOOK_ERROR_*. 135 | */ 136 | FUNCHOOK_EXPORT int funchook_destroy(funchook_t *funchook); 137 | 138 | /** 139 | * Get error message 140 | * 141 | * @param funchook a funchook handle created by funchook_create() 142 | * @return pointer to buffer containing error message 143 | */ 144 | FUNCHOOK_EXPORT const char *funchook_error_message(const funchook_t *funchook); 145 | 146 | /** 147 | * Set log file name to debug funchook itself. 148 | * 149 | * @param name log file name 150 | * @return error code. one of FUNCHOOK_ERROR_*. 151 | */ 152 | FUNCHOOK_EXPORT int funchook_set_debug_file(const char *name); 153 | 154 | /* This function is under developemnt. It will be used by C++ template functions later. */ 155 | FUNCHOOK_EXPORT void *funchook_arg_get_int_reg_addr(const funchook_arg_handle_t *arg_handle, int pos); 156 | 157 | /* This function is under developemnt. It will be used by C++ template functions later. */ 158 | FUNCHOOK_EXPORT void *funchook_arg_get_flt_reg_addr(const funchook_arg_handle_t *arg_handle, int pos); 159 | 160 | /* This function is under developemnt. It will be used by C++ template functions later. */ 161 | FUNCHOOK_EXPORT void *funchook_arg_get_stack_addr(const funchook_arg_handle_t *arg_handle, int pos); 162 | 163 | #ifdef __cplusplus 164 | } // extern "C" 165 | #endif 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /vendor/funchook/lib/Debug/distorm.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Debug/distorm.lib -------------------------------------------------------------------------------- /vendor/funchook/lib/Debug/distorm.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Debug/distorm.pdb -------------------------------------------------------------------------------- /vendor/funchook/lib/Debug/funchook.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Debug/funchook.lib -------------------------------------------------------------------------------- /vendor/funchook/lib/Debug/funchook.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Debug/funchook.pdb -------------------------------------------------------------------------------- /vendor/funchook/lib/Debug/libdistorm.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Debug/libdistorm.a -------------------------------------------------------------------------------- /vendor/funchook/lib/Debug/libfunchook.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Debug/libfunchook.a -------------------------------------------------------------------------------- /vendor/funchook/lib/Release/distorm.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Release/distorm.lib -------------------------------------------------------------------------------- /vendor/funchook/lib/Release/funchook.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Release/funchook.lib -------------------------------------------------------------------------------- /vendor/funchook/lib/Release/libdistorm.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Release/libdistorm.a -------------------------------------------------------------------------------- /vendor/funchook/lib/Release/libfunchook.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Source2ZE/StripperCS2/ce8ccf1fdb49fda8bb393d8eb87a2bcb91bf75c0/vendor/funchook/lib/Release/libfunchook.a -------------------------------------------------------------------------------- /vendor/nlohmann/json_fwd.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.11.3 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ 10 | #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ 11 | 12 | #include // int64_t, uint64_t 13 | #include // map 14 | #include // allocator 15 | #include // string 16 | #include // vector 17 | 18 | // #include 19 | // __ _____ _____ _____ 20 | // __| | __| | | | JSON for Modern C++ 21 | // | | |__ | | | | | | version 3.11.3 22 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 23 | // 24 | // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann 25 | // SPDX-License-Identifier: MIT 26 | 27 | 28 | 29 | // This file contains all macro definitions affecting or depending on the ABI 30 | 31 | #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK 32 | #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) 33 | #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3 34 | #warning "Already included a different version of the library!" 35 | #endif 36 | #endif 37 | #endif 38 | 39 | #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) 40 | #define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) 41 | #define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum) 42 | 43 | #ifndef JSON_DIAGNOSTICS 44 | #define JSON_DIAGNOSTICS 0 45 | #endif 46 | 47 | #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 48 | #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 49 | #endif 50 | 51 | #if JSON_DIAGNOSTICS 52 | #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag 53 | #else 54 | #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS 55 | #endif 56 | 57 | #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 58 | #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp 59 | #else 60 | #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON 61 | #endif 62 | 63 | #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION 64 | #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 65 | #endif 66 | 67 | // Construct the namespace ABI tags component 68 | #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b 69 | #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ 70 | NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) 71 | 72 | #define NLOHMANN_JSON_ABI_TAGS \ 73 | NLOHMANN_JSON_ABI_TAGS_CONCAT( \ 74 | NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ 75 | NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) 76 | 77 | // Construct the namespace version component 78 | #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ 79 | _v ## major ## _ ## minor ## _ ## patch 80 | #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ 81 | NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) 82 | 83 | #if NLOHMANN_JSON_NAMESPACE_NO_VERSION 84 | #define NLOHMANN_JSON_NAMESPACE_VERSION 85 | #else 86 | #define NLOHMANN_JSON_NAMESPACE_VERSION \ 87 | NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ 88 | NLOHMANN_JSON_VERSION_MINOR, \ 89 | NLOHMANN_JSON_VERSION_PATCH) 90 | #endif 91 | 92 | // Combine namespace components 93 | #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b 94 | #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ 95 | NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) 96 | 97 | #ifndef NLOHMANN_JSON_NAMESPACE 98 | #define NLOHMANN_JSON_NAMESPACE \ 99 | nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ 100 | NLOHMANN_JSON_ABI_TAGS, \ 101 | NLOHMANN_JSON_NAMESPACE_VERSION) 102 | #endif 103 | 104 | #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN 105 | #define NLOHMANN_JSON_NAMESPACE_BEGIN \ 106 | namespace nlohmann \ 107 | { \ 108 | inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ 109 | NLOHMANN_JSON_ABI_TAGS, \ 110 | NLOHMANN_JSON_NAMESPACE_VERSION) \ 111 | { 112 | #endif 113 | 114 | #ifndef NLOHMANN_JSON_NAMESPACE_END 115 | #define NLOHMANN_JSON_NAMESPACE_END \ 116 | } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ 117 | } // namespace nlohmann 118 | #endif 119 | 120 | 121 | /*! 122 | @brief namespace for Niels Lohmann 123 | @see https://github.com/nlohmann 124 | @since version 1.0.0 125 | */ 126 | NLOHMANN_JSON_NAMESPACE_BEGIN 127 | 128 | /*! 129 | @brief default JSONSerializer template argument 130 | 131 | This serializer ignores the template arguments and uses ADL 132 | ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) 133 | for serialization. 134 | */ 135 | template 136 | struct adl_serializer; 137 | 138 | /// a class to store JSON values 139 | /// @sa https://json.nlohmann.me/api/basic_json/ 140 | template class ObjectType = 141 | std::map, 142 | template class ArrayType = std::vector, 143 | class StringType = std::string, class BooleanType = bool, 144 | class NumberIntegerType = std::int64_t, 145 | class NumberUnsignedType = std::uint64_t, 146 | class NumberFloatType = double, 147 | template class AllocatorType = std::allocator, 148 | template class JSONSerializer = 149 | adl_serializer, 150 | class BinaryType = std::vector, // cppcheck-suppress syntaxError 151 | class CustomBaseClass = void> 152 | class basic_json; 153 | 154 | /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document 155 | /// @sa https://json.nlohmann.me/api/json_pointer/ 156 | template 157 | class json_pointer; 158 | 159 | /*! 160 | @brief default specialization 161 | @sa https://json.nlohmann.me/api/json/ 162 | */ 163 | using json = basic_json<>; 164 | 165 | /// @brief a minimal map-like container that preserves insertion order 166 | /// @sa https://json.nlohmann.me/api/ordered_map/ 167 | template 168 | struct ordered_map; 169 | 170 | /// @brief specialization that maintains the insertion order of object keys 171 | /// @sa https://json.nlohmann.me/api/ordered_json/ 172 | using ordered_json = basic_json; 173 | 174 | NLOHMANN_JSON_NAMESPACE_END 175 | 176 | #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ 177 | -------------------------------------------------------------------------------- /vendor/pcre/config.h: -------------------------------------------------------------------------------- 1 | /* config.h for CMake builds */ 2 | 3 | /* #undef HAVE_BUILTIN_MUL_OVERFLOW */ 4 | /* #undef HAVE_ATTRIBUTE_UNINITIALIZED */ 5 | /* #undef HAVE_DIRENT_H */ 6 | #define HAVE_SYS_STAT_H 1 7 | #define HAVE_SYS_TYPES_H 1 8 | /* #undef HAVE_UNISTD_H */ 9 | /* #define HAVE_WINDOWS_H 1 */ 10 | 11 | /* #undef HAVE_BCOPY */ 12 | /* #undef HAVE_MEMFD_CREATE */ 13 | #define HAVE_MEMMOVE 1 14 | /* #undef HAVE_SECURE_GETENV */ 15 | #define HAVE_STRERROR 1 16 | 17 | #define SUPPORT_PCRE2_8 1 18 | /* #undef SUPPORT_PCRE2_16 */ 19 | /* #undef SUPPORT_PCRE2_32 */ 20 | /* #undef PCRE2_DEBUG */ 21 | /* #undef DISABLE_PERCENT_ZT */ 22 | 23 | /* #undef SUPPORT_LIBBZ2 */ 24 | /* #undef SUPPORT_LIBEDIT */ 25 | /* #undef SUPPORT_LIBREADLINE */ 26 | /* #undef SUPPORT_LIBZ */ 27 | 28 | /* #undef SUPPORT_JIT */ 29 | /* #undef SLJIT_PROT_EXECUTABLE_ALLOCATOR */ 30 | #define SUPPORT_PCRE2GREP_JIT 1 31 | #define SUPPORT_PCRE2GREP_CALLOUT 1 32 | #define SUPPORT_PCRE2GREP_CALLOUT_FORK 1 33 | #define SUPPORT_UNICODE 1 34 | /* #undef SUPPORT_VALGRIND */ 35 | 36 | /* #undef BSR_ANYCRLF */ 37 | /* #undef EBCDIC */ 38 | /* #undef EBCDIC_NL25 */ 39 | /* #undef HEAP_MATCH_RECURSE */ 40 | /* #undef NEVER_BACKSLASH_C */ 41 | 42 | #define PCRE2_EXPORT 43 | #define LINK_SIZE 2 44 | #define HEAP_LIMIT 20000000 45 | #define MATCH_LIMIT 10000000 46 | #define MATCH_LIMIT_DEPTH MATCH_LIMIT 47 | #define MAX_VARLOOKBEHIND 255 48 | #define NEWLINE_DEFAULT 2 49 | #define PARENS_NEST_LIMIT 250 50 | #define PCRE2GREP_BUFSIZE 20480 51 | #define PCRE2GREP_MAX_BUFSIZE 1048576 52 | 53 | #define MAX_NAME_SIZE 32 54 | #define MAX_NAME_COUNT 10000 55 | 56 | /* end config.h for CMake builds */ 57 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/pcre2posix_test.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * PCRE2 POSIX interface test program * 3 | *************************************************/ 4 | 5 | /* 6 | Written by Philip Hazel, December 2022 7 | Copyright (c) 2022 8 | File last edited: December 2022 9 | 10 | This program tests the POSIX wrapper to the PCRE2 regular expression library. 11 | The main PCRE2 test program is pcre2test, which also tests these function 12 | calls. This little program is needed to test the case where the client includes 13 | pcre2posix.h but not pcre2.h, mainly to make sure that it builds successfully. 14 | However, the code is written as a flexible test program to which extra tests 15 | can be added. 16 | 17 | Compile with -lpcre2-posix -lpcre2-8 18 | 19 | If run with no options, there is no output on success, and the return code is 20 | zero. If any test fails there is output to stderr, and the return code is 1. 21 | 22 | For testing purposes, the "-v" option causes verification output to be written 23 | to stdout. */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #define CAPCOUNT 5 /* Number of captures supported */ 30 | #define PRINTF if (v) printf /* Shorthand for testing output */ 31 | 32 | /* This vector contains compiler flags for each pattern that is tested. */ 33 | 34 | static int cflags[] = { 35 | 0, /* Test 0 */ 36 | REG_ICASE, /* Test 1 */ 37 | 0, /* Test 2 */ 38 | REG_NEWLINE, /* Test 3 */ 39 | 0 /* Test 4 */ 40 | }; 41 | 42 | /* This vector contains match flags for each pattern that is tested. */ 43 | 44 | static int mflags[] = { 45 | 0, /* Test 0 */ 46 | 0, /* Test 1 */ 47 | 0, /* Test 2 */ 48 | REG_NOTBOL, /* Test 3 */ 49 | 0 /* Test 4 */ 50 | }; 51 | 52 | /* Automate the number of patterns */ 53 | 54 | #define count (int)(sizeof(cflags)/sizeof(int)) 55 | 56 | /* The data for each pattern consists of a pattern string, followed by any 57 | number of subject strings, terminated by NULL. Some tests share data, but use 58 | different flags. */ 59 | 60 | static const char *data0_1[] = { "posix", "lower posix", "upper POSIX", NULL }; 61 | static const char *data2_3[] = { "(*LF)^(cat|dog)", "catastrophic\ncataclysm", 62 | "dogfight", "no animals", NULL }; 63 | static const char *data4[] = { "*badpattern", NULL }; 64 | 65 | /* Index the data strings */ 66 | 67 | static char **data[] = { 68 | (char **)(&data0_1), 69 | (char **)(&data0_1), 70 | (char **)(&data2_3), 71 | (char **)(&data2_3), 72 | (char **)(&data4) 73 | }; 74 | 75 | /* The expected results for each pattern consist of a compiler return code, 76 | optionally followed, for each subject string, by a match return code and, for a 77 | successful match, up to CAPCOUNT pairs of returned match data. */ 78 | 79 | static int results0[] = { 80 | 0, /* Compiler rc */ 81 | 0, 6, 11, /* 1st match */ 82 | REG_NOMATCH /* 2nd match */ 83 | }; 84 | 85 | static int results1[] = { 86 | 0, /* Compiler rc */ 87 | 0, 6, 11, /* 1st match */ 88 | 0, 6, 11 /* 2nd match */ 89 | }; 90 | 91 | static int results2[] = { 92 | 0, /* Compiler rc */ 93 | 0, 0, 3, 0, 3, /* 1st match */ 94 | 0, 0, 3, 0, 3, /* 2nd match */ 95 | REG_NOMATCH /* 3rd match */ 96 | }; 97 | 98 | static int results3[] = { 99 | 0, /* Compiler rc */ 100 | 0, 13, 16, 13, 16, /* 1st match */ 101 | REG_NOMATCH, /* 2nd match */ 102 | REG_NOMATCH /* 3rd match */ 103 | }; 104 | 105 | static int results4[] = { 106 | REG_BADRPT /* Compiler rc */ 107 | }; 108 | 109 | /* Index the result vectors */ 110 | 111 | static int *results[] = { 112 | (int *)(&results0), 113 | (int *)(&results1), 114 | (int *)(&results2), 115 | (int *)(&results3), 116 | (int *)(&results4) 117 | }; 118 | 119 | /* And here is the program */ 120 | 121 | int main(int argc, char **argv) 122 | { 123 | regex_t re; 124 | regmatch_t match[CAPCOUNT]; 125 | int v = argc > 1 && strcmp(argv[1], "-v") == 0; 126 | 127 | PRINTF("Test of pcre2posix.h without pcre2.h\n"); 128 | 129 | for (int i = 0; i < count; i++) 130 | { 131 | char *pattern = data[i][0]; 132 | char **subjects = data[i] + 1; 133 | int *rd = results[i]; 134 | int rc = regcomp(&re, pattern, cflags[i]); 135 | 136 | PRINTF("Pattern: %s flags=0x%02x\n", pattern, cflags[i]); 137 | 138 | if (rc != *rd) 139 | { 140 | fprintf(stderr, "Unexpected compile error %d (expected %d)\n", rc, *rd); 141 | fprintf(stderr, "Pattern is: %s\n", pattern); 142 | return 1; 143 | } 144 | 145 | if (rc != 0) 146 | { 147 | if (v) 148 | { 149 | char buffer[256]; 150 | (void)regerror(rc, &re, buffer, sizeof(buffer)); 151 | PRINTF("Compile error %d: %s (expected)\n", rc, buffer); 152 | } 153 | continue; 154 | } 155 | 156 | for (; *subjects != NULL; subjects++) 157 | { 158 | rc = regexec(&re, *subjects, CAPCOUNT, match, mflags[i]); 159 | 160 | PRINTF("Subject: %s\n", *subjects); 161 | PRINTF("Return: %d", rc); 162 | 163 | if (rc != *(++rd)) 164 | { 165 | PRINTF("\n"); 166 | fprintf(stderr, "Unexpected match error %d (expected %d)\n", rc, *rd); 167 | fprintf(stderr, "Pattern is: %s\n", pattern); 168 | fprintf(stderr, "Subject is: %s\n", *subjects); 169 | return 1; 170 | } 171 | 172 | if (rc == 0) 173 | { 174 | for (int j = 0; j < CAPCOUNT; j++) 175 | { 176 | regmatch_t *m = match + j; 177 | if (m->rm_so < 0) continue; 178 | if (m->rm_so != *(++rd) || m->rm_eo != *(++rd)) 179 | { 180 | PRINTF("\n"); 181 | fprintf(stderr, "Mismatched results for successful match\n"); 182 | fprintf(stderr, "Pattern is: %s\n", pattern); 183 | fprintf(stderr, "Subject is: %s\n", *subjects); 184 | fprintf(stderr, "Result %d: expected %d %d received %d %d\n", 185 | j, rd[-1], rd[0], m->rm_so, m->rm_eo); 186 | return 1; 187 | } 188 | PRINTF(" (%d %d %d)", j, m->rm_so, m->rm_eo); 189 | } 190 | } 191 | 192 | else if (v) 193 | { 194 | char buffer[256]; 195 | (void)regerror(rc, &re, buffer, sizeof(buffer)); 196 | PRINTF(": %s (expected)", buffer); 197 | } 198 | 199 | PRINTF("\n"); 200 | } 201 | 202 | regfree(&re); 203 | } 204 | 205 | PRINTF("End of test\n"); 206 | return 0; 207 | } 208 | 209 | /* End of pcre2posix_test.c */ 210 | -------------------------------------------------------------------------------- /vendor/pcre/premake5.lua: -------------------------------------------------------------------------------- 1 | project "pcre" 2 | kind "StaticLib" 3 | language "C++" 4 | 5 | defines { "HAVE_CONFIG_H", "PCRE2_CODE_UNIT_WIDTH=8", "PCRE2_STATIC" } 6 | includedirs { "." } 7 | 8 | vpaths { 9 | ["Headers/*"] = "**.h", 10 | ["Sources/*"] = {"**.c", "**.cc"}, 11 | ["*"] = "premake5.lua" 12 | } 13 | 14 | files { 15 | "premake5.lua", 16 | "*.c", 17 | "*.cc", 18 | "*.h" 19 | } 20 | 21 | removefiles { 22 | "pcre2_jit_misc.c", 23 | "pcre2_jit_match.c", 24 | "pcre2_printint.c", 25 | } 26 | 27 | pic "On" 28 | 29 | filter "system:windows" 30 | defines { "HAVE_WINDOWS_H" } -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | -------------------------------------------------------------------------------- /vendor/pcre/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 | --------------------------------------------------------------------------------