4 Commits
v0.2.0 ... main

382 changed files with 652523 additions and 532 deletions

3
.gitignore vendored
View File

@@ -2,6 +2,9 @@ node_modules/
dist/
release/
.engine-build/
engines/java/target/
engines/dotnet/bin/
engines/dotnet/obj/
coverage/
playwright-report/
test-results/

3
.npmrc
View File

@@ -1,2 +1 @@
@add-ideas:registry=https://git.add-ideas.de/api/packages/zemion/npm/
@add-ideas:registry=https://git.add-ideas.de/api/packages/lotobo/npm/

View File

@@ -1 +1 @@
public/engines/pcre2/pcre2.mjs
public/engines/

View File

@@ -2,6 +2,115 @@
## Unreleased
## 0.4.2 — 2026-07-27
- Move canonical source and package identity from the `zemion` account to the
`lotobo` organization and consume Toolbox SDK 0.2.3 from its new namespace.
- Remove the outer application frame and align the workbench with the shared
`min(100%, 90rem)` Toolbox content width.
- Replace the favicon with a file-style Regex mark derived from the MIT-licensed
OOjs regular-expression icon, retaining its licence and attribution.
- Rebuild the Go WebAssembly engine so its embedded module path uses the new
canonical repository identity.
## 0.4.1 — 2026-07-27
- Keep the last completed syntax and execution frame visible while edited
inputs are parsed and executed, then replace it atomically with the newest
revision instead of rendering transient empty panels.
- Bind every retained result to its exact flavour, options, pattern, flags,
subject, replacement, mode and syntax snapshots. Mark it as stale, disable
execution until current syntax is ready, and suppress stale editor ranges
and cross-panel selection.
## 0.4.0 — 2026-07-27
- Expand the workbench from four to twelve selectable execution profiles:
JavaScript/ECMAScript, standalone PCRE2, PHP, Perl, Python, Ruby, Java, C++,
Go, Rust, .NET and Scala/JVM compatibility.
- Add actual PHP 8.5.8 `preg_*` execution through the self-hosted
`@php-wasm/web-8-5` 3.1.46 runtime. Preserve native UTF-8 byte ranges and
identify PHP's embedded PCRE2 as 10.44, independently of the standalone
PCRE2 10.47 pack.
- Add actual Perl 5.28.1 execution through unmodified WebPerl 0.09-beta assets
as an explicitly legacy beta profile. Pass user values through a fixed
data-only JSON request, stream pre-tokenized bounded replacement output into
a separately verified MEMFS binary file, disable runtime regex evaluation,
reject code assertions and retain the upstream loader's dormant
interoperability `eval` site as a documented CSP caveat.
- Add actual CRuby 4.0.0 `Regexp` execution through a minimal ruby.wasm
2.9.3-2.9.4 pack. Native `String#gsub`/`String#sub` block iteration drives a
fixed byte-bounded CRuby-compatible replacement expander. Use separate
worker-local WASI request/output files and metadata-only inert JSON instead
of output escaping or ruby.wasm's JavaScript-eval object conversion; reject
lossy lone-surrogate requests and pass the strict-CSP browser gate.
- Add Emscripten 6.0.4 libc++ `std::wregex` execution with the modified
ECMAScript default grammar, alternate standard grammars and a build
configured with dynamic execution disabled. Stream a fixed bounded
replacement formatter through the byte cap and verify its grammar against
libc++ at load.
- Add Go 1.26.5 standard-library `regexp` and Rust `regex` crate 1.13.1
execution, preserving their native UTF-8 byte ranges and non-backtracking
semantics. Use bounded streaming replacement expanders that are
differentially checked against `Regexp.ExpandString` and
`Captures::expand`, with predictable base64 output transport. Measure exact
encoded request bytes and reserve native JSON limits for worst-case escaping
so control-heavy inputs retain the documented decoded limits.
- Add .NET 10.0.10 `System.Text.RegularExpressions` in browser WebAssembly,
with invariant-culture execution, native UTF-16 ranges and a bounded native
regex timeout inside the killable worker. Stream bounded replacement tokens
without materializing `Match.Result`, verify token semantics against native
.NET at load, and transport output as bounded base64-encoded UTF-8.
- Add an explicitly labelled Scala/JVM compatibility profile backed by the
verified TeaVM 0.15.0 `java.util.regex` engine. No Scala runtime, Scala
wrapper API or OpenJDK runtime is claimed.
- Add partial application-owned lexical syntax and replacement providers,
flavour-specific quick-reference content and capability labels for the eight
new profiles while keeping each real runtime authoritative.
- Add deterministic, closed-file-set runtime packs, checksums, licences,
notices, exact toolchain/source identities and release verification for the
new self-hosted engines.
- Close the existing Pyodide pack's full base-runtime provenance: exact
primary archive or Git tree identities, vendored JavaScript-port hashes,
CPython/Emscripten patch and recipe hashes, a preferred-form HACL* route,
independently anchored notices, and executable identity checks for the
linked compression/database/parser components.
- Transport bounded Python replacement output as canonical base64 with strict
declared-length, request-cap and UTF-8 validation instead of
content-dependent JSON escaping.
- Close the PHP pack's complete native/source/legal inventory with exact
package, binary, build-recipe, archive and Git identities; independently
pin 38 legal assets; audit linked component versions; and explicitly exclude
the GMP, libsodium, tidy, ICU/intl, FreeType, ImageMagick and adjacent AOM
false-positive or unshipped detections.
- Bound retained heavyweight workers with least-recently-used eviction so
selecting many profiles does not leave every runtime resident.
## 0.3.0 — 2026-07-27
- Add a self-hosted Pyodide 314.0.3 worker containing CPython 3.14.2 `re`, with
runtime identity verification, bounded compilation/matching/replacement and
exact code-point-to-editor-UTF-16 range normalization.
- Add TeaVM 0.15.0's `java.util.regex` class-library implementation as a
verified self-hosted ES module, with bounded `Pattern`/`Matcher` execution,
native replacement and exact UTF-16 ranges.
- Identify the Java engine as TeaVM class-library code rather than OpenJDK and
report its documented `UNICODE_CHARACTER_CLASS`, single-digit replacement
and unavailable named-replacement compatibility boundaries.
- Add partial application-owned Python and Java lexical syntax and replacement
providers while keeping the selected runtime compiler authoritative.
- Separate heavyweight engine loading from the per-request execution deadline,
retain worker recovery after timeout/crash/cancellation and keep every
runtime local to the release.
- Add flavour-specific quick reference and capability content for all four
executable engines.
- Keep comparison, generated cases, code generation, minimization, analysis
and formatting behind their explicitly verified ECMAScript/PCRE2 boundaries;
Python and Java are never routed through another flavour as a fallback.
- Extend deterministic engine-pack provenance, checksums, licence notices,
release verification and nested-path delivery checks to the Python and Java
runtime assets.
## 0.2.0 — 2026-07-27
- Open Quick reference and Capabilities as populated, accessible in-viewport

View File

@@ -0,0 +1,28 @@
OOjs UI regular-expression-progressive icon
Source:
https://commons.wikimedia.org/wiki/File:OOjs_UI_icon_regular-expression-progressive.svg
The icon path is adapted into public/favicon.svg and recoloured. The
surrounding rounded square, document shape, gradient and shadow are original
Regex Tools artwork and are not part of the upstream icon.
Copyright © 20112017 OOjs UI Team and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

229
README.md
View File

@@ -8,16 +8,42 @@ Patterns, replacement templates, test text and project files stay in the
browser. There is no account, backend, upload, remote execution, telemetry,
runtime CDN, remote font, or cloud-save service.
## Current release — 0.2.0
## Current release — 0.4.2
The v0.2.0 release contains two real production engine slices: ECMAScript and
PCRE2 10.47.
The v0.4.2 release contains twelve selectable, executable profiles:
- **JavaScript (ECMAScript)** — the current browser's native `RegExp`, with
ECMAScript 2025 syntax supplied by regexpp 4.12.2;
- **PCRE2** — official standalone PCRE2 10.47 as a self-hosted 8-bit
WebAssembly pack;
- **PHP** — actual PHP 8.5.8 `preg_*` in `@php-wasm/web-8-5` 3.1.46; this
runtime reports PCRE2 10.44 and is deliberately distinct from the standalone
PCRE2 10.47 profile;
- **Perl** — actual Perl 5.28.1 in WebPerl 0.09-beta, prominently identified as
a legacy beta compatibility target rather than current desktop Perl;
- **Python** — CPython 3.14.2 `re` in self-hosted Pyodide 314.0.3;
- **Ruby** — CRuby 4.0.0 `Regexp` in the minimal ruby.wasm
2.9.3-2.9.4 runtime;
- **Java** — TeaVM 0.15.0's `java.util.regex` class-library implementation;
- **C++** — Emscripten 6.0.4 libc++ `std::wregex`, using the C++ modified
ECMAScript grammar by default and exposing the standard alternate grammar
choices;
- **Go** — Go 1.26.5 standard-library `regexp` with RE2 syntax;
- **Rust** — the Rust `regex` crate 1.13.1, built with rustc 1.97.1;
- **.NET** — .NET 10.0.10 `System.Text.RegularExpressions` in browser
WebAssembly with invariant-culture execution; and
- **Scala compatibility** — Scala/JVM regex syntax and replacement semantics
through the same TeaVM `java.util.regex` engine as the Java profile. No Scala
runtime or Scala `Regex` wrapper API is shipped.
Every profile executes the named runtime. Java is TeaVM class-library code,
not OpenJDK. Scala is an explicitly labelled Java-compatibility profile, not a
relabeled Scala engine.
- Syntax acceptance: `@eslint-community/regexpp` 4.12.2, ECMAScript 2025
grammar; application-owned structural explanations are partial and
feature-matrix tested.
- Execution engine: the current browser's native ECMAScript `RegExp`.
- Native and editor offsets: UTF-16 code units.
- ECMAScript native and editor offsets are UTF-16 code units.
- PCRE2 execution and substitution: pinned official PCRE2 10.47 compiled to a
self-hosted 8-bit WebAssembly pack with UTF/UCP always enabled.
- PCRE2 native UTF-8 byte ranges are retained and normalized to exact editor
@@ -26,10 +52,58 @@ PCRE2 10.47.
- PCRE2 automatic callouts are copied through a separate ABI operation and
displayed from a dedicated killable trace worker under 50,000-event and
10 MiB serialized-data hard caps.
- PHP compilation and match selection use actual `preg_match()` in PHP 8.5.8.
A fixed byte-bounded expander reproduces PHP replacement tokens and is
checked against native `preg_replace()` at load. PHP returns native UTF-8
byte ranges and reports its own PCRE2 10.44 identity.
- The legacy Perl bridge passes user values as JSON data to fixed application
code, disables runtime regex evaluation, rejects code assertions and exposes
a pre-tokenized, deliberately bounded replacement grammar. Replacement bytes
stream from native spans to a separate fixed MEMFS file instead of being
materialized or JSON-escaped; the worker validates the exact bounded UTF-8
file before returning it. Its prebuilt WebPerl loader has a dormant optional
interoperability `eval` site; the fixed engine path is verified without broad
CSP `'unsafe-eval'`.
- Python compilation, matching and replacement use the bundled CPython `re`
module. Native code-point ranges are retained and normalized to exact editor
UTF-16 ranges. Bounded replacement UTF-8 crosses the JSON bridge as canonical
base64; the adapter validates the declared byte count, cap and UTF-8 before
exposing output.
- Ruby compilation and matching use CRuby's `Regexp`; native `String#gsub`
and `String#sub` block iteration drives replacement matching, while a fixed
byte-bounded implementation of CRuby 4.0.0's `rb_reg_regsub` template
grammar produces the output prefix. Native character ranges are retained as
Unicode code-point offsets. Requests and replacement output use separate
bounded files in the worker-local WASI memory filesystem; only bounded
metadata returns as inert JSON, avoiding both output escaping amplification
and ruby.wasm's JavaScript-eval conversion path.
- Java compilation, matching and replacement use TeaVM's
`java.util.regex.Pattern` and `Matcher`. Native ranges are UTF-16 code units.
- TeaVM 0.15.0 replacement supports its actual single-digit `$n` subset.
`$12` is therefore `$1` followed by literal `2`; Java SE `${name}`
replacement is reported as unavailable rather than presented as OpenJDK
behavior.
- C++ compilation and matching use libc++ `std::wregex`; a fixed byte-bounded
formatter reproduces `match.format` grammar and checks parity with that
native API at load. Its 32-bit `wchar_t` ranges are Unicode code points.
- Go and Rust return native UTF-8 byte offsets from their real runtimes. Their
fixed bounded expanders are parity-checked against `Regexp.ExpandString` and
`Captures::expand`, then return output through predictable base64 envelopes.
Their adapters measure exact encoded request bytes, and their native JSON
caps cover worst-case escaping for every accepted input field.
- .NET returns native UTF-16 offsets and executes with a bounded native regex
timeout in addition to the killable worker boundary.
- Python, Java and all eight v0.4.0 community additions use deliberately
partial application-owned lexical syntax providers; their actual runtime
compiler remains authoritative.
- Parsing and execution run in separate workers.
- Actual execution can be terminated by killing its worker.
- The worker is recreated after timeout, crash or cancellation.
- Capture ranges use the engine's `d` indices result.
- Live editing retains the last completed, input-bound syntax and result frame
until the newest revision finishes. Stale frames are labelled and cannot
enable Run, decorate current editors, or drive current-input selections.
- ECMAScript capture ranges use the engine's `d` indices result; every other
profile returns its native range records through a bounded fixed bridge.
- Named, numbered, optional, empty and repeated-final captures are represented.
- Match, replacement, typed list/extraction, corpus/apply and unit-test modes
are available.
@@ -73,7 +147,10 @@ as a complete record of every internal engine action.
## Workbench modes
- **Match** — live highlighting, extraction tree and bounded capture table.
- **Replace** — engine-native bounded substitution for ECMAScript and PCRE2;
- **Replace** — bounded profile-authoritative substitution for all twelve
executable profiles; the legacy Perl profile uses its documented fixed
non-executable template grammar, and profiles that use fixed bounded
expanders identify and parity-check them against their named runtime;
output completeness is reported separately from bounded per-match
original/result, changed-range and token-contribution previews that
synchronize the replacement, pattern, subject and output editors.
@@ -118,13 +195,16 @@ unit test and explicit confirmation; see
## Flags and iteration
Pattern and flags are stored separately; delimiters are presentation only.
ECMAScript preserves native `g` and `y`; PCRE2 offers the application-level
`g` iteration flag plus `i`, `m`, `s`, `x`, `U` and `J`. PCRE2 UTF/UCP mode is
mandatory because browser strings are Unicode and partial-byte ranges cannot be
represented safely in the editor. The optional **Scan all** action adds only an
internal iteration flag to that request and does not change saved flags.
ECMAScript may add internal `d` to obtain exact indices without changing match
semantics.
Each profile exposes only its reviewed allowlist, and application-level `g`
means bounded iteration where the underlying API has no compile-time global
flag. PHP delimiters/modifiers, Go and Rust inline options, C++ grammar
selection, .NET options and the legacy Perl character-set modes are mapped by
their own adapters rather than reused across profiles. Standalone PCRE2 always
uses UTF/UCP; PHP controls UTF through its exposed `u` modifier and reports its
own PCRE2 version. The optional **Scan all** action adds only an internal
iteration request and does not change saved flags. ECMAScript may add internal
`d` to obtain exact indices without changing match semantics. The exact flag
matrix is in [`docs/FLAVOUR_SUPPORT.md`](docs/FLAVOUR_SUPPORT.md).
Zero-length global iteration advances using the selected Unicode semantics and
cannot loop forever.
@@ -247,6 +327,24 @@ npm run engines:verify
npm run engines:pcre2:build -- --source-dir /path/to/pcre2 --emcc /path/to/emcc
npm run engines:pcre2:verify
npm run engines:pcre2:install
node scripts/python-engine-pack.mjs node_modules/pyodide .engine-build/python
node scripts/install-python-engine.mjs .engine-build/python
node scripts/java-engine-pack.mjs
node scripts/install-java-engine.mjs
node scripts/php-engine-pack.mjs
node scripts/install-php-engine.mjs
node scripts/perl-engine-pack.mjs --archive /path/to/webperl_prebuilt_v0.09-beta.zip
node scripts/install-perl-engine.mjs
node scripts/ruby-engine-pack.mjs
node scripts/install-ruby-engine.mjs
node scripts/cpp-engine-pack.mjs --empp /path/to/em++
node scripts/install-cpp-engine.mjs
node scripts/build-go-engine.mjs /path/to/go
node scripts/install-go-engine.mjs
node scripts/build-rust-engine.mjs /path/to/rust-toolchain
node scripts/install-rust-engine.mjs
node scripts/dotnet-engine-pack.mjs --dotnet /path/to/dotnet
node scripts/install-dotnet-engine.mjs
npm run build
npm run toolbox:check
npm run check
@@ -258,7 +356,7 @@ The normal build performs no network download. `vite.config.ts` uses
## Toolbox SDK and Portal
The application uses Toolbox SDK 0.2.2 `AppShell`. Its canonical typed/static
The application uses Toolbox SDK 0.2.3 `AppShell`. Its canonical typed/static
manifest source is `src/toolbox/manifest.source.json`; generation fails if its
version or source identity drifts.
@@ -266,18 +364,54 @@ The deterministic release ZIP can be consumed by Toolbox Portal using an exact
artifact URL, manifest ID, version and SHA-256. Portal builds consume the
artifact; they do not build Regex Tools source.
The PCRE2 worker loads self-hosted JavaScript and WebAssembly only. Deployment
must serve `.wasm` as `application/wasm` and allow WebAssembly compilation in
`script-src`; see [`docs/PORTAL_REQUIREMENTS.md`](docs/PORTAL_REQUIREMENTS.md).
All runtime assets are self-hosted below the release path. Deployment must
serve `.wasm` as `application/wasm`, serve module/worker files with a
JavaScript MIME type and allow WebAssembly compilation in `script-src`; see
[`docs/PORTAL_REQUIREMENTS.md`](docs/PORTAL_REQUIREMENTS.md).
## Flavour roadmap
## Flavour support and boundaries
PCRE2 10.47 is the second implemented flavour. Its application-owned ABI
provides bounded compilation, matching, native substitution and separate
automatic-callout tracing, copied caller-owned records, deterministic
allocation cleanup and explicit result completeness. The exact
source/toolchain build is reproducible offline and the verified pack is bundled
with its metadata, checksums and licence.
PCRE2's application-owned ABI provides bounded compilation, matching, native
substitution and separate automatic-callout tracing, copied caller-owned
records, deterministic allocation cleanup and explicit result completeness.
The exact source/toolchain build is reproducible offline and the verified pack
is bundled with its metadata, checksums and licence.
The Python slice executes actual CPython 3.14.2 `re` in Pyodide 314.0.3; it does
not translate a Python pattern into ECMAScript. Pyodide startup is a separate
worker-load operation and is excluded from the normal execution deadline.
Its checked-in pack contains a machine-verified `SOURCE-MANIFEST.json` with the
complete base-runtime inventory, primary source hashes or immutable Git trees,
the vendored Error Stack Parser and StackFrame source ports, all Pyodide
CPython/Emscripten patches and an independently anchored legal file for every
component. Optional wheels named by Pyodide's package catalogue are not
shipped.
PHP executes actual PHP 8.5.8 `preg_*`; the embedded PHP runtime reports PCRE2
10.44. Selecting PHP therefore does not execute the separately built PCRE2
10.47 pack. Perl executes the unmodified WebPerl 0.09-beta runtime containing
Perl 5.28.1 and is kept visibly legacy because that upstream beta was released
in 2019.
Ruby, C++, Go, Rust and .NET execute their named WebAssembly runtimes. Their
native range units are preserved and normalized at checked boundaries. The
C++ profile defaults to libc++'s modified ECMAScript grammar; its checked-in
source manifest binds the exact module to the traced Emscripten runtime, musl,
emmalloc, compiler-rt, libc++ and libc++abi inputs and records libunwind as an
audited non-selection. Go and Rust provide non-backtracking engines that
deliberately exclude look-around and backreferences; .NET uses
`System.Text.RegularExpressions` 10.0.10 with invariant culture.
The Java slice executes TeaVM 0.15.0's own `java.util.regex` class library. It
does not translate a Java pattern into ECMAScript, but it is also not OpenJDK:
in particular, TeaVM 0.15.0 does not implement
`Pattern.UNICODE_CHARACTER_CLASS`. The UI reports the `U` flag as a
compatibility request and preserves TeaVM's predefined-class and word-boundary
behaviour.
Scala reuses that exact TeaVM engine as a clearly named Scala/JVM compatibility
profile. It does not ship or claim Scala compiler/runtime, `scala.util.matching`
wrapper behavior or OpenJDK parity.
Generated-case version 1 is ECMAScript-only. It traverses the complete
application-owned ECMAScript AST under node, depth, attempt, byte, repetition
@@ -286,17 +420,19 @@ browser `RegExp` adapter. PCRE2 generation remains unavailable until its syntax
provider can expose a complete normalized tree.
Pattern formatting is likewise ECMAScript-only. It consumes the complete
regexpp token model and does not reinterpret the partial PCRE2 structure.
PCRE2 formatting remains unavailable until a complete grammar-backed
implementation passes equivalent idempotence, reparse, engine and test gates.
regexpp token model and does not reinterpret any partial lexical structure.
Other profiles remain unavailable until complete grammar-backed
implementations pass equivalent idempotence, reparse, engine and test gates.
The first advertised generated-code target is the PCRE2 10.47 8-bit C API.
Its deterministic match and replacement fixtures compile and execute against
the exact official release. See
[`docs/COMPARISON_AND_CODEGEN.md`](docs/COMPARISON_AND_CODEGEN.md).
Python, Go, Rust, .NET, Java and legacy PCRE follow only through their actual
named runtimes. No flavour is emulated through JavaScript and relabelled.
No profile is emulated through JavaScript and relabelled. The sole shared
runtime is explicit: Scala compatibility intentionally delegates to the
verified TeaVM Java engine and labels that boundary in the selector and result
identity.
## Licensing
@@ -305,10 +441,15 @@ Degering. Shipped dependencies retain their own compatible licences and
notices; see [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) and
[`LICENSES/`](LICENSES/).
The PHP 8.5.8 codebase is distributed under the elected PHP License version 4
(`BSD-3-Clause`) option, while WordPress Playground's `@php-wasm` packages
retain their separate GPL-2.0-or-later notice. Each runtime pack contains the
exact applicable licence and notice material recorded in its metadata.
No regex101 application source, branding, generated explanation prose,
reference text or visual design is copied. RegexLib and RGXP.RU fixtures are not
redistributed because a suitable fixture licence was not established. No
RegexHub fixture is shipped in v0.2.0.
RegexHub fixture is shipped in v0.4.0.
## Known limitations
@@ -332,6 +473,20 @@ RegexHub fixture is shipped in v0.2.0.
recognizes common capture forms and PCRE2-only constructs for reference, but
the actual PCRE2 compiler is authoritative. Branch-reset capture numbering is
omitted from the explanation rather than guessed.
- Python, Java, PHP, Perl, Ruby, C++, Go, Rust, .NET and Scala compatibility
structural explanations are deliberately partial lexical models. The
selected runtime remains authoritative for compilation, group count and
matching.
- Python, Ruby, C++ and Perl report Unicode code-point offsets; Java, Scala,
.NET and ECMAScript report UTF-16 offsets; standalone PCRE2, PHP, Go and Rust
report UTF-8 bytes. Every range is checked before conversion and its native
unit remains visible.
- TeaVM `java.util.regex` is not OpenJDK. Its `U` compatibility request does
not add OpenJDK's `UNICODE_CHARACTER_CLASS` semantics; the same boundary
applies to the Scala compatibility profile.
- WebPerl 0.09-beta and Perl 5.28.1 are intentionally legacy. The shipped
upstream loader contains a dormant optional JavaScript-interoperability
`eval` site, although the fixed bridge does not import or invoke it.
- Capture-table rendering is paged at 200 rows while aggregate collection is
bounded separately.
- Explanation/extraction trees and editor decorations show bounded 2,000-node
@@ -341,10 +496,11 @@ RegexHub fixture is shipped in v0.2.0.
at most 512. UI-only shortening shows the exact range length; engine-clipped
values are labelled as prefixes of that range. Copy and eligible JSON export
continue to use the separately bounded engine value.
- Replacement parsing is complete below its 64 Ki input limit, while editor
marks, token rows and diagnostics have explicit presentation caps. List token
chips are similarly bounded, and list rendering stops at 250,000 token
evaluations.
- Replacement parsing is complete only for the providers that advertise that
coverage; the v0.4.0 community providers label their lexical replacement
models as partial and defer semantics to the runtime. Editor marks, token
rows and diagnostics have explicit presentation caps. List token chips are
similarly bounded, and list rendering stops at 250,000 token evaluations.
- Per-match replacement presentation renders at most 200 matches and 2,000
token contributions under a 50,000 token-evaluation budget. Bounded
replacement output remains available separately and is labelled partial if
@@ -366,6 +522,9 @@ RegexHub fixture is shipped in v0.2.0.
- Pattern formatting is intentionally narrow and ECMAScript-only. Its bounded
source/candidate and unit-test validation is evidence for the checked
snapshots, not a proof of equivalence over all subjects.
- Cross-flavour comparison, PCRE2 C generation and subject minimization remain
scoped to their explicitly supported ECMAScript/PCRE2 paths; selecting any
other profile does not silently substitute one of those engines.
Architecture, security, performance, provenance and flavour details live in
[`docs/`](docs/).

View File

@@ -1,10 +1,10 @@
# Source identity
- Project: Regex Tools
- Release version: `0.2.0`
- Release tag: `v0.2.0`
- Repository: <https://git.add-ideas.de/zemion/regex-tools>
- Previous release tag: `v0.1.0`
- Release version: `0.4.2`
- Release tag: `v0.4.2`
- Repository: <https://git.add-ideas.de/lotobo/regex-tools>
- Previous release tag: `v0.4.1`
- Licence: GPL-3.0-or-later
- Copyright: © 2026 Albrecht Degering
@@ -20,14 +20,75 @@ runtime or build-time CDN fetch. Complete preferred-form source is the tagged
repository. The release archive contains compiled static assets plus legal,
source-identity and attribution documents.
The explicit offline PCRE2 build is documented in `docs/ENGINE_BUILDS.md`.
PCRE2 source is not vendored: the gate accepts only the pinned, clean official
10.47 checkout and Emscripten 6.0.4 compiler. Generated staging is ignored; the
verified runtime files, deterministic metadata, checksums and exact licence are
installed under `public/engines/pcre2/` and included in the application source
and build.
The engine-pack inputs and rebuild gates are documented in
`docs/ENGINE_BUILDS.md`.
The v0.2.0 release includes PCRE2. Python, Go, Rust, .NET, Java and legacy PCRE
remain unimplemented. The v0.1.0 release remains available under its historical
tag and artifact coordinates. A future public artifact must bump package,
manifest, tag and source identity together; it must not reuse `v0.2.0`.
- PCRE2 source is not vendored: the gate accepts only the pinned, clean
official 10.47 checkout and Emscripten 6.0.4 compiler.
- The Python pack is copied from the exact pinned Pyodide 314.0.3 npm package
and contains its CPython 3.14.2 runtime, Python standard library, loader,
WebAssembly module, metadata, checksums and licence material.
`SOURCE-MANIFEST.json` closes the base-runtime inventory with exact archive
hashes or Git commit/tree identities for Pyodide, pyodide-build, the
vendored Error Stack Parser and StackFrame ports, CPython, libffi, Hiwire,
liblzma, Zstandard, SQLite, bzip2, zlib, Emscripten and HACL*. It also pins
every Pyodide CPython/Emscripten patch and build recipe, documents the one
Regex Tools loader transformation, and maps each linked component to
independently anchored legal text.
- The Java bridge source is under `engines/java/`. Its bundled module is
compiled against TeaVM 0.15.0's `java.util.regex` class library and is
identified as TeaVM rather than OpenJDK.
- The PHP bridge source is under `engines/php/`. The runtime pack comes from
the pinned `@php-wasm/web-8-5` and support packages at 3.1.46, executes PHP
8.5.8, and reports its embedded PCRE2 as 10.44. This identity is separate
from the standalone PCRE2 10.47 pack. Its `native-components.json` binds the
exact WebAssembly to the WordPress Playground/PHP/Emscripten commits,
inventories all 32 linked native/source surfaces, records exact archive or
Git routes and explicitly bounds the upstream recipe's one unpinned
Oniguruma clone. Every linked component maps to independently pinned legal
text; runtime and binary audits distinguish GMP, libsodium, tidy, ICU/intl,
FreeType, ImageMagick and the adjacent AOM 3.13.1 recipe from what is
actually linked.
- The Perl bridge source is under `engines/perl/`. The byte-for-byte WebPerl
0.09-beta prebuilt archive contains Perl 5.28.1 and Emscripten 1.38.28
output. It is shipped only as a visibly legacy beta target; user values cross
a fixed data-only bridge.
- The Ruby pack comes from the pinned minimal `@ruby/4.0-wasm-wasi` and
`@ruby/wasm-wasi` packages at 2.9.3-2.9.4 and executes CRuby 4.0.0. The
application bridge under `engines/ruby/` uses bounded length-prefixed
worker-local WASI file input and inert JSON output instead of ruby.wasm's
JavaScript-eval object-conversion path.
- The C++ bridge source is under `engines/cpp/`. Emscripten 6.0.4 compiles it
against libc++ `std::wregex` with dynamic JavaScript execution disabled. Its
`SOURCE-MANIFEST.json` pins the Emscripten, emsdk and LLVM identities and
maps the exact traced musl, emmalloc, compiler-rt, libc++ and libc++abi link
inputs to preferred-source paths and legal files. libunwind is retained as
an explicit audited exclusion because the selected JavaScript-exception
build links no `libunwind.a` member.
- The Go bridge source is under `engines/go/`. The official Go 1.26.5
linux/amd64 distribution cross-compiles standard-library `regexp` for
`js/wasm`.
- The Rust bridge source and exact Cargo lock are under `engines/rust/`.
rustc 1.97.1 and wasm-bindgen 0.2.126 compile `regex` crate 1.13.1 for
`wasm32-unknown-unknown`.
- The .NET bridge source is under `engines/dotnet/`. .NET SDK 10.0.302 with
runtime 10.0.10 and its `wasm-tools` workload publishes the
`System.Text.RegularExpressions` browser-WASM pack.
- Scala compatibility has no additional engine pack. It deliberately uses the
verified TeaVM Java pack and labels that shared runtime in every result.
Generated staging is ignored. Only verified runtime packs with deterministic
metadata, closed file sets, checksums and exact licence/notice material are
installed under `public/engines/` and included in the application source and
build.
The v0.4.2 release includes native browser ECMAScript, standalone PCRE2 10.47,
PHP 8.5.8 `preg` with PCRE2 10.44, legacy Perl 5.28.1 via WebPerl 0.09-beta,
CPython 3.14.2 `re`, CRuby 4.0.0 `Regexp`, TeaVM 0.15.0 `java.util.regex`,
Emscripten 6.0.4 libc++ `std::wregex`, Go 1.26.5 `regexp`, Rust `regex` 1.13.1,
.NET 10.0.10 `System.Text.RegularExpressions`, and the explicitly shared
TeaVM-backed Scala/JVM compatibility profile.
Earlier releases remain available under their historical tags and artifact
coordinates. A future public artifact must bump package, manifest, tag and
source identity together; it must not reuse `v0.4.2`.

View File

@@ -4,28 +4,75 @@ Regex Tools original source is GPL-3.0-or-later. The production browser bundle
contains the compatible runtime components below.
Exact dependency resolution is recorded in `package-lock.json`.
| Component | Version | Licence | Shipped | Role and source |
| -------------------------------- | ------------------------------------------------------------------------ | --------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------- |
| `@add-ideas/toolbox-contract` | 0.2.2 | Apache-2.0 | Runtime | Manifest contract; <https://git.add-ideas.de/zemion/toolbox-sdk> |
| `@add-ideas/toolbox-shell-react` | 0.2.2 | Apache-2.0 | Runtime | Shared shell; same source |
| `@eslint-community/regexpp` | 4.12.2 | MIT | Syntax worker | ECMAScript parser; <https://github.com/eslint-community/regexpp> |
| CodeMirror packages | state 6.7.1; view 6.43.6; language 6.12.4; commands 6.10.4; search 6.7.1 | MIT | Runtime | Editors; <https://github.com/codemirror> |
| `@lezer/highlight` | 1.2.3 | MIT | Runtime | Editor highlighting support; <https://github.com/lezer-parser/highlight> |
| React / React DOM | 19.2.7 | MIT | Runtime | User interface; <https://github.com/facebook/react> |
| `fflate` | 0.8.3 | MIT | Runtime and build dependency | Local corpus-output ZIP and deterministic release ZIP; <https://github.com/101arrowz/fflate> |
| Emscripten generated runtime | 6.0.4 | MIT | Generated WebAssembly glue | PCRE2 module loader/runtime; <https://github.com/emscripten-core/emscripten> |
| PCRE2 | 10.47 | BSD-3-Clause WITH PCRE2-exception | WebAssembly runtime | Pinned official 8-bit engine; <https://github.com/PCRE2Project/pcre2> |
| Vite | 8.1.5 | MIT | Generated helpers | Production build; <https://github.com/vitejs/vite> |
| Rolldown | 1.1.5 | MIT | Generated helpers | Production bundling; <https://github.com/rolldown/rolldown> |
| Component | Version | Licence | Shipped | Role and source |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `@add-ideas/toolbox-contract` | 0.2.3 | Apache-2.0 | Runtime | Manifest contract; <https://git.add-ideas.de/lotobo/toolbox-sdk> |
| `@add-ideas/toolbox-shell-react` | 0.2.3 | Apache-2.0 | Runtime | Shared shell; same source |
| `@eslint-community/regexpp` | 4.12.2 | MIT | Syntax worker | ECMAScript parser; <https://github.com/eslint-community/regexpp> |
| CodeMirror packages | state 6.7.1; view 6.43.6; language 6.12.4; commands 6.10.4; search 6.7.1 | MIT | Runtime | Editors; <https://github.com/codemirror> |
| `@lezer/highlight` | 1.2.3 | MIT | Runtime | Editor highlighting support; <https://github.com/lezer-parser/highlight> |
| React / React DOM | 19.2.7 | MIT | Runtime | User interface; <https://github.com/facebook/react> |
| `fflate` | 0.8.3 | MIT | Runtime and build dependency | Local corpus-output ZIP and deterministic release ZIP; <https://github.com/101arrowz/fflate> |
| Emscripten generated runtime | 6.0.4 | MIT OR NCSA | Generated WebAssembly glue | Standalone PCRE2 and C++ module toolchain; <https://github.com/emscripten-core/emscripten> |
| PCRE2 | 10.47 | BSD-3-Clause WITH PCRE2-exception | WebAssembly runtime | Pinned official 8-bit engine; <https://github.com/PCRE2Project/pcre2> |
| PHP | 8.5.8 | PHP License 4 (BSD-3-Clause) | PHP runtime | `preg_*` execution; v4 elected through the earlier licence's later-version option; <https://www.php.net/> |
| PCRE2 in PHP | 10.44 | PCRE2 BSD licence | PHP runtime | Engine embedded in the PHP build; distinct from standalone PCRE2 10.47 |
| WordPress Playground `@php-wasm` | 3.1.46 | GPL-2.0-or-later | PHP runtime/host packages | `web-8-5`, `universal` and pinned support packages; <https://github.com/WordPress/wordpress-playground> |
| Zend Engine and PHP bundled code | PHP 8.5.8 | Zend Engine License 2.00; MIT; public-domain/CC0 and component terms | PHP WebAssembly | Exact Zend, official `README.REDIST.BINS`, CLI HTTP parser and hash-code notices travel with the pack |
| PHP-vendored support code | bcmath snapshot; timelib 2022.15; tzdata 2026.1; libmagic snapshot; Lexbor 2.7.0; libmbfl 1.3.2; uriparser 1.0.2; libavifinfo snapshot | LGPL-2.0-or-later; MIT; public domain; BSD; Apache-2.0; LGPL-2.1; BSD and AOM patent terms | PHP WebAssembly | Exact php-src 8.5.8 component paths and legal routes are recorded in the native inventory |
| PHP data/archive/image libraries | zlib 1.2.13; libzip 1.9.2; libxml2 2.9.10; SQLite 3.51.0; libgd 2.3.3 | Zlib; BSD-3-Clause; MIT; public domain; BSD-like | PHP WebAssembly | Exact primary archive hashes/commits and separately pinned legal files |
| PHP image codec libraries | libjpeg-turbo 3.0.3; libpng 1.6.39; libwebp/libsharpyuv pinned commit; libavif 1.3.0; libaom 3.12.1 with libyuv snapshot | IJG/BSD/Zlib; Libpng; BSD/patent grants; BSD-2-Clause/AOM patent terms | PHP WebAssembly | libavif's local AOM 3.12.1 is linked; the adjacent standalone AOM 3.13.1 recipe is not |
| PHP network/text libraries | OpenSSL 1.1.1t; curl 7.69.1; libiconv 1.17; Oniguruma 6.9.10 | OpenSSL/SSLeay; curl; LGPL-2.1-or-later; BSD-2-Clause | PHP WebAssembly | Oniguruma's exact archive/header and bounded upstream source interval are recorded without claiming an unpinned build HEAD |
| Emscripten system code in PHP | main linker 4.0.19; musl, compiler-rt, libc++, libc++abi and dlmalloc snapshots | MIT/NCSA; MIT/component terms; Apache-2.0 WITH LLVM-exception plus legacy terms; public domain | PHP WebAssembly | Exact Emscripten commit and independently pinned component legal files |
| WebPerl / Perl | 0.09-beta / 5.28.1 | GPL-1.0-or-later OR Artistic-1.0-Perl | Legacy Perl runtime | Unmodified, explicitly legacy prebuilt engine; <https://github.com/haukex/webperl> |
| Emscripten used by WebPerl | 1.38.28 | MIT OR NCSA | Legacy Perl loader/runtime | Exact upstream-generated asset toolchain |
| Pyodide | 314.0.3 | MPL-2.0 | Python runtime pack | Self-hosted CPython browser runtime; <https://github.com/pyodide/pyodide> |
| Error Stack Parser / StackFrame | 2.1.4 / 1.3.4 vendored ports | MIT | Python loader | Exact upstream tags/archives and Pyodide port-source hashes are recorded |
| CPython | 3.14.2 | Python-2.0 and bundled terms | Python runtime/stdlib | `re` execution and bundled standard library; <https://github.com/python/cpython> |
| Expat / libmpdec / HACL* | 2.7.3 / 2.5.1 / pinned HACL commit | MIT / BSD-2-Clause / MIT | Python base WebAssembly | CPython-vendored static components; exact preferred HACL source and generated-source route are recorded |
| libffi / Hiwire | pinned commit / 1.0.1 | MIT / MPL-2.0 | Python base WebAssembly | Pyodide's exact `_ctypes` and JavaScript-reference bridge inputs |
| XZ liblzma / Zstandard | 5.2.2 / 1.5.7 | Public-domain fallback grant / BSD-3-Clause | Python base WebAssembly | Static compression modules from Pyodide's pinned primary source archives |
| SQLite | 3.39.0 | Public-domain dedication/blessing | Python base WebAssembly | Static `_sqlite3` from the pinned official amalgamation archive |
| bzip2 / zlib | 1.0.6 / 1.3.1 | bzip2-1.0.6 / Zlib | Python base WebAssembly | Exact Emscripten 5.0.3 ports selected by Pyodide |
| Emscripten used by Pyodide | 5.0.3 plus five pinned Pyodide patches | MIT OR NCSA | Python loader/WebAssembly | Exact toolchain source tree, patches and recipe hashes |
| Emscripten system runtime | snapshot in 5.0.3 | MIT and Apache-2.0 WITH LLVM-exception | Python base WebAssembly | musl, compiler-rt, libc++, libc++abi, libunwind and dlmalloc conservative notice closure |
| MiniLZ4 | snapshot in Emscripten 5.0.3 | MIT | Python loader | Selected by Pyodide's `-sLZ4=1`; its source notice is restored outside the minified loader |
| ruby.wasm / CRuby | 2.9.3-2.9.4 / 4.0.0 | MIT host; Ruby/BSD and bundled terms | Ruby runtime | Minimal CRuby WebAssembly pack and complete upstream NOTICE; <https://github.com/ruby/ruby.wasm> |
| TeaVM | 0.15.0 | Apache-2.0 | Generated Java engine module | `java.util.regex` class-library implementation; <https://github.com/konsoletyper/teavm> |
| Emscripten system code in C++ | Emscripten 6.0.4; musl 1.2.6; compiler-rt 22.1.8; libc++/libc++abi 21.1.8; emmalloc snapshot | MIT/NCSA; MIT/component terms; Apache-2.0 WITH LLVM-exception plus legacy terms | C++ WebAssembly | Exact traced link and preferred-source/legal closure; libunwind 22.1.8 is retained as an audited non-selection |
| Go | 1.26.5 | BSD-3-Clause | Go runtime/engine | Standard-library `regexp` and official `js/wasm` support; <https://go.dev/> |
| Rust `regex` / toolchain | regex 1.13.1 / rustc 1.97.1 | MIT OR Apache-2.0 plus component terms | Rust runtime/engine | Exact Cargo graph, standard library and wasm-bindgen notices travel with the pack |
| .NET | runtime 10.0.10 / SDK 10.0.302 | MIT plus bundled component terms | .NET runtime/engine | Browser-WASM `System.Text.RegularExpressions`; <https://github.com/dotnet/runtime> |
| Vite | 8.1.5 | MIT | Generated helpers | Production build; <https://github.com/vitejs/vite> |
| Rolldown | 1.1.5 | MIT | Generated helpers | Production bundling; <https://github.com/rolldown/rolldown> |
`@add-ideas/toolbox-testkit` 0.2.2 and the other test/build dependencies are
The application icon adapts and recolours the MIT-licensed
[OOjs UI regular-expression-progressive icon](https://commons.wikimedia.org/wiki/File:OOjs_UI_icon_regular-expression-progressive.svg)
inside original Regex Tools file artwork. Its copyright notice, source and
licence are preserved in `LICENSES/OOjs-UI-icon-MIT.txt`.
`@add-ideas/toolbox-testkit` 0.2.3 and the other test/build dependencies are
development-only and are not part of the static runtime bundle.
The PHP pack's `native-components.json` is scoped to the exact
`php.wasm` SHA-256 and routes every linked component above to one or more of 42
independently verifier-pinned licence, notice or patent files. It separately
records and tests the false-positive/unshipped detections for GMP, libsodium,
tidy, ICU/intl, FreeType, ImageMagick/imagick and AOM 3.13.1.
`recheck` 4.5.0 and `regexp-ast-analysis` 0.7.1 were inspected but deliberately
not installed or shipped. PCRE2 source is not vendored; its generated
WebAssembly pack is shipped with exact metadata, checksums and licence.
WebAssembly pack is shipped with exact metadata, checksums and licence. Pyodide,
PHP WebAssembly and ruby.wasm are pinned npm build inputs whose reviewed
self-hosted files are copied into engine packs. The Python pack's
`SOURCE-MANIFEST.json` distinguishes the optional wheel catalogue from files
actually shipped, inventories the complete linked base runtime and provides
exact preferred-form/archive/Git/patch identities. The TeaVM module contains
its compiled class library and is explicitly identified as TeaVM, not OpenJDK;
the Scala compatibility profile shares it and ships no Scala runtime.
Corresponding licence texts and copyright notices are in `LICENSES/`. The
release package additionally carries the exact Vite and Rolldown legal files
under `LICENSES/build/`, including Vite's bundled-dependency notices for code
emitted by the production build.
Licence texts and copyright notices for the ordinary bundled dependencies are
in `LICENSES/`. Each engine pack carries its exact upstream licence/notice
files alongside the runtime. The release package additionally carries the exact
Vite and Rolldown legal files under `LICENSES/build/`, including Vite's
bundled-dependency notices for code emitted by the production build.

View File

@@ -3,7 +3,7 @@
Regex Tools provides one deliberately scoped analysis implementation:
ECMAScript 2025 patterns parsed into the application-owned normalized AST and
executed by the browser's native `RegExp` runtime. The analyser does not apply
ECMAScript findings to PCRE2 or any other flavour.
ECMAScript findings to PCRE2, Python, Java or any other flavour.
Analysis is advisory. The UI uses “potential risk”, “possibly” and “observed
under selected limits”. It never turns an empty finding list into “safe”,

View File

@@ -7,11 +7,24 @@ boundaries.
React workbench
├─ Pattern SyntaxSupervisor → syntax.worker
│ ├─ Regexpp ECMAScript provider → normalized AST
─ PCRE2 lexical provider → partial normalized structure
─ PCRE2 lexical provider → partial normalized structure
│ ├─ Python lexical provider → partial normalized structure
│ ├─ Java lexical provider → partial normalized structure
│ └─ PHP/Perl/Ruby/C++/Go/Rust/.NET/Scala lexical providers → partial structures
├─ Replacement SyntaxSupervisor → syntax.worker → typed replacement tokens
├─ EngineSupervisor
│ ├─ ecmascript.worker → native RegExp → match DTOs
─ pcre2.worker → PCRE2 10.47 WASM ABI → match DTOs
─ pcre2.worker → PCRE2 10.47 WASM ABI → match DTOs
│ ├─ php.worker → PHP 8.5.8 preg / PCRE2 10.44 → match DTOs
│ ├─ perl.worker → legacy WebPerl 0.09-beta / Perl 5.28.1 → match DTOs
│ ├─ python.worker → Pyodide 314.0.3 → CPython 3.14.2 re → match DTOs
│ ├─ ruby.worker → ruby.wasm → CRuby 4.0.0 Regexp → match DTOs
│ ├─ java.worker → TeaVM 0.15.0 java.util.regex module → match DTOs
│ ├─ cpp.worker → Emscripten 6.0.4 libc++ std::wregex → match DTOs
│ ├─ go.worker → Go 1.26.5 standard-library regexp → match DTOs
│ ├─ rust.worker → Rust regex crate 1.13.1 → match DTOs
│ ├─ dotnet.worker → .NET 10.0.10 System.Text.RegularExpressions → match DTOs
│ └─ scala.worker → explicit compatibility adapter → TeaVM Java module
├─ Pcre2TraceSupervisor → pcre2-trace.worker
│ └─ separate ABI-v3 PCRE2_AUTO_CALLOUT operation → bounded trace DTOs
├─ AnalysisPanel
@@ -42,7 +55,37 @@ provenance. React never imports or traverses regexpp's cyclic AST.
Every engine request carries a protocol version, monotonically increasing
request ID and worker generation. A supervisor allows one active request,
rejects stale responses, terminates on timeout/crash/cancel, and lazily creates
a new generation. Timeout is a distinct error state.
a new generation. Timeout is a distinct error state. A separate idempotent
load operation verifies a worker's runtime identity before execution; its
flavour-specific startup deadline is not charged to the 250 ms live or selected
manual execution deadline. A killed generation must load and verify again.
The supervisor has a two-worker retention target; before creating another
profile worker it evicts the least recently used idle generation. Active work
is never evicted and may temporarily exceed that target.
The Python worker imports only the self-hosted Pyodide loader and pack, then
evaluates the application-owned bounded bridge in CPython. The bridge returns
code-point ranges, which are retained as native values and converted only at
valid boundaries to editor UTF-16. The Java worker imports a verified TeaVM
ES2015 module. That module executes TeaVM's own `java.util.regex.Pattern` and
`Matcher` class-library implementation and returns native UTF-16 ranges; it is
not OpenJDK.
PHP, Perl, Ruby, C++, Go, Rust and .NET each use a fixed bounded bridge to the
named self-hosted runtime. User values cross as structured/JSON data, never as
generated source. Scala intentionally reuses the TeaVM Java module and rewrites
only request/result profile metadata; it contains no Scala runtime. The legacy
Perl topology is unusual: the supervised module worker owns the classic worker
required by WebPerl, so supervisor termination still discards the complete
worker tree.
Ruby's production bridge avoids ruby.wasm's generic JavaScript object
conversion: the worker writes one bounded length-prefixed request into its
private WASI memory filesystem, calls the fixed bridge with no user arguments,
reads one bounded inert metadata JSON string, and obtains bounded UTF-8
replacement output from a separate private file. That path avoids JSON output
amplification and passes the same strict-CSP browser gate as the other
profiles.
PCRE2 tracing is not an `EngineSupervisor` match or replacement operation. Its
own worker compiles with `PCRE2_AUTO_CALLOUT`, copies only complete fixed
@@ -70,13 +113,15 @@ PCRE2 API cannot express directly. Its advertised C17 target is protected by
deterministic golden identities and an exact PCRE2 10.47 compile/execute gate.
Subject minimization is a main-thread bounded reducer whose expensive predicate
checks stay in independently terminable engine workers. Fixed pattern syntax
is parsed once for capture metadata. The baseline and every accepted candidate
retain the exact target and engine identity. Timeout, crash, cancellation,
worker failure and incomplete output are separate outcomes. Deterministic
ddmin deletion is followed by a fixed-point local sweep over Unicode-scalar
deletion and lower-rank canonical replacement; only completion of that sweep
permits a transform-local minimality claim.
checks stay in independently terminable ECMAScript or PCRE2 workers. Fixed
pattern syntax is parsed once for capture metadata. Every other profile is
blocked at this feature boundary rather than routed to a different engine. The
baseline and every accepted candidate retain the exact target and engine
identity.
Timeout, crash, cancellation, worker failure and incomplete output are separate
outcomes. Deterministic ddmin deletion is followed by a fixed-point local sweep
over Unicode-scalar deletion and lower-rank canonical replacement; only
completion of that sweep permits a transform-local minimality claim.
Generated-case synthesis and verification are separate trust boundaries. The
dedicated generation worker receives only a validated, complete ECMAScript
@@ -123,10 +168,11 @@ separator during apply. This makes anchor and cross-line behavior deliberately
different rather than silently rewriting the pattern. Match DTOs are reduced to
bounded per-group participation counts and samples before the next document.
Native ranges are retained in the engine's declared unit. PCRE2 always uses
UTF/UCP and exposes UTF-8 byte ranges; its ABI copies scalar records and names
out of WebAssembly before returning and retains no code pointer. Browser editor ranges
are half-open UTF-16 code-unit ranges. Reusable converters cover UTF-8 byte and
Native ranges are retained in the engine's declared unit. ECMAScript, Java,
Scala compatibility and .NET use UTF-16 code units. Standalone PCRE2, PHP, Go
and Rust expose UTF-8 byte ranges. CPython, CRuby, libc++ `std::wregex` and
legacy Perl expose Unicode code-point positions. Browser editor ranges are
half-open UTF-16 code-unit ranges. Reusable converters cover UTF-8 byte and
Unicode code-point offsets, including invalid-boundary rejection and
lone-surrogate detection.

View File

@@ -6,6 +6,11 @@ The comparison panel sends two explicit requests: one to the native browser
ECMAScript worker and one to the bundled PCRE2 10.47 worker. It does not
translate patterns, flags, options or replacement templates.
This is an explicit two-engine feature, not a generic active-flavour
comparison. Selecting PHP, Perl, Python, Ruby, Java, C++, Go, Rust, .NET or
Scala compatibility for the main workbench does not insert it into either side
or route it through ECMAScript/PCRE2.
Two pattern models are available:
- **Shared pattern** sends the same string unchanged to both engines.
@@ -51,9 +56,12 @@ result. The panel renders at most 250 differences and 100 alignments at once.
## PCRE2 C17 generator
The first reviewed code-generation target is the PCRE2 10.47 8-bit C API.
Other languages remain unavailable until their generators have equivalent
escaping, semantic and toolchain gates.
The first reviewed code-generation target is the standalone PCRE2 10.47 8-bit
C API. Every other target remains unavailable until its generator has
equivalent escaping, semantic and named-runtime/toolchain gates. In particular,
PHP's embedded PCRE2 10.44 is not routed through the standalone-PCRE2
generator; an executable browser profile does not by itself imply a
code-generation target.
The generator consumes a validated PCRE2 snapshot and:

View File

@@ -1,9 +1,11 @@
# Engine builds
The production application uses the browser's native `RegExp` for ECMAScript
and bundles a verified PCRE2 10.47 WebAssembly pack. Normal application builds
never download or compile an engine: the reviewed files under
`public/engines/pcre2/` are copied into `dist/` and verified there.
and bundles ten verified runtime packs for standalone PCRE2, PHP, Perl, Python,
Ruby, Java, C++, Go, Rust and .NET. The Scala/JVM compatibility profile shares
the Java pack and contains no Scala runtime. Normal application builds never
download or compile an engine: reviewed files under `public/engines/` are
copied into `dist/` and verified there.
## Rebuilding PCRE2
@@ -52,7 +54,277 @@ The immutable signed-tag object is pinned. OpenPGP trust validation remains a
release-operator step because the offline builder does not install or trust a
key.
## Runtime boundary
## Installing the Python pack
The Python pack is derived from the exact `pyodide@314.0.3` npm package locked
with integrity:
```text
sha512-sK40My6m8tmBUYtYH9au9rXUeh9x0wfahtHdOlGmJxZDsKBGKtP6KznyFB2+u/klbQTdDionR0uaVd176zVQzQ==
```
That Pyodide release is tag/commit
`ac57031be7564f864d061cb37c5c152e59f83ad4`. Direct executable identity
verification reports CPython 3.14.2; the shipped `pyodide-lock.json`
independently reports `info.python` as 3.14.0, and the verifier records rather
than conflates those two upstream identities. The pack copies only the reviewed
loader, WebAssembly runtime, Python standard library and lock metadata required
for a local CPython `re` worker. It adds deterministic engine metadata, a
closed-file-set checksum manifest and a complete `SOURCE-MANIFEST.json`.
The source manifest records immutable Git commit/tree identities or primary
release-archive SHA-256 values for Pyodide, its `pyodide-build` submodule, its
vendored Error Stack Parser 2.1.4 and StackFrame 1.3.4 ports, CPython, libffi,
Hiwire, XZ/liblzma, Zstandard, SQLite, the Emscripten bzip2 and zlib ports,
Emscripten itself and HACL* preferred source. It hashes both vendored
JavaScript ports, all nine CPython patches, all five Emscripten patches, and
the Pyodide Makefiles that select those inputs. That is the
preferred-form/patch route for the upstream MPL source; the exact npm package
remains the binary-distribution reference, not a claim that arbitrary future
host SDK packaging will reproduce identical bytes.
The linked-component inventory is derived from the exact Pyodide recipe and
checked against executable identities where the libraries expose one. Besides
Pyodide and CPython, the base module contains CPython-vendored Expat 2.7.3,
libmpdec 2.5.1 and HACL*, plus libffi, Hiwire 1.0.1, liblzma 5.2.2,
Zstandard 1.5.7, SQLite 3.39.0, bzip2 1.0.6 and zlib 1.3.1. The conservative
Emscripten 5.0.3 runtime notice closure covers musl, compiler-rt, libc++,
libc++abi, libunwind, dlmalloc and the MiniLZ4 source selected by the pinned
link flags. The upstream stripped module contains no link map, so retaining the
complete potentially selected Emscripten runtime notice set is intentional.
The install operation reads from the already installed pinned npm package. It
does not contact a CDN or package index. It verifies source package identity,
file hashes, runtime metadata, every independently fetched legal-source hash,
the generated source manifest and licence inputs before atomically replacing
only `public/engines/python/`. The distribution verifier checks the same closed
set under `dist/`, validates WebAssembly and native component identities and
confirms that all runtime references remain relative and self-hosted.
```sh
node scripts/python-engine-pack.mjs \
node_modules/pyodide \
.engine-build/python
node scripts/install-python-engine.mjs .engine-build/python
```
The installed closed set is:
- `pyodide.mjs`, `pyodide.asm.mjs` and `pyodide.asm.wasm`;
- `python_stdlib.zip` and `pyodide-lock.json`;
- `engine-metadata.json`, `SOURCE-MANIFEST.json` and `SHA256SUMS`; and
- 22 exact `LICENSE.*`/`NOTICE.*` files enumerated and source-anchored by that
manifest.
`pyodide-lock.json` is the upstream catalogue of optional packages. Regex
Tools does not ship the catalogue's wheels; `externalPackagesIncluded: false`
and the closed pack file set make that boundary machine-verifiable.
## Building the Java pack
The Java bridge under `engines/java/` wraps TeaVM 0.15.0
`java.util.regex.Pattern` and `Matcher`. TeaVM tag/commit
`ee91b03e616c4b45401cd11fb0cd7eb0daf6649b` is pinned through the Maven build.
The build produces a minified ES2015 module without source maps, source files,
remote imports or an OpenJDK runtime.
The pack gate verifies the Maven coordinates, bridge source identity, TeaVM
engine identity and self-test, generated module, deterministic metadata,
checksums, Apache-2.0 licence and TeaVM NOTICE. Only the verified pack is
installed under `public/engines/java/`.
```sh
node scripts/java-engine-pack.mjs
node scripts/install-java-engine.mjs
```
The pack command performs two clean offline Maven builds and requires identical
output. The installed closed set is `java-regex.mjs`,
`engine-metadata.json`, `SHA256SUMS`, `LICENSE.txt` and `NOTICE.txt`.
TeaVM supplies its own Apache Harmony-derived class-library implementation.
The resulting engine is therefore identified as
`TeaVM java.util.regex 0.15.0`, not OpenJDK. TeaVM 0.15.0 does not implement
OpenJDK's `Pattern.UNICODE_CHARACTER_CLASS`; the bridge treats the application
`U` flag as a compatibility request, implies Unicode case folding and reports
that predefined-character classes and word boundaries retain TeaVM behaviour.
## Building the PHP pack
The PHP bridge under `engines/php/` executes actual PHP 8.5.8 `preg_*`.
`@php-wasm/web-8-5` and `@php-wasm/universal` 3.1.46 plus their pinned support
packages supply the Asyncify WebAssembly runtime and host API. Direct identity
verification reports PCRE2 10.44; this pack is not the standalone PCRE2 10.47
build.
```sh
node scripts/php-engine-pack.mjs
node scripts/install-php-engine.mjs
```
The builder copies only the pinned npm runtime files, changes the
bundler-specific WebAssembly import into a same-directory URL, records the
original and transformed hashes, and runs real identity, match, bounded
replacement and native-component positive/negative audits before installation.
`native-components.json` binds the exact WebAssembly hash to WordPress
Playground `v3.1.46` commit
`581c7c172428159eb4e6c5309054a568cd39a97a`, PHP tag `php-8.5.8` commit
`26b97507444c4fbda072f57dda1820f7b7d5e467`, Emscripten 4.0.19 commit
`08e2de1031913e4ba7963b1c56f35f036a7d4d56` and all 32 linked native/source
surfaces. It carries exact archive hashes or Git identities where upstream
recorded them and honestly bounds the one unpinned Oniguruma clone using the
committed archive/header identities and upstream source interval.
The pack elects PHP License version 4 (`BSD-3-Clause`) for PHP 8.5.8 through
PHP's later-version option and includes the complete PCRE2 and PHP-vendored,
external-library, patent and Emscripten/LLVM/musl legal set. This includes the
exact Zend Engine licence, official php-src binary redistribution notice, CLI
HTTP parser MIT terms, and the public-domain, CC0 and FNV permission notices for
linked hash implementations. The WordPress Playground `@php-wasm` packages
retain GPL-2.0-or-later; JavaScript support-package licences remain separate.
All 42 legal assets and the native inventory are independently SHA-256-pinned
by the builder, then covered again by the closed file set, `SHA256SUMS`, release
requirements and metadata.
## Building the legacy Perl pack
The Perl bridge under `engines/perl/` uses the unmodified WebPerl 0.09-beta
prebuilt archive, SHA-256
`5f441249217e90ab378c666f473d4206ab4f44907f6bb0aa8d70834bc38c40dc`.
That 2019 beta contains Perl 5.28.1 and Emscripten 1.38.28 output. It is
intentionally a legacy compatibility target, not a current Perl distribution.
The builder accepts only a local copy of that exact official archive; it never
downloads. An already extracted release root can be supplied with `--prebuilt`
instead of `--archive`.
```sh
node scripts/perl-engine-pack.mjs \
--archive /absolute/path/webperl_prebuilt_v0.09-beta.zip
node scripts/perl-engine-pack.mjs --verify .engine-build/perl
node scripts/install-perl-engine.mjs .engine-build/perl
```
The installed pack retains upstream `emperl.js`, `emperl.wasm` and
`emperl.data` byte-for-byte. Application-owned fixed worker and Perl bridge
files carry values through an exact-key, byte-bounded JSON request path; they do
not splice patterns or replacements into source. The metadata response remains
bounded JSON, while successful replacement UTF-8 bytes stream into a separate
fixed MEMFS binary file and receive exact worker-side byte, size and encoding
validation. Exact WebPerl/Perl, Emscripten and bundled-CPAN notices travel with
the pack.
The legacy generated loader contains one `eval(code)` site in an optional
Perl-to-JavaScript interoperability import. The application bridge never loads
that facility. Its browser CSP smoke passes with `'wasm-unsafe-eval'` and
without broad `'unsafe-eval'`; that dormant upstream site remains documented
rather than removed from the checksummed asset.
## Building the Ruby pack
The Ruby pack copies the minimal runtime from pinned
`@ruby/4.0-wasm-wasi@2.9.3-2.9.4` and uses
`@ruby/wasm-wasi@2.9.3-2.9.4` as its host. It verifies the CRuby 4.0.0
`wasm32-wasi` identity and actual `Regexp`/replacement behavior before
installation.
```sh
node scripts/ruby-engine-pack.mjs
node scripts/install-ruby-engine.mjs
```
The closed set contains the runtime WebAssembly file, deterministic metadata
and checksums, ruby.wasm licence/complete NOTICE and the exact browser WASI
shim and `tslib` licence texts needed by the host bundle. The production worker
passes each request through a bounded length-prefixed file in its private WASI
memory filesystem. It receives bounded inert JSON metadata and reads bounded
UTF-8 replacement output from a separate private file, rather than amplifying
that output through JSON or using `RubyVM.wrap`/`toJS` and their
JavaScript-eval conversion path. Ruby cold startup passes the release's
strict-CSP browser gate.
## Building the C++ pack
The C++ bridge under `engines/cpp/` is compiled with Emscripten 6.0.4 at
compiler revision `fe5be6afdff43ad58860d821fcc8572a23f92d19`. It uses libc++
`std::wregex`, 32-bit `wchar_t`, fixed structured Embind entry points and
`-sDYNAMIC_EXECUTION=0`.
```sh
node scripts/cpp-engine-pack.mjs --empp /absolute/path/to/em++
node scripts/install-cpp-engine.mjs
```
The verifier checks exact Emscripten, emsdk and LLVM identities, bridge hashes,
WebAssembly/module structure, absence of dynamic-execution constructs in the
generated module, runtime identity, code-point ranges and bounded replacement
parity. The build also enables `wasm-ld --trace` and accepts only the reviewed
linked archive set: Emscripten runtime support, musl `libc`, emmalloc,
compiler-rt builtins, libc++ and libc++abi.
`SOURCE-MANIFEST.json` ties the exact module hash to Emscripten tag/commit
`6.0.4`/`fe5be6afdff43ad58860d821fcc8572a23f92d19`, emsdk commit
`224ec5f9f2f72f09f9ce0e26d66bae7dbd8b692f`, the official release commit and
LLVM compiler commit. It records preferred-source paths and independently
pinned legal files for musl 1.2.6, emmalloc, compiler-rt 22.1.8, libc++ 21.1.8
and libc++abi 21.1.8. The current JavaScript-exception link selects no
`libunwind.a` member; libunwind 22.1.8 and its legal text remain as an explicit
audited exclusion. Any added, removed or newly selected archive fails the pack
build.
## Building the Go pack
Go 1.26.5 standard-library `regexp` is built with the official linux/amd64
archive, SHA-256
`5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053`,
for `GOOS=js GOARCH=wasm`.
```sh
node scripts/build-go-engine.mjs /absolute/path/to/go
node scripts/install-go-engine.mjs
node scripts/verify-go-engine.mjs
```
The pack pins the source commit, official archive, `wasm_exec.mjs`, bridge
source, build flags and Go licence. Verification executes real Unicode
matching and `regexp.ExpandString` cases.
## Building the Rust pack
The Rust bridge pins `regex` crate 1.13.1 and its complete Cargo graph, rustc
1.97.1, the matching `wasm32-unknown-unknown` standard library and wasm-bindgen
0.2.126.
```sh
node scripts/build-rust-engine.mjs /absolute/path/to/rust-toolchain
node scripts/install-rust-engine.mjs
node scripts/verify-rust-engine.mjs
```
The pack records the distribution manifest/archive hashes, crate checksums,
compiler and LLVM identities, bridge sources, exact bindings and complete
Rust/crate licence material. Runtime verification covers identity, Unicode
byte ranges, limits and `Captures::expand`.
## Building the .NET pack
The fixed `[JSExport]` bridge under `engines/dotnet/` is published by .NET SDK
10.0.302 with runtime 10.0.10 and its `wasm-tools` workload.
```sh
node scripts/dotnet-engine-pack.mjs --dotnet /absolute/path/to/dotnet
node scripts/install-dotnet-engine.mjs
```
The pack gate checks SDK/runtime/workload and bridge identities, removes
compressed/debug outputs, records every `_framework` file, and includes the
.NET MIT licence and third-party notices. The release browser gate executes
the browser-WASM identity, Unicode-range and native-replacement smoke. There
is no separate Scala pack.
## Runtime boundaries
### PCRE2
ABI version 3 has no retained native handles. Each call compiles, obtains
capture names, matches/substitutes or traces and releases its code, match data
@@ -72,3 +344,115 @@ Normal execution lives only in `pcre2.worker`. Instrumented
never call it. Each supervisor terminates its worker on timeout, crash,
cancellation or supersession and lazily creates a clean generation for the
next request.
### Python
The Python worker loads the self-hosted Pyodide pack and verifies Pyodide,
CPython and `re` identities before accepting work. The application bridge is
evaluated inside that interpreter and exposes bounded compile, match and native
replacement operations. It reports CPython's Unicode code-point positions;
the TypeScript adapter retains them and converts only valid boundaries to
half-open editor UTF-16 ranges. Replacement output is byte-bounded in Python,
encoded as canonical base64 in the JSON envelope and decoded only after its
declared size, request cap and UTF-8 are validated. Runtime load has a separate
startup deadline. Execution timeout, cancellation or crash terminates the
worker and its complete Python/WebAssembly heap.
### Java
The Java worker imports the self-hosted TeaVM ES module and checks the bridge
ABI, declared engine identity and compiled self-test before accepting work.
Every request compiles a `Pattern`, obtains bounded `Matcher` results or native
replacement output, and returns native half-open UTF-16 ranges. No Java virtual
machine, OpenJDK classes, remote service or ECMAScript regex fallback is
involved. Runtime load has a separate startup deadline; termination discards
the complete worker module state.
### PHP
The PHP worker starts the same-origin Asyncify runtime, installs the fixed
`bridge.php` in its private virtual filesystem and verifies PHP 8.5.8 plus
PCRE2 10.44 before accepting work. User values cross only as JSON data. The
bridge selects its own safe delimiter, permits only registered modifiers and
calls native `preg_match()`. `PREG_OFFSET_CAPTURE` byte offsets are retained;
byte matches that split an encoded character are rejected because they cannot
map losslessly to a browser string. Bounded replacement mirrors PHP 8.5.8's
`preg_get_backref()` syntax over those native records and clips every append
before allocation crosses the requested byte cap. `preg_replace()` is used
only by the fixed identity parity self-test. Replacement bytes cross the JSON
envelope as size-predictable base64 and are decoded with a fatal UTF-8 check.
### Perl
The supervised module worker owns a nested classic worker required by the
legacy WebPerl loader. Terminating the supervisor also terminates that
descendant and the complete Perl heap. The fixed bridge uses `no re 'eval'`,
rejects code assertions independently and exposes only literal text, `$$`,
greedy `$n` and `${name}` replacement expansion. It pre-tokenizes that grammar,
streams small bounded UTF-8 pieces from native spans without constructing a
complete expansion or JSON output, and preserves the unmatched tail when the
match/capture-row bound stops replacement. Fixed named and numbered fixtures
are checked against native Perl `s///` during the identity self-test. Perl
character offsets are returned as Unicode code points. This containment does
not make WebPerl current software; the UI continues to report its legacy beta
identity.
### Ruby
The Ruby worker starts the minimal WASI runtime, evaluates only the fixed
application bridge and verifies CRuby 4.0.0 identity. User values travel as
bounded length-prefixed data in the worker-local memory filesystem; the bridge
returns inert metadata JSON and never sends a user-controlled value through
ruby.wasm's JavaScript-eval object-conversion path. CRuby compiles and matches.
Native `String#gsub`/`String#sub` block iteration selects replacement matches;
a fixed streaming implementation of CRuby 4.0.0's `rb_reg_regsub` grammar
writes only the configured UTF-8 prefix to a separate private file. A
load-time parity check compares the fixed expander with CRuby on bounded
fixtures. Native character offsets are retained as Unicode code points.
Worker termination discards the Ruby VM and both private files.
### C++
The C++ worker loads fixed Embind exports whose generated module was built with
dynamic execution disabled. Each request constructs `std::wregex`, iterates
under central result limits and streams a fixed implementation of libc++'s
`match_results::format` default grammar through the output byte cap. Load-time
fixtures compare it with the native formatter. The adapter exposes 32-bit
`wchar_t` positions as Unicode code points. The default grammar is C++'s
modified ECMAScript grammar, not the browser's current ECMAScript grammar.
### Go and Rust
The Go and Rust workers load their own fixed JSON bridges and verify the exact
runtime/crate identities before work. Both return UTF-8 byte ranges and reject
lone surrogates before encoding. Go uses standard-library `regexp` and
`ExpandString`; Rust uses `regex` crate iteration and `Captures::expand`.
Their fixed streaming expanders reproduce those native replacement grammars
under the output byte cap and compare bounded fixtures with the native APIs at
load. The adapters measure exact request JSON bytes, while matching native caps
include the worst-case sixfold escaping of every accepted string field. Output
bytes use fixed 4:3 base64 JSON envelopes instead of content-dependent JSON
escaping. Neither runtime supports look-around or backreferences. Each module
also enforces its own pattern, result and output bounds; Rust adds
compiled-regex and DFA-size limits.
### .NET
The .NET worker loads the browser-WASM runtime and calls only fixed
`[JSExport]` methods with bounded JSON. It verifies runtime 10.0.10,
`System.Text.RegularExpressions`, UTF-16 offsets and invariant culture. A
nine-second native regex timeout complements the shorter supervisor deadline;
terminating the worker discards the managed runtime. The adapter currently
returns the final retained capture only, not .NET capture history. Replacement
templates are parsed once by a fixed streaming implementation of .NET's
numbered, named and special substitution tokens. A load-time oracle compares
the fixed implementation with native `Match.Result`; bounded UTF-8 output is
transported as canonical base64 rather than JSON-escaped user text.
### Scala/JVM compatibility
Scala requests deliberately delegate to the same verified TeaVM adapter and
module described under Java. Result metadata says “no Scala runtime”. The
profile covers Java-compatible pattern/replacement semantics only and does not
claim Scala `Regex` wrappers, extractors, compiler/runtime code or OpenJDK
behavior.

View File

@@ -5,6 +5,11 @@ results, but no V8, SpiderMonkey or JavaScriptCore execution trace. Regex Tools
does not relabel structural explanations, static findings or timing
observations as an ECMAScript engine trace.
The PHP, legacy Perl, CPython, CRuby, TeaVM Java/Scala compatibility, libc++,
Go, Rust and .NET bridges likewise expose compilation, bounded match/capture
and replacement results, not internal engine steps. Regex Tools does not label
their partial lexical syntax trees as traces.
PCRE2 10.47 has a separate actual automatic-callout vertical. ABI version 3
compiles the requested pattern with `PCRE2_AUTO_CALLOUT`, registers an
application callback, and copies only:

View File

@@ -20,8 +20,18 @@ common capture forms. It does not infer branch-reset numbering or claim full
nesting; authoritative compilation, capture counts, names and result ranges
come from PCRE2 itself.
The Python, Java, PHP, Perl, Ruby, C++, Go, Rust, .NET and Scala-compatibility
providers likewise emit deliberately partial lexical trees. They recognize
their documented capture and replacement forms for navigation and display,
but do not claim full grammar acceptance. The selected named runtime remains
authoritative for compilation. Java and Scala capture names displayed with
native numbered spans come from bounded lexical metadata; they are not
invented as a TeaVM-reported name table. C++ capture discovery is explicitly
unavailable for alternate grammars or `nosubs`.
The explanation tree is structural. It is never called an actual execution
trace. Selecting a node selects and scrolls its exact editor range; selecting
pattern text chooses the smallest enclosing node. PCRE2s separate trace viewer
contains actual bounded automatic callouts; its movement labels remain a
distinct derived layer and are never copied into the structural explanation.
The other eleven profiles expose no actual execution trace.

View File

@@ -18,10 +18,22 @@ budget. Consumers must inspect the preview status rather than treating a
preview as complete. In particular, list export is disabled if its template
would consume an incomplete value.
Repeated ECMAScript captures expose only the final retained capture. The UI
labels this limitation and does not invent history. Later .NET support may add
actual engine capture-history nodes without degrading them to this model.
Repeated captures expose only the final retained value in all twelve v0.4.2
profiles. This includes .NET even though its native API can retain capture
history: the current adapter deliberately normalizes only the final record and
reports `captureHistory: false`. The UI labels the limitation and does not
invent or silently discard advertised history.
The syntactic hierarchy remains useful even if actual spans overlap or fall
outside a parent's geometry; native and normalized ranges are preserved rather
than “fixed”.
The partial syntactic hierarchy remains useful when the active provider found
capture relationships, even if actual spans overlap or fall outside a parent's
geometry. For C++ alternate grammars or suppressed submatches, capture
discovery can be explicitly unavailable. Runtime records remain authoritative.
Native and normalized ranges are preserved rather than “fixed”:
- JavaScript, Java, Scala compatibility and .NET use UTF-16 code units;
- standalone PCRE2, PHP, Go and Rust use UTF-8 bytes; and
- Python, Ruby, C++ and legacy Perl use Unicode code points.
All editor ranges are normalized to UTF-16 only after the adapter verifies
valid boundaries. The native unit and original range remain available.

View File

@@ -1,55 +1,87 @@
# Flavour support
| Flavour | Syntax | Execution | Replacement | Captures | Trace | Analysis | Generated cases | Native offsets |
| ------------ | ------------------------------------------------------------ | ------------------------------------------------------ | ---------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------- | ------------------- |
| ECMAScript | regexpp 4.12.2; explanations partial/feature-matrix tested | Current browser `RegExp`; conformance tested | Bounded ECMAScript `GetSubstitution` | Named/numbered; final repeated capture; no history | Unavailable | Experimental static heuristics + bounded native probes | Bounded normalized-AST sampling; actual-engine verified | UTF-16 |
| PCRE2 10.47 | Application lexical provider partial; compiler authoritative | Pinned 8-bit WASM; bounded/killable/conformance tested | Native bounded `pcre2_substitute()` loop | Native named/numbered records; no capture history | Bounded reported automatic callouts; derived movement labels | Unavailable; ECMAScript heuristics are never applied | Unavailable; structural syntax provider is partial | UTF-8 bytes |
| PCRE | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable |
| Python `re` | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Planned code points |
| Go `regexp` | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Planned UTF-8 bytes |
| Rust `regex` | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Planned UTF-8 bytes |
| .NET | Unavailable | Unavailable | Unavailable | Planned capture history | Unavailable | Unavailable | Unavailable | Planned UTF-16 |
| Java | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Unavailable | Planned UTF-16 |
Version 0.4.2 exposes twelve executable profiles. “Partial lexical provider”
means that Regex Tools recognizes common structure and replacement tokens for
explanation only; the named runtime compiler and replacement operation remain
authoritative.
ECMAScript tests cover its complete exposed flag matrix, internal indices,
zero-length iteration, captures, lookbehind, backreferences, Unicode properties
and bounded replacement.
| Profile | Syntax and execution identity | Replacement | Captures and native offsets |
| ----------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| JavaScript (ECMAScript) | regexpp 4.12.2 with ECMAScript 2025 syntax; current browser `RegExp` executes | Bounded ECMAScript `GetSubstitution` | Named/numbered, final repeated capture; UTF-16 |
| PCRE2 | Partial provider; official standalone PCRE2 10.47 8-bit WASM executes in mandatory UTF/UCP mode | Native bounded `pcre2_substitute()` loop | Native named/numbered records, no history; UTF-8 bytes |
| PHP | Partial provider; actual PHP 8.5.8 `preg_*` in `@php-wasm/web-8-5` 3.1.46, reporting PCRE2 10.44 | Fixed bounded PHP-token expansion; load-time `preg_replace()` parity | Native named/numbered records, no history; UTF-8 bytes |
| Perl | Partial provider; actual Perl 5.28.1 through legacy WebPerl 0.09-beta | Fixed bounded literal/`$$`/`$n`/`${name}` expansion; arbitrary Perl expressions unavailable | Native numbered spans plus bounded name annotations, no history; Unicode code points |
| Python | Partial provider; CPython 3.14.2 `re` in Pyodide 314.0.3 | Native bounded `re` expansion | Native named/numbered spans, no history; Unicode code points |
| Ruby | Partial provider; CRuby 4.0.0 `Regexp` in ruby.wasm 2.9.3-2.9.4 | Native `gsub`/`sub` iteration plus bounded CRuby 4.0.0-compatible expansion | Native named/numbered spans, no history; Unicode code points |
| Java | Partial provider; TeaVM 0.15.0 `java.util.regex`, not OpenJDK | TeaVM single-digit `$n`; no `${name}` | Native numbered ranges plus lexical names, no history; UTF-16 |
| C++ | Partial provider; Emscripten 6.0.4 libc++ `std::wregex`; modified ECMAScript grammar by default | Fixed bounded formatter; load-time libc++ `match.format` parity | Numbered captures only, no history; 32-bit `wchar_t` code points |
| Go | Partial provider; Go 1.26.5 standard-library `regexp` with RE2 syntax | Fixed bounded expansion; load-time `regexp.ExpandString` parity | Native named/numbered records, no history; UTF-8 bytes |
| Rust | Partial provider; Rust `regex` crate 1.13.1, built with rustc 1.97.1 | Fixed bounded expansion; load-time `Captures::expand` parity | Native named/numbered records, no history; UTF-8 bytes |
| .NET | Partial provider; .NET 10.0.10 `System.Text.RegularExpressions`, invariant culture | Fixed streaming .NET-token expansion with load-time native `Match.Result` parity | Named/numbered final records, no capture history in this adapter; UTF-16 |
| Scala/JVM compatibility | Partial provider; explicitly shares TeaVM 0.15.0 `java.util.regex`; no Scala runtime | Same TeaVM single-digit `$n` subset; no `${name}` | Same ranges as the TeaVM Java adapter; UTF-16 |
PCRE2 tests cover `g`, `i`, `m`, `s`, `x`, `U`, `J`, mandatory UTF/UCP,
branch-reset groups, recursion, `\K`, duplicate names, native substitution,
astral byte/UTF-16 ranges, zero-length iteration, compile errors, match limits
and result/output truncation. Trace tests cover reported automatic callouts,
bounded mark copying, native stop at the complete-event cap, compile ranges,
worker loading and browser rendering.
## Flags and options
ECMAScript static findings and generated-input timing observations are
advisory. They describe only the selected ECMAScript 2025 pattern, browser
runtime and bounded inputs; they are not proofs of safety or general
complexity.
- JavaScript exposes `g`, `i`, `m`, `s`, `u`, `v`, `y` and `d`; `u` and `v`
are mutually exclusive.
- Standalone PCRE2 exposes application iteration `g` plus `i`, `m`, `s`, `x`,
`U` and `J`, with match-step, depth and heap limits. UTF/UCP is mandatory.
- PHP exposes application iteration `g` plus the reviewed `preg` modifiers
`i`, `m`, `s`, `x`, `u`, `U`, `A`, `D`, `J`, `n` and `r`. PHP's `u` is not
conflated with standalone PCRE2's mandatory UTF/UCP configuration.
- Legacy Perl exposes `g`, `i`, `m`, `s`, `x`, `n` and one of `a`, `d`, `l` or
`u`. The two-character `/aa` mode is not exposed.
- Python exposes application iteration `g` plus `a`, `i`, `m`, `s` and `x`.
- Ruby exposes application iteration `g` plus `i`, `m` and `x`; Ruby `m`
includes dot-all behavior.
- Java and Scala compatibility expose application iteration `g` plus TeaVM
`Pattern` flags `i`, `d`, `m`, `s`, `u`, `x` and the documented `U`
compatibility request.
- C++ exposes application iteration `g` plus `i`, `n`, `o` and `c`, and a
required grammar option: `ECMAScript`, `basic`, `extended`, `awk`, `grep` or
`egrep`.
- Go exposes application iteration `g` plus `i`, `m`, `s` and `U`.
- Rust exposes application iteration `g` plus `i`, `m`, `s`, `U`, `u`, `x` and
`R`; Unicode is enabled by default.
- .NET exposes application iteration `g` plus `i`, `m`, `s`, `n`, `x`, `r`,
`c` and `b`. Execution is always culture invariant; `c` makes that fixed
compatibility choice explicit.
ECMAScript generated-case version 1 uses only a complete accepted normalized
AST, an explicit deterministic seed and bounded sampling strategies. Every
retained positive or negative label is confirmed by the actual selected
browser engine. PCRE2 generation is unavailable because its current lexical
provider is intentionally partial; ECMAScript behavior is never relabelled as
PCRE2.
## Verified boundaries
The PCRE2 explanation provider deliberately does not invent full structural
coverage. In particular, branch-reset numbering is omitted from the syntax tree
while actual capture numbers and names still come from PCRE2 results.
Every adapter has focused identity, request and result-contract tests.
Conformance and browser suites exercise compilation errors, bounded matching,
zero-length iteration, range normalization, replacement and worker recovery
across the profile set. Pack verifiers additionally check self-hosted assets,
metadata, closed-file-set checksums and applicable licences/notices.
ECMAScript and PCRE2 support exact-request comparison for syntax acceptance,
engine compilation, matches, captures and engine-native replacement. Results
align by normalized UTF-16 ranges while retaining each native offset model.
Timeout, cancellation, rejection and truncation are never presented as
equivalent results.
TeaVM supplies an Apache Harmony-derived class library. It is not OpenJDK and
does not implement OpenJDK `Pattern.UNICODE_CHARACTER_CLASS`; `U` means the
documented TeaVM compatibility behavior in both the Java and Scala profiles.
The Scala profile also does not implement `scala.util.matching.Regex` wrapper
or extractor APIs.
Pattern formatting is available only for an exact accepted ECMAScript regexpp
snapshot. It canonicalizes literal slashes and raw control/line-separator
representations, then requires paired actual-engine and applicable exact-test
validation before apply. PCRE2 formatting is unavailable because the current
provider is deliberately partial; its syntax is never treated as ECMAScript.
The Perl target is intentionally legacy. Its unmodified WebPerl loader contains
one `eval(code)` site in an optional Perl-to-JavaScript interoperability import.
The fixed Regex Tools bridge does not load that facility, accepts pattern and
replacement values only as JSON data, uses `no re 'eval'`, rejects `(?{...})`
and `(??{...})`, and passes the documented CSP smoke without broad
`'unsafe-eval'`.
PCRE2 is the only current code-generation target. The reviewed C17 generator is
pinned to the PCRE2 10.47 8-bit API; other language generators remain
unavailable until they pass equivalent escaping and named-toolchain gates.
## Feature scope
Static findings, bounded growth probes, benchmarks, generated cases and
formatting are ECMAScript-only. Generated-case version 1 requires the complete
accepted regexpp AST and verifies every retained label through the actual
browser engine. No partial provider is passed through that generator or
formatter.
Automatic-callout tracing and reviewed C17 code generation are standalone
PCRE2-only. The PHP profile does not reuse the standalone PCRE2 10.47 trace or
code-generation path because its authoritative engine is PHP `preg` with
PCRE2 10.44.
Exact-request semantic comparison and subject minimization support only their
reviewed ECMAScript/standalone-PCRE2 paths. Other selections are disabled
rather than routed through another profile. Results never claim generic
twelve-way equivalence.

View File

@@ -23,8 +23,9 @@ pretty-printer. The transform is idempotent.
Formatting requires the exact current, accepted, non-recovered syntax snapshot
from the bundled `@eslint-community/regexpp` provider. Transformations are
derived from the provider's literal-token ranges rather than from a heuristic
text scan. A stale parse, a malformed pattern, a partial provider, PCRE2 or any
other flavour is reported as unavailable and is never silently rewritten.
text scan. A stale parse, malformed pattern, partial provider or any
non-ECMAScript profile is reported as unavailable and is never silently
rewritten.
## Mandatory validation before apply

View File

@@ -25,10 +25,11 @@ The coverage report says `covered`, `partial`, `unsupported` or
sampling strategy was requested. It does not mean every string in the regular
language was enumerated.
PCRE2 generation is unavailable in version 1. Its actual engine is complete for
the advertised execution operations, but its current structural syntax
provider is intentionally partial. Regex Tools does not feed PCRE2 syntax to
the ECMAScript generator or relabel ECMAScript behavior.
Standalone PCRE2, PHP, Perl, Python, Ruby, Java, C++, Go, Rust, .NET and Scala
compatibility generation is unavailable in version 1. Their actual engines are
complete for the advertised execution operations, but their current structural
syntax providers are intentionally partial. Regex Tools does not feed their
syntax to the ECMAScript generator or relabel ECMAScript behaviour.
## Unsupported and partial constructs
@@ -75,7 +76,9 @@ removes the generation provenance.
Candidate synthesis runs in a dedicated killable worker. The verifier then
sends each exact candidate, pattern, flavour version, flags, engine options and
scan mode through `EngineSupervisor`, which selects the registered real engine
worker.
worker. Version 1's eligibility gate accepts only the exact current ECMAScript
snapshot; the generic supervisor boundary does not make partial-provider
flavours eligible.
- An intended positive is labelled `should-match` only after the engine returns
at least one match.

View File

@@ -10,6 +10,11 @@ selected real ECMAScript or PCRE2 worker. It can preserve:
- the same one-sided comparison timeout while the other engine completes with
authoritative, untruncated output.
PHP, Perl, Python, Ruby, Java, C++, Go, Rust, .NET and Scala compatibility are
not supported minimization targets in v0.4.2. The workspace disables reduction
for those active profiles; it does not substitute ECMAScript, PCRE2 or a
lexical provider as an execution oracle.
The fixed pattern, ordered flags, options, replacement and engine versions form
the target identity. Syntax is parsed once to obtain capture metadata. Every
accepted subject candidate is then verified through the selected execution

View File

@@ -6,14 +6,38 @@ Regex Tools has one public profile:
community
```
It uses only reviewed open-source dependencies and builds without private
registry credentials. ECMAScript uses regexpp 4.12.2. PCRE2 uses an
application-owned lexical provider for partial explanations and the actual
bundled PCRE2 compiler for authoritative acceptance.
It uses reviewed open-source dependencies and builds without private registry
credentials. No licensed parser is installed, referenced or required.
JavaScript/ECMAScript uses regexpp 4.12.2 for ECMAScript 2025 syntax. That is
the only current complete grammar-backed normalized syntax tree. All other
profiles use application-owned, deliberately partial lexical providers:
| Profile | Authoritative compiler | Lexical-provider boundary |
| ----------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| PCRE2 | Standalone PCRE2 10.47 | Common captures and PCRE2 constructs; no complete structural grammar or branch-reset numbering |
| PHP | PHP 8.5.8 `preg` / PCRE2 10.44 | Common PCRE2/PHP capture forms and numbered replacement references; no delimiter or complete `preg` template model |
| Perl | Perl 5.28.1 via legacy WebPerl 0.09-beta | Common captures and fixed bridge references only; embedded code and complete Perl interpolation are unavailable |
| Python | CPython 3.14.2 `re` | Common Python captures and replacement references |
| Ruby | CRuby 4.0.0 `Regexp` | Common Onigmo capture forms and `String#gsub` references |
| Java | TeaVM 0.15.0 `java.util.regex` | Common Java captures and TeaVM replacement subset; not OpenJDK |
| C++ | Emscripten 6.0.4 libc++ `std::wregex` | Capture discovery only for the default modified ECMAScript grammar; alternate grammars remain compiler-authoritative |
| Go | Go 1.26.5 standard-library `regexp` | Common RE2 capture forms and `regexp.Expand` references |
| Rust | Rust `regex` crate 1.13.1 | Common capture forms and `Captures::expand` references |
| .NET | .NET 10.0.10 `System.Text.RegularExpressions` | Common captures/substitutions; no balancing-group or capture-history structure |
| Scala/JVM compatibility | Same TeaVM 0.15.0 Java engine | Java-compatible syntax only; no Scala runtime, wrapper or extractor model |
The Java and Scala providers follow the bundled TeaVM 0.15.0 replacement
subset: single-digit `$n` is executable, `$12` is `$1` followed by literal
`2`, and `${name}` is surfaced as a compatibility limitation. The Scala
provider deliberately shares that implementation and says so.
Every partial provider exposes its gaps through coverage metadata. Actual
acceptance, capture numbering and replacement output always come from the
selected runtime. ECMAScript analysis, case generation and formatting are not
applied to these partial trees.
The product deliberately does not implement or reference an `@r101/parser`
profile. No commercial package alias, import, tarball, credential, licence key
or private CI path exists. Additional flavour syntax will be implemented
incrementally as open-source providers behind the same application-owned
interface. Partial coverage is exposed as metadata and never presented as a
complete parser.
or private CI path exists. Further syntax coverage can grow behind the same
application-owned interface without changing the runtime identity.

View File

@@ -10,12 +10,33 @@ browser, engine version, pattern and subject. The UI therefore reports observed
elapsed time and exact runtime identity but makes no universal throughput or
safety claim.
PCRE2 cold execution includes loading and instantiating the self-hosted
WebAssembly module inside its worker; warm requests reuse that instance.
PCRE2 cold worker startup includes loading and instantiating the self-hosted
WebAssembly module; warm requests reuse that instance.
Every request still compiles and frees its pattern so no unbounded compiled-code
cache can accumulate. Native match-step, depth and heap limits complement the
supervisor wall clock, and cancellation discards the complete worker heap.
Python has a materially larger cold start because its worker loads the
self-hosted Pyodide JavaScript/WebAssembly runtime and Python standard library
before verifying CPython and `re`. Java imports and self-tests its bundled
TeaVM ES module. Scala compatibility shares that Java module and does not load
a second runtime.
PHP, legacy Perl, Ruby, Go, Rust, C++ and .NET likewise load only when first
selected. Their cold cost differs substantially: PHP, Perl, Ruby and .NET
instantiate larger language/runtime packs; Go includes its standard
WebAssembly runtime; Rust and C++ are comparatively compact native modules.
The UI reports loading separately rather than charging it to the 250 ms live or
selected manual execution timeout.
Warm requests reuse a verified worker. To prevent profile exploration from
leaving every large runtime resident, the supervisor uses a two-worker
retention target and evicts the least recently used idle generation before it
creates another profile worker. An active request is never evicted, so
concurrent active work can temporarily exceed the target. Killing or evicting
a worker discards its complete runtime, so the next request pays the cold-load
cost and verifies identity again.
Automatic-callout tracing is deliberately excluded from every benchmark. It
compiles an independently instrumented PCRE2 pattern in a separate worker and
can materially change runtime work. The trace path retains at most 50,000
@@ -44,12 +65,12 @@ pages of 200. Individual result-value previews are capped at 64 Ki UTF-16 units
and share an 8 Mi-unit aggregate engine-result budget. The extraction tree
shows 100 UTF-16 units per value and capture-table cells show 512, with explicit
range lengths and separate engine-prefix labels; copy and eligible JSON export
retain the bounded engine value. List export is disabled when a source value is incomplete, so a bounded
preview cannot be mistaken for the full value. List generation additionally
stops at 250,000 template-token evaluations, a 64 Ki UTF-16 row preview, or an
8 Mi-unit aggregate materialization bound. The UI shows 500 list rows while an
eligible export still contains every generated row; any incomplete result
disables export.
retain the bounded engine value. List export is disabled when a source value is
incomplete, so a bounded preview cannot be mistaken for the full value. List
generation additionally stops at 250,000 template-token evaluations, a 64 Ki
UTF-16 row preview, or an 8 Mi-unit aggregate materialization bound. The UI
shows 500 list rows while an eligible export still contains every generated
row; any incomplete result disables export.
Replacement output has a separate 64 MiB bound. Match/capture-limit
incompleteness and output-byte truncation are tracked separately; either makes
the aggregate replacement result incomplete.

View File

@@ -1,25 +1,46 @@
# Portal requirements
Regex Tools is a static nested-path-safe application.
Regex Tools is a static nested-path-safe application. All engine resources are
self-hosted below the mounted release path; no runtime CDN fallback is allowed.
Required delivery behavior:
- JavaScript workers use a JavaScript MIME type.
- `toolbox-app.json`, HTML and legal/source documents should remain
revalidation/no-cache resources.
- Hashed Vite assets may use immutable long-term caching.
- CSP must allow `worker-src 'self' blob:`.
- `engines/pcre2/pcre2.wasm` must use `application/wasm`.
- `script-src` must permit self-hosted WebAssembly compilation, normally with
`'wasm-unsafe-eval'`; broad `'unsafe-eval'` is neither needed nor recommended.
- `engines/pcre2/pcre2.mjs`, metadata, checksums, licence and WASM should use
revalidation or a release-scoped immutable cache. They are not
content-hashed filenames and must never drift under one release identity.
- JavaScript, module and worker files (`.js` and `.mjs`) use a JavaScript MIME
type.
- Every `.wasm` file below `engines/` uses `application/wasm`. This includes
standalone PCRE2, PHP, Perl, Python, Ruby, C++, Go, Rust and every .NET
`_framework` WebAssembly file.
- `toolbox-app.json`, HTML and legal/source documents remain
revalidation/no-cache resources. Hashed Vite assets may use immutable
long-term caching.
- CSP permits `worker-src 'self' blob:`. The legacy Perl profile starts one
nested same-origin classic worker inside its supervised module worker.
- CSP permits self-hosted WebAssembly compilation in `script-src`, normally
through `'wasm-unsafe-eval'`. Broad `'unsafe-eval'` must not be enabled to
accommodate a runtime. Ruby cold startup and the fixed legacy Perl path pass
the release's strict-CSP browser gate without broad eval. WebPerl retains a
dormant optional interoperability `eval` site in upstream `emperl.js`, but
the fixed bridge does not load it.
- `connect-src 'self'` permits workers/runtimes to fetch their own same-origin
WebAssembly, Python standard-library, Perl data, .NET framework and metadata
resources.
- Binary/data assets such as `python_stdlib.zip`, `emperl.data`, metadata JSON,
checksum files, licences and notices are delivered without content
transformation.
- Range support is not required, but servers and proxies must not rewrite
engine bytes or apply HTML fallbacks to missing asset paths.
- Every directory below `engines/` uses revalidation or a release-scoped
immutable cache. Most engine filenames are not content-addressed and must
never drift under one release identity.
A suitable CSP is documented in [`SECURITY.md`](SECURITY.md). Deployments
should test both a direct root mount and a nested mount such as
`/apps/regex/`, including cold loading of all twelve profiles.
The Portal must consume the immutable release ZIP, verify its SHA-256, verify
manifest ID `de.add-ideas.regex-tools` and version `0.2.0`, and mount it at a
manifest ID `de.add-ideas.regex-tools` and version `0.4.2`, and mount it at a
relative target such as `apps/regex/`.
The package, manifest, tag, artifact URL and checksum must all use the v0.2.0
identity. The historical v0.1.0 artifact coordinates remain immutable and must
not be overwritten or reused.
The package, manifest, tag, artifact URL and checksum must all use the v0.4.2
identity. Historical artifact coordinates remain immutable and must not be
overwritten or reused.

View File

@@ -1,21 +1,35 @@
# Reference implementations and sources
Inspection date: 2026-07-24.
Inspection date: 2026-07-27.
| Reference | Exact revision/version | Licence | Use and copying status |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Regex Tools | Unborn repository at initial inspection; release identity `v0.1.0` | GPL-3.0-or-later | Application source written for this project. |
| Toolbox SDK | `53c40a61ba1581246f65773fcbb1c1cfd31ac98e` / 0.2.2 | Apache-2.0 | Contract, shell and release conventions; package APIs used, no source adapted. |
| Toolbox Portal | `a9c31c8986c40a0097966318e925083302e91e13` / 0.5.0 | AGPL-3.0-only | Assembly/lock conventions inspected; no source copied into the app. |
| regexpp | 4.12.2; npm integrity `sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==` | MIT | Pinned ECMAScript syntax provider. Provider AST is normalized in a worker. |
| PCRE2 | signed tag 10.47; commit `f454e231fe5006dd7ff8f4693fd2b8eb94333429` | BSD-3-Clause WITH PCRE2-exception | Pinned offline build; generated verified WebAssembly pack is shipped, source is not vendored. |
| ECMAScript specification | <https://tc39.es/ecma262/>; living specification inspected 2026-07-24 | ECMA terms | Semantics reference; no prose copied. |
| regex101 | <https://regex101.com/> and public parser documentation | Product/commercial terms | Product reference only. No source, branding, explanations, reference prose or visual design copied. |
| `recheck` | 4.5.0 | MIT | Metadata inspected; not installed or shipped. |
| `regexp-ast-analysis` | 0.7.1 | MIT | Metadata inspected; not installed or shipped. |
| RegexHub | repository revision `d1d9f19d259745dfdd21935b9ef3e747b62b9bfb` | MIT | Potential future adversarial cases; no file copied. |
| RegexLib | Website inspected | Redistribution licence not established | No fixture copied. |
| RGXP.RU | Website inspected | Redistribution licence not established | No fixture copied. |
| Reference | Exact revision/version | Licence | Use and copying status |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Regex Tools | Release identity `v0.4.2` | GPL-3.0-or-later | Application source written for this project. |
| Toolbox SDK | `ef2dab4b46c61812c9a877d8a19fe497b4a4630a` / 0.2.3 | Apache-2.0 | Contract, shell and release conventions; package APIs used, no source adapted. |
| Toolbox Portal | `43670a58249a920d37b7465cfda6724f644a92f7` / aggregate v0.9.1 / package 0.2.9 | AGPL-3.0-only | Assembly/lock conventions inspected; no source copied into the app. |
| regexpp | 4.12.2; pinned npm integrity in `package-lock.json` | MIT | ECMAScript 2025 syntax provider; normalized in the syntax worker. |
| PCRE2 | Signed tag 10.47; commit `f454e231fe5006dd7ff8f4693fd2b8eb94333429` | BSD-3-Clause WITH PCRE2-exception | Standalone pinned offline build; verified 8-bit WebAssembly pack shipped, source not vendored. |
| PHP | Executable identity 8.5.8; embedded PCRE2 identity 10.44 | PHP License version 4 (BSD-3-Clause), elected through the earlier licence's later-version option | Actual PHP `preg_*` compiler, matcher and replacement runtime; PHP source not vendored. |
| WordPress Playground `@php-wasm` | `web-8-5`, `universal`, `util`, `logger`, `stream-compression` and `progress` 3.1.46; pinned npm integrities | GPL-2.0-or-later | Self-hosted PHP WebAssembly distribution/host packages; their separate GPL notice is included and recorded in the pack metadata. |
| WebPerl | 0.09-beta; commit `6f2173d29a2c2e3536e1de75ff5d291ae96ab348`; prebuilt archive SHA-256 `5f441249217e90ab378c666f473d4206ab4f44907f6bb0aa8d70834bc38c40dc` | GPL-1.0-or-later OR Artistic-1.0-Perl | Unmodified legacy prebuilt pack containing Perl 5.28.1; visibly labelled beta/legacy. |
| Emscripten used by WebPerl | 1.38.28 | MIT OR NCSA | Upstream-generated legacy Perl loader/runtime; applicable licence included. |
| Pyodide | Tag 314.0.3; commit `ac57031be7564f864d061cb37c5c152e59f83ad4`; pinned npm integrity | MPL-2.0 | Reviewed self-hosted runtime pack; no CDN use. |
| CPython | Executable runtime identity 3.14.2 in Pyodide 314.0.3 | PSF-2.0 | Actual `re` compiler, matcher and replacement runtime; Python source not vendored. |
| ruby.wasm / CRuby | `@ruby/4.0-wasm-wasi` and `@ruby/wasm-wasi` 2.9.3-2.9.4; executable CRuby identity 4.0.0 | MIT for ruby.wasm host; Ruby/BSD and component terms in bundled NOTICE | Minimal self-hosted CRuby `Regexp` runtime; pinned npm integrities/notices; fixed file/JSON bridge avoids the JavaScript-eval conversion. |
| TeaVM | Tag/commit `ee91b03e616c4b45401cd11fb0cd7eb0daf6649b` / 0.15.0 | Apache-2.0 | `java.util.regex` class library compiled into the verified Java module; not OpenJDK. Also backs the explicit Scala compatibility profile. |
| Emscripten / libc++ | Emscripten 6.0.4 compiler revision `fe5be6afdff43ad58860d821fcc8572a23f92d19` | MIT OR NCSA; Apache-2.0 WITH LLVM-exception | Compiles the application C++ bridge against libc++ `std::wregex`; toolchain source not vendored. |
| Go | Tag 1.26.5; commit `c19862e5f8415b4f24b189d065ed739517c548ba`; official archive SHA-256 `5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053` | BSD-3-Clause | Standard-library `regexp` compiler/matcher and official `js/wasm` runtime. |
| Rust `regex` | 1.13.1; commit `2b527599eb9eea0dcc288c704584f242f26a5c61`; crate checksum `f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d` | MIT OR Apache-2.0 | Actual crate compiler/matcher built for WebAssembly with the pinned Cargo graph. |
| Rust toolchain | rustc 1.97.1 commit `8bab26f4f68e0e26f0bb7960be334d5b520ea452`; wasm-bindgen 0.2.126 | Apache-2.0 OR MIT plus bundled component terms | Exact compiler, standard library and binding tool identities recorded in pack metadata. |
| .NET | SDK 10.0.302 / runtime 10.0.10; runtime commit `f7d90799ce` | MIT plus bundled third-party notices | Actual `System.Text.RegularExpressions` browser-WASM runtime. |
| ECMAScript specification | <https://tc39.es/ecma262/>; living specification inspected 2026-07-24 | ECMA terms | Semantics reference; no prose copied. |
| regex101 | <https://regex101.com/> and public parser documentation | Product/commercial terms | Product reference only. No source, branding, explanations, reference prose or visual design copied. |
| `recheck` | 4.5.0 | MIT | Metadata inspected; not installed or shipped. |
| `regexp-ast-analysis` | 0.7.1 | MIT | Metadata inspected; not installed or shipped. |
| RegexHub | Repository revision `d1d9f19d259745dfdd21935b9ef3e747b62b9bfb` | MIT | Potential future adversarial cases; no file copied. |
| RegexLib | Website inspected | Redistribution licence not established | No fixture copied. |
| RGXP.RU | Website inspected | Redistribution licence not established | No fixture copied. |
All v0.1.0 and v0.2.0 conformance cases are project-authored. See
`tests/fixtures/README.md`.
All v0.1.0 through v0.4.2 conformance cases are project-authored. See
`tests/fixtures/README.md`. Runtime pack metadata and adjacent licence/notice
files are authoritative for the exact binary distribution.

View File

@@ -18,9 +18,30 @@ on publication failure, replaces an existing exact version only with
`--force`, and produces:
```text
release/regex-tools-0.2.0.zip
release/regex-tools-0.2.0.zip.sha256
release/regex-tools-0.4.2.zip
release/regex-tools-0.4.2.zip.sha256
```
The existing `release/regex-tools-0.1.0.zip` and matching sidecar are historical
immutable artifacts. Creating v0.2.0 must not replace, rename or remove them.
The release scan checks ASCII/UTF-8, UTF-16LE and UTF-16BE content in text,
JavaScript, WebAssembly and PDB-like assets for local Unix/macOS/Windows build
paths. Runtime virtual homes are allowed only for the named generated loaders.
Two byte-exact upstream prebuilts are hash-bound exceptions:
`engines/perl/emperl.data` retains WebPerl's historical build paths and
documentation examples, and `engines/ruby/ruby.wasm` retains ruby.wasm's
upstream build paths. Any byte or path change removes that exception and fails
the release scan; neither artifact is rewritten.
Before packaging, the engine verifier checks the closed standalone-PCRE2, PHP,
Perl, Python, Ruby, Java, C++, Go, Rust and .NET file sets in `dist/`,
including checksums, metadata, licences/notices, module and WebAssembly
identities and self-hosted relative asset references. Browser/runtime smoke
tests cover every selectable profile; Scala compatibility must resolve to the
verified TeaVM Java pack while reporting that no Scala runtime is present.
The Python gate additionally requires its complete `SOURCE-MANIFEST.json`,
every preferred-form archive/Git/patch identity and all 22 independently
anchored base-runtime legal files. The C++ gate requires its exact traced
component/source manifest and six independently pinned legal files. The release
packager names every one of those files explicitly.
The existing v0.1.0 through v0.4.1 ZIPs and matching sidecars are historical
immutable artifacts. Creating v0.4.2 must not replace, rename or remove them.

View File

@@ -19,6 +19,75 @@ untrusted.
- PCRE2 runs only in mandatory UTF/UCP mode. Exact UTF-8 byte boundaries are
normalized to editor UTF-16 offsets; lone surrogates are rejected instead of
being silently replaced by browser encoding.
- Python starts only after the worker verifies Pyodide, CPython and `re`
identities. Pattern, subject, flags and replacement remain string data passed
to the fixed application bridge; no user-supplied Python source is evaluated.
Native code-point boundaries are checked before conversion to editor UTF-16.
Bounded replacement bytes use canonical base64 rather than content-dependent
JSON escaping; declared length, request cap and canonical UTF-8 are validated
before the output is exposed.
- Java starts only after the worker verifies the TeaVM bridge ABI, engine
identity and compiled self-test. It exposes only fixed bounded
`Pattern`/`Matcher` entry points; no JVM, Java class loading or user-supplied
JavaScript is available. The runtime is TeaVM, not OpenJDK.
- PHP starts only after the worker verifies PHP 8.5.8, PCRE2 10.44 and the
fixed bridge ABI. User values are JSON data written to a private virtual
filesystem; the bridge chooses a safe delimiter, allowlists modifiers and
invokes only fixed `preg_*` operations.
- The legacy Perl worker writes exact-key, byte-bounded JSON to a fixed MEMFS
request path and invokes only the constant `RegexTools::run_request()` entry
point. The bridge uses `no re 'eval'`, rejects `(?{...})` and `(??{...})`
outside escaped literals/classes, pre-tokenizes its non-executable
replacement grammar and streams bounded UTF-8 chunks from native match spans.
Successful output uses a separate fixed binary file, never the JSON response;
the worker verifies exact bytes, limit and canonical UTF-8 before decoding
it. Replacement stops at the match/capture-row bound and leaves the
unprocessed subject tail unchanged. WebPerl 0.09-beta's unmodified generated
loader contains one `eval(code)` site in an optional
JavaScript-interoperability import; the fixed bridge never loads or calls it.
The checksummed asset passes the browser CSP smoke without broad
`'unsafe-eval'`.
- Ruby evaluates only the fixed application bridge during worker startup.
Pattern, subject, flags, limits and replacement travel in one bounded,
length-prefixed file in the worker-local WASI memory filesystem. Native
`String#gsub`/`String#sub` block iteration cannot materialize expanded user
output: a fixed CRuby 4.0.0-compatible expander stops at the byte limit and
writes that prefix to a separate bounded file. The inert JSON response
contains metadata only and is assembled without per-code-point arrays. No
user value is interpolated into source or sent through ruby.wasm's
`RubyVM.wrap`/`toJS` JavaScript-eval conversion path. Unpaired browser
surrogates are rejected before UTF-8 encoding. Ruby cold startup passes the
strict-CSP release browser gate.
- C++ accepts only structured fixed Embind calls and is compiled with
Emscripten `-sDYNAMIC_EXECUTION=0`; the generated module is checked for
dynamic-source construction. Its libc++-compatible replacement expander
appends directly through the UTF-8 byte cap and is parity-checked at load.
Embind returns a structured JavaScript string rather than JSON, so there is
no escape amplification; the 64 MiB native buffer and its bounded UTF-16
conversion are the explicit peak-output copies.
- Go and Rust accept JSON data only through fixed exports. Each validates its
request and enforces pattern, subject, result and output caps inside
WebAssembly. Adapters measure exact encoded request bytes; the native request
cap covers worst-case sixfold JSON escaping for every accepted string field,
so control-heavy values retain the documented decoded field limits. Their
native-compatible replacement token streams stop at the output cap without
allocating a whole capture expansion. Bounded UTF-8 output crosses the JSON
bridge as fixed 4:3 base64 rather than content-dependent escaped text. Rust
additionally caps compiled-regex and DFA storage.
- .NET accepts bounded JSON only through fixed `[JSExport]` methods and never
evaluates user input as managed or JavaScript source. A native regex timeout
complements the supervisor timeout. Its fixed replacement parser streams
native-compatible token fragments through the UTF-8 byte cap, verifies
parity with `Match.Result` at load and transports output as canonical base64
to avoid JSON escaping amplification. The shipped .NET host contains runtime
debugging machinery, but normal production startup disables debugging and
is verified under the documented CSP.
- Scala compatibility shares the TeaVM Java bridge. It introduces no Scala
runtime, dynamic compiler or additional execution surface.
- Every bundled engine directory has a closed file set, deterministic
metadata/checksums and licence material verified both before installation and
in `dist/`. Runtime imports and fetches resolve only against the same-origin
release path.
- Replacement templates are strings; executable callbacks are unavailable.
- Replacement/list token decorations, rows, chips, diagnostics and list
evaluation work have separate presentation/operation caps; incomplete list
@@ -72,10 +141,17 @@ untrusted.
predicate check runs in the selected killable engine worker. Timeout, crash,
cancellation and worker error remain distinct; truncated results fail
closed. Subjects and results are ephemeral and never uploaded or persisted.
- No backend, uploads, telemetry, remote corpus URL, CDN, remote font, `eval`,
`Function`, arbitrary command line or unsafe HTML rendering exists.
- No backend, uploads, telemetry, remote corpus URL, CDN, remote font,
arbitrary command line or unsafe HTML rendering exists. Application code
does not evaluate user-controlled source in any language. The generic
generated Pyodide loader contains an Emscripten dynamic-link branch that
uses JavaScript `eval`, while the legacy WebPerl loader contains the optional
interop site described above. Neither shipped fixed execution path exercises
those branches, and both load under the CSP below without broad
`'unsafe-eval'`.
The PCRE2-enabled build needs a CSP equivalent to:
Every enabled profile, including a cold Ruby start, passes the release CSP
equivalent to:
```text
default-src 'self';
@@ -92,8 +168,11 @@ form-action 'none';
```
The Toolbox shell currently requires inline styles. Corpus ZIP generation and
PCRE2 use self-hosted modules and local workers under the existing
`worker-src` policy. Broad `unsafe-eval` is not required.
every engine pack use self-hosted modules/assets and local workers under the
existing `worker-src` and `connect-src` policy. Broad `'unsafe-eval'` must not
be added to accommodate an engine. The release gate blocks any future profile
that fails this strict-CSP browser matrix. `'wasm-unsafe-eval'` remains required
for the WebAssembly runtimes.
Report vulnerabilities privately to the repository owner before public issue
details are posted.

34
engines/cpp/README.md Normal file
View File

@@ -0,0 +1,34 @@
# C++ regex engine
This bridge executes patterns with the `std::wregex` implementation shipped in
Emscripten 6.0.4's libc++. The default grammar is the C++ standard library's
modified ECMAScript grammar; it is not presented as modern browser ECMAScript.
The fixed Embind entry points accept structured values only. User patterns,
subjects and replacement templates are passed as data and are never evaluated
as JavaScript or C++ source. The worker remains subject to Regex Tools' hard
timeout and result limits.
Replacement is streamed through the output byte limit with libc++
`match_results::format` default grammar. A load-time differential self-test
compares bounded fixture output with the native API; capture amplification
never materializes a whole per-match expansion.
Build with the pinned Emscripten checkout:
```sh
node scripts/cpp-engine-pack.mjs --empp /absolute/path/to/em++
node scripts/install-cpp-engine.mjs
```
The builder enables `wasm-ld --trace` and accepts only the reviewed archive
set. The generated `SOURCE-MANIFEST.json` records the exact Emscripten, emsdk
and LLVM identities; maps the selected Emscripten runtime, musl 1.2.6,
emmalloc, compiler-rt 22.1.8, libc++ 21.1.8 and libc++abi 21.1.8 sources to
their pinned legal files; and records that JavaScript exceptions select no
libunwind object. The libunwind legal text is retained so that exclusion stays
explicit and reviewable.
Native positions are Unicode code-point offsets because the bridge deliberately
uses 32-bit `wchar_t`; the TypeScript adapter preserves them and separately
normalizes editor ranges to UTF-16.

View File

@@ -0,0 +1,419 @@
#include <emscripten/bind.h>
#include <emscripten/version.h>
#include <cstdint>
#include <regex>
#include <stdexcept>
#include <string>
namespace {
using emscripten::val;
constexpr int kBridgeAbiVersion = 1;
constexpr std::size_t kMaximumCaptureGroups = 1000;
std::wstring decode_utf8(const std::string& input) {
std::wstring output;
output.reserve(input.size());
for (std::size_t index = 0; index < input.size();) {
const auto first = static_cast<unsigned char>(input[index]);
std::uint32_t code_point = 0;
std::size_t width = 0;
if (first <= 0x7f) {
code_point = first;
width = 1;
} else if ((first & 0xe0) == 0xc0) {
code_point = first & 0x1f;
width = 2;
} else if ((first & 0xf0) == 0xe0) {
code_point = first & 0x0f;
width = 3;
} else if ((first & 0xf8) == 0xf0) {
code_point = first & 0x07;
width = 4;
} else {
throw std::invalid_argument("Input is not valid UTF-8.");
}
if (index + width > input.size()) {
throw std::invalid_argument("Input ends inside a UTF-8 sequence.");
}
for (std::size_t offset = 1; offset < width; ++offset) {
const auto continuation =
static_cast<unsigned char>(input[index + offset]);
if ((continuation & 0xc0) != 0x80) {
throw std::invalid_argument("Input contains invalid UTF-8.");
}
code_point = (code_point << 6) | (continuation & 0x3f);
}
const bool overlong = (width == 2 && code_point < 0x80) ||
(width == 3 && code_point < 0x800) ||
(width == 4 && code_point < 0x10000);
if (overlong || code_point > 0x10ffff ||
(code_point >= 0xd800 && code_point <= 0xdfff)) {
throw std::invalid_argument("Input contains invalid Unicode.");
}
output.push_back(static_cast<wchar_t>(code_point));
index += width;
}
return output;
}
void append_utf8_code_point(std::string& output, std::uint32_t code_point) {
if (code_point <= 0x7f) {
output.push_back(static_cast<char>(code_point));
} else if (code_point <= 0x7ff) {
output.push_back(static_cast<char>(0xc0 | (code_point >> 6)));
output.push_back(static_cast<char>(0x80 | (code_point & 0x3f)));
} else if (code_point <= 0xffff) {
output.push_back(static_cast<char>(0xe0 | (code_point >> 12)));
output.push_back(static_cast<char>(0x80 | ((code_point >> 6) & 0x3f)));
output.push_back(static_cast<char>(0x80 | (code_point & 0x3f)));
} else {
output.push_back(static_cast<char>(0xf0 | (code_point >> 18)));
output.push_back(
static_cast<char>(0x80 | ((code_point >> 12) & 0x3f)));
output.push_back(static_cast<char>(0x80 | ((code_point >> 6) & 0x3f)));
output.push_back(static_cast<char>(0x80 | (code_point & 0x3f)));
}
}
std::string encode_utf8(const std::wstring& input) {
std::string output;
output.reserve(input.size());
for (const wchar_t character : input) {
append_utf8_code_point(output, static_cast<std::uint32_t>(character));
}
return output;
}
class BoundedOutput {
public:
explicit BoundedOutput(std::size_t maximum_bytes)
: maximum_bytes_(maximum_bytes) {}
void append(
std::wstring::const_iterator first,
std::wstring::const_iterator last) {
if (truncated_) return;
for (; first != last; ++first) {
std::string encoded;
append_utf8_code_point(
encoded, static_cast<std::uint32_t>(*first));
if (value_.size() + encoded.size() > maximum_bytes_) {
truncated_ = true;
return;
}
value_ += encoded;
}
}
void append(const std::wstring& value) {
append(value.cbegin(), value.cend());
}
const std::string& value() const { return value_; }
bool truncated() const { return truncated_; }
private:
std::size_t maximum_bytes_;
std::string value_;
bool truncated_ = false;
};
template <typename Iterator>
void append_native_format_bounded(
BoundedOutput& output,
const std::match_results<Iterator>& match,
const std::wstring& replacement) {
for (std::size_t index = 0;
index < replacement.size() && !output.truncated();
++index) {
if (replacement[index] != L'$' || index + 1 == replacement.size()) {
output.append(
replacement.cbegin() + index,
replacement.cbegin() + index + 1);
continue;
}
const wchar_t next = replacement[index + 1];
if (next == L'$') {
output.append(
replacement.cbegin() + index + 1,
replacement.cbegin() + index + 2);
++index;
} else if (next == L'&') {
output.append(match[0].first, match[0].second);
++index;
} else if (next == L'`') {
output.append(match.prefix().first, match.prefix().second);
++index;
} else if (next == L'\'') {
output.append(match.suffix().first, match.suffix().second);
++index;
} else if (next >= L'0' && next <= L'9') {
std::size_t capture = static_cast<std::size_t>(next - L'0');
++index;
if (index + 1 < replacement.size() &&
replacement[index + 1] >= L'0' &&
replacement[index + 1] <= L'9') {
capture =
capture * 10 +
static_cast<std::size_t>(replacement[index + 1] - L'0');
++index;
}
output.append(match[capture].first, match[capture].second);
} else {
output.append(
replacement.cbegin() + index,
replacement.cbegin() + index + 1);
}
}
}
bool replacement_expansion_self_test() {
const std::wstring subject = L"xab!";
const std::wregex expression(L"(a)(b)?");
std::wsmatch match;
if (!std::regex_search(subject, match, expression)) return false;
const std::wstring fixtures[] = {
L"<$1:$2:$&>",
L"$$-$`-$'",
L"$0-$00-$01-$99",
L"$x-$",
};
for (const auto& replacement : fixtures) {
BoundedOutput bounded(4096);
append_native_format_bounded(bounded, match, replacement);
if (bounded.truncated() ||
bounded.value() != encode_utf8(match.format(replacement))) {
return false;
}
}
const std::wstring large_subject(4096, L'a');
const std::wregex large_expression(L"(a+)");
std::wsmatch large_match;
if (!std::regex_search(
large_subject, large_match, large_expression)) {
return false;
}
std::wstring amplifying_replacement;
amplifying_replacement.reserve(65'536);
for (std::size_t index = 0; index < 32'768; ++index) {
amplifying_replacement += L"$1";
}
BoundedOutput adversarial(5);
append_native_format_bounded(
adversarial, large_match, amplifying_replacement);
return adversarial.truncated() && adversarial.value() == "aaaaa";
}
val failure(
const std::string& phase,
const std::string& code,
const std::string& message) {
val result = val::object();
result.set("abi", kBridgeAbiVersion);
result.set("ok", false);
result.set("phase", phase);
result.set("code", code);
result.set(
"message",
message.size() <= 1024 ? message : message.substr(0, 1024));
return result;
}
std::regex_constants::syntax_option_type syntax_options(
const val& request) {
using namespace std::regex_constants;
auto result = syntax_option_type{};
const val options = request["options"];
std::string grammar = "ECMAScript";
const val configured_grammar = options["grammar"];
if (!configured_grammar.isUndefined()) {
grammar = configured_grammar.as<std::string>();
}
if (grammar == "ECMAScript") {
result = ECMAScript;
} else if (grammar == "basic") {
result = basic;
} else if (grammar == "extended") {
result = extended;
} else if (grammar == "awk") {
result = awk;
} else if (grammar == "grep") {
result = grep;
} else if (grammar == "egrep") {
result = egrep;
} else {
throw std::invalid_argument("Unsupported std::regex grammar.");
}
const std::string flags = request["flags"].as<std::string>();
if (flags.find('i') != std::string::npos) result |= icase;
if (flags.find('n') != std::string::npos) result |= nosubs;
if (flags.find('o') != std::string::npos) result |= optimize;
if (flags.find('c') != std::string::npos) result |= collate;
return result;
}
template <typename Iterator>
val match_record(
const std::match_results<Iterator>& match,
Iterator subject_begin) {
val record = val::object();
val span = val::array();
span.call<void>(
"push",
static_cast<double>(std::distance(subject_begin, match[0].first)));
span.call<void>(
"push",
static_cast<double>(std::distance(subject_begin, match[0].second)));
record.set("span", span);
val captures = val::array();
for (std::size_t group = 1; group < match.size(); ++group) {
if (!match[group].matched) {
captures.call<void>("push", val::null());
continue;
}
val capture = val::array();
capture.call<void>(
"push",
static_cast<double>(
std::distance(subject_begin, match[group].first)));
capture.call<void>(
"push",
static_cast<double>(
std::distance(subject_begin, match[group].second)));
captures.call<void>("push", capture);
}
record.set("captures", captures);
return record;
}
val cpp_regex_identity() {
val identity = val::object();
identity.set("implementation", "libc++ std::wregex");
identity.set("cplusplus", static_cast<double>(__cplusplus));
#ifdef __EMSCRIPTEN_MAJOR__
identity.set(
"emscripten",
std::to_string(__EMSCRIPTEN_MAJOR__) + "." +
std::to_string(__EMSCRIPTEN_MINOR__) + "." +
std::to_string(__EMSCRIPTEN_TINY__));
#else
identity.set("emscripten", "unknown");
#endif
identity.set("wcharBits", static_cast<double>(sizeof(wchar_t) * 8));
identity.set(
"replacementSelfTest", replacement_expansion_self_test());
return identity;
}
val cpp_regex_run(const val& request) {
try {
if (request["abi"].as<int>() != kBridgeAbiVersion) {
return failure("bridge", "unsupported-abi", "Unsupported bridge ABI.");
}
const std::string operation = request["operation"].as<std::string>();
if (operation != "execute" && operation != "replace") {
return failure(
"bridge", "invalid-operation", "Unsupported bridge operation.");
}
const std::wstring pattern =
decode_utf8(request["pattern"].as<std::string>());
const std::wstring subject =
decode_utf8(request["subject"].as<std::string>());
const std::wstring replacement =
operation == "replace"
? decode_utf8(request["replacement"].as<std::string>())
: std::wstring();
const std::string flags = request["flags"].as<std::string>();
const bool global = flags.find('g') != std::string::npos;
const auto maximum_matches =
request["maximumMatches"].as<std::uint32_t>();
const auto maximum_capture_rows =
request["maximumCaptureRows"].as<std::uint32_t>();
const auto maximum_output_bytes =
operation == "replace"
? request["maximumOutputBytes"].as<std::uint32_t>()
: 1U;
std::wregex expression;
try {
expression.assign(pattern, syntax_options(request));
} catch (const std::regex_error& error) {
return failure("compile", "regex-error", error.what());
}
const std::size_t group_count = expression.mark_count();
if (group_count > kMaximumCaptureGroups) {
return failure(
"compile",
"capture-group-limit",
"The pattern exceeds the 1,000 capture-group bridge limit.");
}
val matches = val::array();
std::size_t match_count = 0;
std::size_t capture_rows = 0;
bool results_truncated = false;
BoundedOutput output(maximum_output_bytes);
auto next_output = subject.cbegin();
using Iterator = std::wstring::const_iterator;
std::regex_iterator<Iterator> current(
subject.cbegin(), subject.cend(), expression);
const std::regex_iterator<Iterator> end;
for (; current != end; ++current) {
const auto& match = *current;
const std::size_t rows = std::max<std::size_t>(1, group_count);
if (match_count >= maximum_matches ||
capture_rows + rows > maximum_capture_rows) {
results_truncated = true;
break;
}
matches.call<void>(
"push", match_record(match, subject.cbegin()));
++match_count;
capture_rows += rows;
if (operation == "replace") {
output.append(next_output, match[0].first);
append_native_format_bounded(output, match, replacement);
next_output = match[0].second;
}
if (!global) {
++current;
break;
}
}
if (operation == "replace") {
output.append(next_output, subject.cend());
}
val result = val::object();
result.set("abi", kBridgeAbiVersion);
result.set("ok", true);
result.set("groupCount", static_cast<double>(group_count));
result.set("groupNames", val::array());
result.set("matches", matches);
result.set("resultsTruncated", results_truncated);
if (operation == "replace") {
result.set("output", output.value());
result.set(
"outputBytes", static_cast<double>(output.value().size()));
result.set("outputTruncated", output.truncated());
}
return result;
} catch (const std::exception& error) {
return failure("bridge", "bridge-error", error.what());
} catch (...) {
return failure(
"bridge", "bridge-error", "Unknown C++ bridge failure.");
}
}
} // namespace
EMSCRIPTEN_BINDINGS(regex_tools_cpp_bridge) {
emscripten::function("regexToolsCppIdentity", &cpp_regex_identity);
emscripten::function("regexToolsCppRun", &cpp_regex_run);
}

818
engines/dotnet/Program.cs Normal file
View File

@@ -0,0 +1,818 @@
using System.Buffers;
using System.Globalization;
using System.Runtime.InteropServices.JavaScript;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
public static partial class RegexBridge
{
private const int AbiVersion = 1;
private const int MaximumCaptureGroups = 1_000;
private static readonly TimeSpan MatchTimeout = TimeSpan.FromSeconds(9);
private static readonly Lazy<bool> ReplacementParity = new(
ReplacementParitySelfTest
);
[JSExport]
public static string Identity()
{
if (!ReplacementParity.Value)
throw new InvalidOperationException(
"The bounded replacement parser failed its native parity self-test."
);
return "dotnet-regex|10.0.10|System.Text.RegularExpressions|utf16|culture-invariant|replacement-parity";
}
[JSExport]
public static string Run(string requestJson)
{
try
{
using var document = JsonDocument.Parse(
requestJson,
new JsonDocumentOptions
{
AllowTrailingCommas = false,
CommentHandling = JsonCommentHandling.Disallow,
MaxDepth = 16,
}
);
var root = document.RootElement;
if (RequiredInt(root, "abi") != AbiVersion)
return Failure("bridge", "unsupported-abi", "Unsupported bridge ABI.");
var operation = RequiredString(root, "operation", 16);
if (operation is not ("execute" or "replace"))
return Failure(
"bridge",
"invalid-operation",
"Unsupported bridge operation."
);
var pattern = RequiredString(root, "pattern", 65_536);
var subject = RequiredString(root, "subject", 16 * 1024 * 1024);
var flags = RequiredString(root, "flags", 32);
var maximumMatches = RequiredInt(root, "maximumMatches");
var maximumCaptureRows = RequiredInt(root, "maximumCaptureRows");
if (
maximumMatches is < 1 or > 10_000
|| maximumCaptureRows is < 1 or > 100_000
)
return Failure(
"bridge",
"invalid-limit",
"Result limits are outside the bridge contract."
);
var replacement =
operation == "replace"
? RequiredString(root, "replacement", 65_536)
: string.Empty;
var maximumOutputBytes =
operation == "replace" ? RequiredInt(root, "maximumOutputBytes") : 1;
if (
operation == "replace"
&& maximumOutputBytes is < 1 or > 64 * 1024 * 1024
)
return Failure(
"bridge",
"invalid-limit",
"Output limit is outside the bridge contract."
);
Regex expression;
try
{
expression = new Regex(
pattern,
RegexOptionsFor(flags) | RegexOptions.CultureInvariant,
MatchTimeout
);
}
catch (RegexParseException error)
{
return Failure(
"compile",
"regex-parse-error",
error.Message,
error.Offset
);
}
catch (ArgumentException error)
{
return Failure("compile", "regex-parse-error", error.Message);
}
var numbers = expression.GetGroupNumbers();
var groupCount = numbers.Length == 0 ? 0 : numbers.Max();
if (groupCount > MaximumCaptureGroups)
return Failure(
"compile",
"capture-group-limit",
"The pattern exceeds the 1,000 capture-group bridge limit."
);
var presentNumbers = numbers.ToHashSet();
var groupNames = expression
.GetGroupNames()
.Select(name => (Name: name, Number: expression.GroupNumberFromName(name)))
.Where(item =>
item.Number > 0
&& !int.TryParse(
item.Name,
NumberStyles.None,
CultureInfo.InvariantCulture,
out _
)
)
.OrderBy(item => item.Number)
.ToArray();
ReplacementProgram? replacementProgram = null;
if (operation == "replace")
{
try
{
replacementProgram = ReplacementProgram.Parse(
replacement,
expression,
presentNumbers
);
}
catch (ArgumentException error)
{
return Failure(
"replacement",
"replacement-error",
error.Message
);
}
}
var records = new List<MatchRecord>();
var captureRows = 0;
var resultsTruncated = false;
var global = flags.Contains('g');
try
{
for (var match = expression.Match(subject); match.Success; match = match.NextMatch())
{
var rows = Math.Max(1, groupCount);
if (
records.Count >= maximumMatches
|| captureRows + rows > maximumCaptureRows
)
{
resultsTruncated = true;
break;
}
var captures = new NativeSpan?[groupCount];
for (var number = 1; number <= groupCount; number++)
{
if (!presentNumbers.Contains(number))
continue;
var group = match.Groups[number];
if (group.Success)
captures[number - 1] = new NativeSpan(
group.Index,
group.Index + group.Length
);
}
records.Add(
new MatchRecord(
new NativeSpan(match.Index, match.Index + match.Length),
captures,
match
)
);
captureRows += rows;
if (!global)
break;
}
}
catch (RegexMatchTimeoutException error)
{
return Failure("match", "match-timeout", error.Message);
}
BoundedUtf8Output? output = null;
if (operation == "replace")
{
output = new BoundedUtf8Output(maximumOutputBytes);
var sourcePosition = 0;
try
{
foreach (var record in records.OrderBy(record => record.Span.Start))
{
output.Append(
subject.AsSpan(
sourcePosition,
record.Span.Start - sourcePosition
)
);
AppendReplacement(
output,
subject,
record.Match,
replacementProgram!
);
sourcePosition = record.Span.End;
}
output.Append(subject.AsSpan(sourcePosition));
}
catch (ArgumentException error)
{
return Failure(
"replacement",
"replacement-error",
error.Message
);
}
}
return Success(
groupCount,
groupNames,
records,
resultsTruncated,
output
);
}
catch (JsonException error)
{
return Failure("bridge", "invalid-json", error.Message);
}
catch (Exception error)
{
return Failure("bridge", "bridge-error", error.Message);
}
}
private static RegexOptions RegexOptionsFor(string flags)
{
var options = RegexOptions.None;
foreach (var flag in flags)
options |= flag switch
{
'g' => RegexOptions.None,
'i' => RegexOptions.IgnoreCase,
'm' => RegexOptions.Multiline,
's' => RegexOptions.Singleline,
'n' => RegexOptions.ExplicitCapture,
'x' => RegexOptions.IgnorePatternWhitespace,
'r' => RegexOptions.RightToLeft,
'c' => RegexOptions.CultureInvariant,
'b' => RegexOptions.NonBacktracking,
_ => throw new ArgumentException($"Unsupported .NET flag: {flag}."),
};
return options;
}
private static string RequiredString(JsonElement root, string name, int maximumLength)
{
if (
!root.TryGetProperty(name, out var property)
|| property.ValueKind != JsonValueKind.String
)
throw new JsonException($"{name} must be a string.");
var value = property.GetString()!;
if (value.Length > maximumLength)
throw new JsonException($"{name} exceeds its bounded contract.");
return value;
}
private static int RequiredInt(JsonElement root, string name)
{
if (
!root.TryGetProperty(name, out var property)
|| !property.TryGetInt32(out var value)
)
throw new JsonException($"{name} must be a 32-bit integer.");
return value;
}
private static string Failure(
string phase,
string code,
string message,
int? position = null
)
{
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream))
{
writer.WriteStartObject();
writer.WriteNumber("abi", AbiVersion);
writer.WriteBoolean("ok", false);
writer.WriteString("phase", phase);
writer.WriteString("code", code);
writer.WriteString(
"message",
message.Length <= 1_024 ? message : message[..1_024]
);
if (position >= 0)
writer.WriteNumber("position", position.Value);
writer.WriteEndObject();
}
return Encoding.UTF8.GetString(stream.ToArray());
}
private static string Success(
int groupCount,
IEnumerable<(string Name, int Number)> groupNames,
IEnumerable<MatchRecord> records,
bool resultsTruncated,
BoundedUtf8Output? output
)
{
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream))
{
writer.WriteStartObject();
writer.WriteNumber("abi", AbiVersion);
writer.WriteBoolean("ok", true);
writer.WriteNumber("groupCount", groupCount);
writer.WriteStartArray("groupNames");
foreach (var group in groupNames)
{
writer.WriteStartArray();
writer.WriteNumberValue(group.Number);
writer.WriteStringValue(group.Name);
writer.WriteEndArray();
}
writer.WriteEndArray();
writer.WriteStartArray("matches");
foreach (var record in records)
{
writer.WriteStartObject();
WriteSpan(writer, "span", record.Span);
writer.WriteStartArray("captures");
foreach (var capture in record.Captures)
{
if (capture is { } span)
WriteSpan(writer, null, span);
else
writer.WriteNullValue();
}
writer.WriteEndArray();
writer.WriteEndObject();
}
writer.WriteEndArray();
writer.WriteBoolean("resultsTruncated", resultsTruncated);
if (output is not null)
{
writer.WriteBase64String("outputBase64", output.Bytes);
writer.WriteNumber("outputBytes", output.ByteCount);
writer.WriteBoolean("outputTruncated", output.Truncated);
}
writer.WriteEndObject();
}
return Encoding.UTF8.GetString(stream.ToArray());
}
private static void WriteSpan(
Utf8JsonWriter writer,
string? propertyName,
NativeSpan span
)
{
if (propertyName is null)
writer.WriteStartArray();
else
writer.WriteStartArray(propertyName);
writer.WriteNumberValue(span.Start);
writer.WriteNumberValue(span.End);
writer.WriteEndArray();
}
private readonly record struct NativeSpan(int Start, int End);
private sealed record MatchRecord(
NativeSpan Span,
NativeSpan?[] Captures,
Match Match
);
private static void AppendReplacement(
BoundedUtf8Output output,
string subject,
Match match,
ReplacementProgram replacement
)
{
foreach (var token in replacement.Tokens)
{
switch (token.Kind)
{
case ReplacementTokenKind.Literal:
output.Append(
replacement.Template.AsSpan(token.Start, token.Length)
);
break;
case ReplacementTokenKind.Group:
{
var group = match.Groups[token.GroupNumber];
if (group.Success)
output.Append(subject.AsSpan(group.Index, group.Length));
break;
}
case ReplacementTokenKind.LeftPortion:
output.Append(subject.AsSpan(0, match.Index));
break;
case ReplacementTokenKind.RightPortion:
{
var start = match.Index + match.Length;
output.Append(subject.AsSpan(start));
break;
}
case ReplacementTokenKind.LastGroup:
{
var group = match.Groups[replacement.LastGroupNumber];
if (group.Success)
output.Append(subject.AsSpan(group.Index, group.Length));
break;
}
case ReplacementTokenKind.WholeString:
output.Append(subject.AsSpan());
break;
}
}
}
private static bool ReplacementParitySelfTest()
{
try
{
var expression = new Regex(
"(?<word>a)(b)?(?<tail>c)?",
RegexOptions.CultureInvariant,
MatchTimeout
);
var presentNumbers = expression.GetGroupNumbers().ToHashSet();
var templates = new[]
{
"$2:$1/${word}/${3}/$$/$&/$`/$'/$+/$_/$99/${missing}/$",
"${1}$01-$0",
"literal",
};
for (
var match = expression.Match("zab a");
match.Success;
match = match.NextMatch()
)
{
foreach (var template in templates)
{
var replacement = ReplacementProgram.Parse(
template,
expression,
presentNumbers
);
var bounded = new BoundedUtf8Output(16 * 1024);
AppendReplacement(
bounded,
"zab a",
match,
replacement
);
if (
bounded.Truncated
|| Encoding.UTF8.GetString(bounded.Bytes)
!= match.Result(template)
)
return false;
}
}
try
{
_ = ReplacementProgram.Parse(
"$2147483648",
expression,
presentNumbers
);
return false;
}
catch (ArgumentException)
{
try
{
_ = expression.Match("a").Result("$2147483648");
return false;
}
catch (ArgumentException)
{
// Both parsers reject an overflowing numeric reference.
}
}
var largeSubject = new string('a', 256 * 1024);
var largeExpression = new Regex(
"(a+)",
RegexOptions.CultureInvariant,
MatchTimeout
);
var amplifyingTemplate = string.Concat(
Enumerable.Repeat("$1", 32_768)
);
var amplifyingProgram = ReplacementProgram.Parse(
amplifyingTemplate,
largeExpression,
largeExpression.GetGroupNumbers().ToHashSet()
);
var adversarial = new BoundedUtf8Output(5);
AppendReplacement(
adversarial,
largeSubject,
largeExpression.Match(largeSubject),
amplifyingProgram
);
return adversarial.Truncated
&& Encoding.UTF8.GetString(adversarial.Bytes) == "aaaaa";
}
catch
{
return false;
}
}
private enum ReplacementTokenKind
{
Literal,
Group,
LeftPortion,
RightPortion,
LastGroup,
WholeString,
}
private readonly record struct ReplacementToken(
ReplacementTokenKind Kind,
int Start = 0,
int Length = 0,
int GroupNumber = 0
);
private sealed record ReplacementProgram(
string Template,
ReplacementToken[] Tokens,
int LastGroupNumber
)
{
public static ReplacementProgram Parse(
string template,
Regex expression,
HashSet<int> presentNumbers
)
{
var tokens = new List<ReplacementToken>();
var literalStart = 0;
var cursor = 0;
void AddLiteral(int end)
{
if (end > literalStart)
tokens.Add(
new ReplacementToken(
ReplacementTokenKind.Literal,
literalStart,
end - literalStart
)
);
}
void AddRecognized(
int dollar,
int end,
ReplacementToken token
)
{
AddLiteral(dollar);
tokens.Add(token);
cursor = end;
literalStart = end;
}
while (cursor < template.Length)
{
var dollar = template.IndexOf('$', cursor);
if (dollar < 0)
break;
if (dollar + 1 >= template.Length)
{
cursor = dollar + 1;
continue;
}
var next = template[dollar + 1];
if (next == '$')
{
AddRecognized(
dollar,
dollar + 2,
new ReplacementToken(
ReplacementTokenKind.Literal,
dollar + 1,
1
)
);
continue;
}
if (next == '&')
{
AddRecognized(
dollar,
dollar + 2,
new ReplacementToken(
ReplacementTokenKind.Group,
GroupNumber: 0
)
);
continue;
}
if (next == '`')
{
AddRecognized(
dollar,
dollar + 2,
new ReplacementToken(
ReplacementTokenKind.LeftPortion
)
);
continue;
}
if (next == '\'')
{
AddRecognized(
dollar,
dollar + 2,
new ReplacementToken(
ReplacementTokenKind.RightPortion
)
);
continue;
}
if (next == '+')
{
AddRecognized(
dollar,
dollar + 2,
new ReplacementToken(
ReplacementTokenKind.LastGroup
)
);
continue;
}
if (next == '_')
{
AddRecognized(
dollar,
dollar + 2,
new ReplacementToken(
ReplacementTokenKind.WholeString
)
);
continue;
}
var angled = next == '{' && dollar + 2 < template.Length;
var referenceStart = dollar + (angled ? 2 : 1);
if (
referenceStart < template.Length
&& template[referenceStart] is >= '0' and <= '9'
)
{
var number = 0;
var end = referenceStart;
while (
end < template.Length
&& template[end] is >= '0' and <= '9'
)
{
var digit = template[end] - '0';
if (
number > int.MaxValue / 10
|| (
number == int.MaxValue / 10
&& digit > int.MaxValue % 10
)
)
throw new ArgumentException(
"A replacement capture number exceeds Int32.MaxValue."
);
number = number * 10 + digit;
end++;
}
var syntaxComplete =
!angled
|| (
end < template.Length
&& template[end] == '}'
);
if (syntaxComplete && presentNumbers.Contains(number))
{
AddRecognized(
dollar,
angled ? end + 1 : end,
new ReplacementToken(
ReplacementTokenKind.Group,
GroupNumber: number
)
);
continue;
}
}
else if (
angled
&& referenceStart < template.Length
&& IsBoundaryWordCharacter(template[referenceStart])
)
{
var end = referenceStart + 1;
while (
end < template.Length
&& IsBoundaryWordCharacter(template[end])
)
end++;
if (end < template.Length && template[end] == '}')
{
var name = template[
referenceStart..end
];
var number = expression.GroupNumberFromName(name);
if (number >= 0)
{
AddRecognized(
dollar,
end + 1,
new ReplacementToken(
ReplacementTokenKind.Group,
GroupNumber: number
)
);
continue;
}
}
}
cursor = dollar + 1;
}
AddLiteral(template.Length);
var numbers = expression.GetGroupNumbers();
return new ReplacementProgram(
template,
tokens.ToArray(),
numbers.Length == 0 ? 0 : numbers[^1]
);
}
private static bool IsBoundaryWordCharacter(char value)
{
if (value is '\u200c' or '\u200d')
return true;
return CharUnicodeInfo.GetUnicodeCategory(value) switch
{
UnicodeCategory.UppercaseLetter => true,
UnicodeCategory.LowercaseLetter => true,
UnicodeCategory.TitlecaseLetter => true,
UnicodeCategory.ModifierLetter => true,
UnicodeCategory.OtherLetter => true,
UnicodeCategory.NonSpacingMark => true,
UnicodeCategory.DecimalDigitNumber => true,
UnicodeCategory.ConnectorPunctuation => true,
_ => false,
};
}
}
private sealed class BoundedUtf8Output(int maximumBytes)
{
private readonly ArrayBufferWriter<byte> _value = new();
public int ByteCount => _value.WrittenCount;
public bool Truncated { get; private set; }
public ReadOnlySpan<byte> Bytes => _value.WrittenSpan;
public void Append(ReadOnlySpan<char> value)
{
if (Truncated)
return;
while (!value.IsEmpty)
{
var status = Rune.DecodeFromUtf16(value, out var rune, out var consumed);
if (status != OperationStatus.Done)
{
rune = Rune.ReplacementChar;
consumed = 1;
}
var width = rune.Utf8SequenceLength;
if (ByteCount + width > maximumBytes)
{
Truncated = true;
return;
}
var destination = _value.GetSpan(width);
var written = rune.EncodeToUtf8(destination);
_value.Advance(written);
value = value[consumed..];
}
}
}
}

26
engines/dotnet/README.md Normal file
View File

@@ -0,0 +1,26 @@
# .NET regex engine
This is a fixed `[JSExport]` bridge over .NET 10.0.10
`System.Text.RegularExpressions`, built with SDK 10.0.302 for `browser-wasm`.
It always applies `RegexOptions.CultureInvariant` for deterministic local
results. Native match positions are UTF-16 offsets. The project uses
WebAssembly library mode because its `[JSExport]` methods are hosted directly
inside a module worker and do not require an executable entry point.
The bridge receives one JSON value and never evaluates user input as managed or
JavaScript source. A nine-second native regex timeout complements the app's
shorter killable-worker deadline. Match, capture-row, pattern, subject and
replacement-output limits are enforced in managed code as a second boundary.
Replacement templates are parsed once by a fixed streaming implementation of
.NET's `$$`, numbered/named-group, whole-match, left/right-context, last-group
and whole-input tokens. Engine startup compares that implementation with
native `Match.Result` on a parity corpus. Successful output crosses the JS
export as bounded UTF-8 bytes in canonical base64, avoiding unbounded
intermediate replacement strings and JSON escaping amplification.
Build from the pinned SDK plus `wasm-tools` workload:
```sh
/absolute/path/to/dotnet publish engines/dotnet/RegexTools.DotNet.csproj \
--configuration Release
```

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputType>Library</OutputType>
<InvariantGlobalization>true</InvariantGlobalization>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>RegexTools.DotNet</AssemblyName>
<RootNamespace>RegexToolsDotNet</RootNamespace>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Deterministic>true</Deterministic>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>full</TrimMode>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,2 @@
// Fixed entry point retained by the WebAssembly SDK publish pipeline.
// Regex Tools imports _framework/dotnet.js directly inside its engine worker.

26
engines/go/README.md Normal file
View File

@@ -0,0 +1,26 @@
# Go regexp WebAssembly engine
This directory is the fixed bridge around Go 1.26.5's standard-library
`regexp` package. It is compiled with the official `go1.26.5` toolchain for
`GOOS=js GOARCH=wasm`; `public/engines/go/wasm_exec.mjs` must come from that
same toolchain.
The bridge accepts JSON data only. The adapter measures the exact encoded
request size, and the native cap includes JSON's worst-case sixfold escaping
for every accepted string field. It implements native RE2-family Go syntax,
native UTF-8 byte offsets, `SubexpNames`, `Find(All)StringSubmatchIndex`, and
`Regexp.ExpandString` replacement templates. Application flags `i`, `m`, `s`
and `U` become Go inline flags; `g` selects native global iteration.
Replacement uses a bounded streaming implementation of `Regexp.ExpandString`
grammar. Load-time differential fixtures compare it with the native API, and
capture references stop expanding as soon as the UTF-8 output cap is reached.
The bounded bytes cross the JSON bridge as base64, so control-heavy output has
a fixed 4:3 transport expansion instead of JSON's content-dependent escaping.
Go deliberately excludes look-around and backreferences. Its global iterator
also ignores an empty match that abuts the preceding match. Those behaviours
are tested rather than emulated.
The bridge independently caps pattern, subject, match, capture-row and output
sizes. Replacement output is clipped only at a complete UTF-8 boundary.

5
engines/go/go.mod Normal file
View File

@@ -0,0 +1,5 @@
module git.add-ideas.de/lotobo/regex-tools/engines/go
go 1.26.0
toolchain go1.26.5

521
engines/go/main.go Normal file
View File

@@ -0,0 +1,521 @@
// Regex Tools Go engine bridge.
//
// The WebAssembly module exposes two fixed callbacks. User-controlled values
// enter only through JSON data and are handed to the standard-library regexp
// package; no Go or JavaScript source is evaluated.
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"regexp"
"runtime"
"sort"
"strings"
"syscall/js"
"unicode"
"unicode/utf8"
)
const (
bridgeABIVersion = 1
expectedGoVersion = "go1.26.5"
maximumPatternBytes = 256 * 1024
maximumSubjectBytes = 16 * 1024 * 1024
maximumReplacementBytes = 256 * 1024
maximumMatches = 10_000
maximumCaptureRows = 100_000
maximumCaptureGroups = 1_000
maximumOutputBytes = 64 * 1024 * 1024
maximumRequestJSONBytes = 6*(maximumSubjectBytes+maximumPatternBytes+maximumReplacementBytes) + 64*1024
maximumErrorMessageBytes = 1_024
bridgeInstallerGlobalName = "__regexToolsInstallGoBridge"
)
type bridgeRequest struct {
ABI int `json:"abi"`
Operation string `json:"operation"`
Pattern string `json:"pattern"`
Flags string `json:"flags"`
Options map[string]json.RawMessage `json:"options"`
Subject string `json:"subject"`
ScanAll bool `json:"scanAll"`
MaximumMatches int `json:"maximumMatches"`
MaximumCaptureRows int `json:"maximumCaptureRows"`
Replacement *string `json:"replacement,omitempty"`
MaximumOutputBytes *int `json:"maximumOutputBytes,omitempty"`
}
type bridgeFailure struct {
ABI int `json:"abi"`
OK bool `json:"ok"`
Phase string `json:"phase"`
Code string `json:"code"`
Message string `json:"message"`
Position *int `json:"position,omitempty"`
}
type nativeMatch struct {
Span [2]int `json:"span"`
Captures []*[2]int `json:"captures"`
}
type bridgeSuccess struct {
ABI int `json:"abi"`
OK bool `json:"ok"`
GroupCount int `json:"groupCount"`
GroupNames [][2]any `json:"groupNames"`
Matches []nativeMatch `json:"matches"`
ResultsTruncated bool `json:"resultsTruncated"`
OutputBase64 *string `json:"outputBase64,omitempty"`
OutputBytes *int `json:"outputBytes,omitempty"`
OutputTruncated *bool `json:"outputTruncated,omitempty"`
}
type identityEnvelope struct {
ABI int `json:"abi"`
OK bool `json:"ok"`
Identity map[string]any `json:"identity"`
}
func boundedMessage(value string) string {
if len(value) <= maximumErrorMessageBytes {
return value
}
end := maximumErrorMessageBytes - len("…")
for end > 0 && !utf8.ValidString(value[:end]) {
end--
}
return value[:end] + "…"
}
func marshal(value any) string {
encoded, err := json.Marshal(value)
if err == nil {
return string(encoded)
}
fallback, _ := json.Marshal(bridgeFailure{
ABI: bridgeABIVersion,
OK: false,
Phase: "bridge",
Code: "serialization-error",
Message: "The Go bridge could not serialize its bounded result.",
})
return string(fallback)
}
func failure(phase, code string, err any) string {
return marshal(bridgeFailure{
ABI: bridgeABIVersion,
OK: false,
Phase: phase,
Code: code,
Message: boundedMessage(fmt.Sprint(err)),
})
}
func decodeRequest(encoded string) (bridgeRequest, string) {
var request bridgeRequest
if len(encoded) > maximumRequestJSONBytes {
return request, failure("bridge", "request-limit", "The encoded request exceeds the bridge limit.")
}
decoder := json.NewDecoder(strings.NewReader(encoded))
decoder.DisallowUnknownFields()
if err := decoder.Decode(&request); err != nil {
return request, failure("bridge", "invalid-request", err)
}
if decoder.More() {
return request, failure("bridge", "invalid-request", "The encoded request contains trailing JSON values.")
}
return request, ""
}
func validateRequest(request bridgeRequest) string {
if request.ABI != bridgeABIVersion {
return failure("bridge", "abi-mismatch", "The bridge ABI version is unsupported.")
}
if request.Operation != "execute" && request.Operation != "replace" {
return failure("bridge", "invalid-operation", "The bridge operation is unsupported.")
}
if len(request.Options) != 0 {
return failure("bridge", "unsupported-option", "Go regexp does not accept engine options.")
}
if !utf8.ValidString(request.Pattern) || len(request.Pattern) > maximumPatternBytes {
return failure("bridge", "pattern-limit", "The pattern is invalid UTF-8 or exceeds the bridge limit.")
}
if !utf8.ValidString(request.Subject) || len(request.Subject) > maximumSubjectBytes {
return failure("bridge", "subject-limit", "The subject is invalid UTF-8 or exceeds the bridge limit.")
}
if request.MaximumMatches < 1 || request.MaximumMatches > maximumMatches ||
request.MaximumCaptureRows < 1 || request.MaximumCaptureRows > maximumCaptureRows {
return failure("bridge", "result-limit", "The requested result bounds are outside the bridge contract.")
}
seenFlags := make(map[rune]bool)
for _, flag := range request.Flags {
if !strings.ContainsRune("gimsU", flag) || seenFlags[flag] {
return failure("bridge", "unsupported-flag", "The request contains an unsupported or duplicate Go flag.")
}
seenFlags[flag] = true
}
if request.Operation == "execute" {
if request.Replacement != nil || request.MaximumOutputBytes != nil {
return failure("bridge", "invalid-request", "Execution requests cannot contain replacement fields.")
}
return ""
}
if request.Replacement == nil || request.MaximumOutputBytes == nil {
return failure("bridge", "invalid-request", "Replacement requests require a template and output bound.")
}
if !utf8.ValidString(*request.Replacement) || len(*request.Replacement) > maximumReplacementBytes {
return failure("bridge", "replacement-limit", "The replacement is invalid UTF-8 or exceeds the bridge limit.")
}
if *request.MaximumOutputBytes < 1 || *request.MaximumOutputBytes > maximumOutputBytes {
return failure("bridge", "output-limit", "The output bound is outside the bridge contract.")
}
return ""
}
func compilePattern(pattern, flags string) (*regexp.Regexp, error) {
var modifiers strings.Builder
for _, flag := range "imsU" {
if strings.ContainsRune(flags, flag) {
modifiers.WriteRune(flag)
}
}
if modifiers.Len() != 0 {
pattern = "(?" + modifiers.String() + ")" + pattern
}
return regexp.Compile(pattern)
}
func materializeMatch(indices []int, groupCount int) nativeMatch {
record := nativeMatch{
Span: [2]int{indices[0], indices[1]},
Captures: make([]*[2]int, groupCount),
}
for group := 0; group < groupCount; group++ {
start := indices[2+group*2]
end := indices[3+group*2]
if start >= 0 {
span := [2]int{start, end}
record.Captures[group] = &span
}
}
return record
}
func collectMatches(
compiled *regexp.Regexp,
subject string,
global bool,
maximumMatchCount int,
maximumRows int,
) ([][]int, bool) {
rowsPerMatch := compiled.NumSubexp()
if rowsPerMatch < 1 {
rowsPerMatch = 1
}
allowed := maximumMatchCount
if rowBound := maximumRows / rowsPerMatch; rowBound < allowed {
allowed = rowBound
}
probeLimit := allowed + 1
var indices [][]int
if global {
indices = compiled.FindAllStringSubmatchIndex(subject, probeLimit)
} else if candidate := compiled.FindStringSubmatchIndex(subject); candidate != nil {
indices = [][]int{candidate}
}
if len(indices) <= allowed {
return indices, false
}
return indices[:allowed], true
}
type boundedOutput struct {
buffer bytes.Buffer
maximum int
truncated bool
}
func (output *boundedOutput) append(value string) {
if output.truncated || value == "" {
return
}
remaining := output.maximum - output.buffer.Len()
if len(value) <= remaining {
output.buffer.WriteString(value)
return
}
end := remaining
for end > 0 && !utf8.ValidString(value[:end]) {
end--
}
output.buffer.WriteString(value[:end])
output.truncated = true
}
func extractReplacementReference(value string) (name string, number int, rest string, ok bool) {
if value == "" {
return
}
braced := false
if value[0] == '{' {
braced = true
value = value[1:]
}
index := 0
for index < len(value) {
character, size := utf8.DecodeRuneInString(value[index:])
if !unicode.IsLetter(character) && !unicode.IsDigit(character) && character != '_' {
break
}
index += size
}
if index == 0 {
return
}
name = value[:index]
if braced {
if index >= len(value) || value[index] != '}' {
return
}
index++
}
number = 0
for position := 0; position < len(name); position++ {
if name[position] < '0' || name[position] > '9' || number >= 1e8 {
number = -1
break
}
number = number*10 + int(name[position]) - '0'
}
if name[0] == '0' && len(name) > 1 {
number = -1
}
rest = value[index:]
ok = true
return
}
func expandReplacementBounded(
output *boundedOutput,
compiled *regexp.Regexp,
template, subject string,
match []int,
) {
for len(template) > 0 && !output.truncated {
before, after, found := strings.Cut(template, "$")
if !found {
break
}
output.append(before)
if output.truncated {
return
}
template = after
if template != "" && template[0] == '$' {
output.append("$")
template = template[1:]
continue
}
name, number, rest, ok := extractReplacementReference(template)
if !ok {
output.append("$")
continue
}
template = rest
if number >= 0 {
if 2*number+1 < len(match) && match[2*number] >= 0 {
output.append(subject[match[2*number]:match[2*number+1]])
}
continue
}
for index, candidate := range compiled.SubexpNames() {
if name == candidate && 2*index+1 < len(match) && match[2*index] >= 0 {
output.append(subject[match[2*index]:match[2*index+1]])
break
}
}
}
output.append(template)
}
func replaceBounded(
compiled *regexp.Regexp,
subject, replacement string,
indices [][]int,
maximumBytes int,
) (string, int, bool) {
output := boundedOutput{maximum: maximumBytes}
cursor := 0
for _, match := range indices {
output.append(subject[cursor:match[0]])
expandReplacementBounded(&output, compiled, replacement, subject, match)
cursor = match[1]
}
output.append(subject[cursor:])
value := output.buffer.Bytes()
return base64.StdEncoding.EncodeToString(value), len(value), output.truncated
}
func run(encoded string) string {
request, requestError := decodeRequest(encoded)
if requestError != "" {
return requestError
}
if validationError := validateRequest(request); validationError != "" {
return validationError
}
compiled, err := compilePattern(request.Pattern, request.Flags)
if err != nil {
return failure("compile", "compile-error", err)
}
groupCount := compiled.NumSubexp()
if groupCount > maximumCaptureGroups {
return failure(
"compile",
"capture-group-limit",
fmt.Sprintf("The pattern declares %d capture groups; the bridge limit is %d.", groupCount, maximumCaptureGroups),
)
}
names := make([][2]any, 0)
for number, name := range compiled.SubexpNames() {
if number > 0 && name != "" {
names = append(names, [2]any{number, name})
}
}
sort.Slice(names, func(left, right int) bool {
return names[left][0].(int) < names[right][0].(int)
})
global := strings.ContainsRune(request.Flags, 'g')
indices, resultsTruncated := collectMatches(
compiled,
request.Subject,
global,
request.MaximumMatches,
request.MaximumCaptureRows,
)
records := make([]nativeMatch, len(indices))
for index, match := range indices {
records[index] = materializeMatch(match, groupCount)
}
result := bridgeSuccess{
ABI: bridgeABIVersion,
OK: true,
GroupCount: groupCount,
GroupNames: names,
Matches: records,
ResultsTruncated: resultsTruncated,
}
if request.Operation == "replace" {
outputBase64, outputBytes, outputTruncated := replaceBounded(
compiled,
request.Subject,
*request.Replacement,
indices,
*request.MaximumOutputBytes,
)
result.OutputBase64 = &outputBase64
result.OutputBytes = &outputBytes
result.OutputTruncated = &outputTruncated
}
return marshal(result)
}
func selfTest() bool {
if runtime.Version() != expectedGoVersion {
return false
}
compiled, err := regexp.Compile(`(?P<word>😀+)`)
if err != nil {
return false
}
match := compiled.FindStringSubmatchIndex("x😀😀")
if len(match) != 4 || match[0] != 1 || match[1] != 9 ||
match[2] != 1 || match[3] != 9 || compiled.SubexpNames()[1] != "word" {
return false
}
for _, template := range []string{
`${word}-$1-$$`,
`$1x|${1}x`,
`${missing}|$|${word`,
`$01|${01}|$1234567890`,
} {
expected := string(compiled.ExpandString(nil, template, "x😀😀", match))
bounded := boundedOutput{maximum: 4 * 1024}
expandReplacementBounded(&bounded, compiled, template, "x😀😀", match)
if bounded.truncated || bounded.buffer.String() != expected {
return false
}
}
adversarial := boundedOutput{maximum: 5}
expandReplacementBounded(
&adversarial,
compiled,
strings.Repeat("$word", 32*1024),
"x😀😀",
match,
)
if !adversarial.truncated || adversarial.buffer.String() != "😀" {
return false
}
empty := regexp.MustCompile("a*").FindAllStringIndex("baaab", -1)
return len(empty) == 3 &&
empty[0][0] == 0 && empty[0][1] == 0 &&
empty[1][0] == 1 && empty[1][1] == 4 &&
empty[2][0] == 5 && empty[2][1] == 5
}
func identity() string {
return marshal(identityEnvelope{
ABI: bridgeABIVersion,
OK: true,
Identity: map[string]any{
"bridge": "regex-tools-go-json",
"bridgeVersion": bridgeABIVersion,
"engine": "Go standard-library regexp",
"engineVersion": "1.26.5",
"goVersion": runtime.Version(),
"offsetUnit": "utf8-byte",
"package": "regexp",
"selfTest": selfTest(),
},
})
}
var retainedCallbacks []js.Func
func main() {
identityCallback := js.FuncOf(func(_ js.Value, arguments []js.Value) any {
if len(arguments) != 0 {
return failure("bridge", "invalid-request", "The identity callback does not accept arguments.")
}
return identity()
})
runCallback := js.FuncOf(func(_ js.Value, arguments []js.Value) (result any) {
defer func() {
if recovered := recover(); recovered != nil {
result = failure("bridge", "panic", "The Go bridge stopped an unexpected internal panic.")
}
}()
if len(arguments) != 1 || arguments[0].Type() != js.TypeString {
return failure("bridge", "invalid-request", "The run callback requires one JSON string.")
}
return run(arguments[0].String())
})
retainedCallbacks = []js.Func{identityCallback, runCallback}
installer := js.Global().Get(bridgeInstallerGlobalName)
if installer.Type() != js.TypeFunction {
panic("Regex Tools Go bridge installer is unavailable")
}
installer.Invoke(identityCallback, runCallback)
select {}
}

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,11 @@
This product includes software developed by Alexey Andreev
(http://teavm.org).
This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).
=============================================================================
= NOTICE file corresponding to section 4d of the Apache License Version 2.0 =
=============================================================================
This product includes software developed by
Joda.org (http://www.joda.org/).

25
engines/java/README.md Normal file
View File

@@ -0,0 +1,25 @@
# TeaVM Java regular-expression engine
This project compiles a bounded bridge around TeaVM 0.15.0's
`java.util.regex.Pattern` and `Matcher` class-library implementation to a
minified ES2015 module.
The runtime is intentionally identified as `TeaVM java.util.regex 0.15.0`.
TeaVM supplies its own Apache Harmony-derived Java class-library subset; the
generated engine is not OpenJDK and must not be presented as exact OpenJDK
semantics.
The `U` application flag is a compatibility request. TeaVM 0.15.0 does not
implement OpenJDK's `Pattern.UNICODE_CHARACTER_CLASS`; the bridge implies
Unicode case folding but retains TeaVM's predefined-character-class and word
boundary behaviour. The TypeScript adapter reports this boundary.
Replacement is delegated to TeaVM 0.15.0's native `Matcher` implementation.
That implementation recognizes only a single decimal digit after `$` (`$0`
through `$9`, subject to the compiled group count). It does not implement
OpenJDK's `${name}` named-replacement syntax; the bridge returns a
`replacement-error` when such a replacement is attempted.
Maven builds `target/generated/java-regex.mjs`. The repository pack script
verifies the pinned source identity, bridge source hashes, licence/notice and
generated module before it can be installed under `public/engines/java`.

84
engines/java/pom.xml Normal file
View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.addideas.regextools</groupId>
<artifactId>java-regex-engine</artifactId>
<version>0.1.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.release>11</maven.compiler.release>
<project.build.outputTimestamp>2026-06-06T15:27:10Z</project.build.outputTimestamp>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<teavm.version>0.15.0</teavm.version>
</properties>
<dependencies>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-classlib</artifactId>
<version>${teavm.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-jso</artifactId>
<version>${teavm.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>${maven.compiler.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<outputTimestamp>${project.build.outputTimestamp}</outputTimestamp>
</configuration>
</plugin>
<plugin>
<groupId>org.teavm</groupId>
<artifactId>teavm-maven-plugin</artifactId>
<version>${teavm.version}</version>
<executions>
<execution>
<id>java-regex-browser-engine</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<mainClass>de.addideas.regextools.javaengine.RegexBridge</mainClass>
<targetDirectory>${project.build.directory}/generated</targetDirectory>
<targetFileName>java-regex.mjs</targetFileName>
<targetType>JAVASCRIPT</targetType>
<jsModuleType>ES2015</jsModuleType>
<minifying>true</minifying>
<optimizationLevel>ADVANCED</optimizationLevel>
<debugInformationGenerated>false</debugInformationGenerated>
<sourceMapsGenerated>false</sourceMapsGenerated>
<sourceFilesCopied>false</sourceFilesCopied>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,346 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* The generated module links TeaVM 0.15.0 class-library code distributed
* under Apache-2.0. Its runtime identity is TeaVM java.util.regex, not OpenJDK.
*/
package de.addideas.regextools.javaengine;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.teavm.jso.JSExport;
public final class RegexBridge {
private static final int BRIDGE_ABI_VERSION = 1;
private static final String ENGINE_IDENTITY = "TeaVM java.util.regex 0.15.0";
private static final int MAXIMUM_CAPTURE_GROUPS = 1_000;
private static final int MAXIMUM_NATIVE_OUTPUT_UTF16 = 64 * 1024 * 1024;
private static final int FLAG_CASE_INSENSITIVE = 1 << 0;
private static final int FLAG_MULTILINE = 1 << 1;
private static final int FLAG_DOTALL = 1 << 2;
private static final int FLAG_UNICODE_CASE = 1 << 3;
private static final int FLAG_COMMENTS = 1 << 4;
private static final int FLAG_UNICODE_CHARACTER_COMPATIBILITY = 1 << 5;
private static final int FLAG_UNIX_LINES = 1 << 6;
private RegexBridge() {
}
public static void main(String[] arguments) {
// TeaVM requires a main class. All useful entry points are JS exports.
}
@JSExport
public static int bridgeAbiVersion() {
return BRIDGE_ABI_VERSION;
}
@JSExport
public static String engineIdentity() {
return ENGINE_IDENTITY;
}
@JSExport
public static int selfTest() {
try {
Matcher matcher = Pattern.compile("(?<=a)(b)\\1").matcher("abb");
if (!matcher.find() || matcher.start() != 1 || matcher.end() != 3
|| matcher.start(1) != 1 || matcher.end(1) != 2) {
return 1;
}
StringBuffer output = new StringBuffer();
matcher.appendReplacement(output, "<$1>");
matcher.appendTail(output);
return "a<b>".contentEquals(output) ? 0 : 2;
} catch (RuntimeException failure) {
return 3;
}
}
@JSExport
public static String execute(
String pattern,
String subject,
int applicationFlags,
boolean iterate,
int maximumMatches,
int maximumCaptureRows) {
return run(
pattern,
subject,
applicationFlags,
iterate,
maximumMatches,
maximumCaptureRows,
null);
}
@JSExport
public static String replace(
String pattern,
String subject,
String replacement,
int applicationFlags,
boolean iterate,
int maximumMatches,
int maximumCaptureRows) {
return run(
pattern,
subject,
applicationFlags,
iterate,
maximumMatches,
maximumCaptureRows,
replacement);
}
private static String run(
String patternText,
String subject,
int applicationFlags,
boolean iterate,
int maximumMatches,
int maximumCaptureRows,
String replacement) {
if (patternText == null || subject == null) {
return failure("bridge-error", "NullPointerException",
"Pattern and subject must not be null.", -1);
}
if (maximumMatches < 1 || maximumCaptureRows < 1) {
return failure("limit-error", "IllegalArgumentException",
"Result limits must be positive.", -1);
}
Pattern pattern;
try {
pattern = Pattern.compile(patternText, nativeFlags(applicationFlags));
} catch (PatternSyntaxException failure) {
String message = failure.getDescription();
if (message == null || message.length() == 0) {
message = failure.getMessage();
}
return failure("compile-error", "PatternSyntaxException", message, failure.getIndex());
} catch (RuntimeException failure) {
return failure("compile-error", failure.getClass().getSimpleName(),
safeMessage(failure, "TeaVM rejected the pattern."), -1);
}
Matcher matcher = pattern.matcher(subject);
int groupCount = matcher.groupCount();
if (groupCount > MAXIMUM_CAPTURE_GROUPS) {
return failure("limit-error", "CaptureGroupLimit",
"The pattern exceeds the 1,000 capture-group execution limit.", -1);
}
StringBuilder records = new StringBuilder();
StringBuffer output = replacement == null ? null : new StringBuffer();
int matchCount = 0;
int captureRows = 0;
int lastReplacementEnd = 0;
boolean resultsTruncated = false;
boolean outputTruncated = false;
try {
while (matcher.find()) {
int rowsForMatch = Math.max(1, groupCount);
if (matchCount >= maximumMatches
|| captureRows + rowsForMatch > maximumCaptureRows) {
resultsTruncated = true;
break;
}
appendNumber(records, matcher.start());
appendNumber(records, matcher.end());
for (int group = 1; group <= groupCount; group++) {
appendNumber(records, matcher.start(group));
appendNumber(records, matcher.end(group));
}
matchCount++;
captureRows += rowsForMatch;
if (output != null && !outputTruncated) {
long expansionLength = replacementExpansionLength(matcher, replacement);
long projectedLength = (long) output.length()
+ matcher.start() - lastReplacementEnd
+ expansionLength;
if (projectedLength > MAXIMUM_NATIVE_OUTPUT_UTF16) {
appendBounded(
output,
subject,
lastReplacementEnd,
matcher.start(),
MAXIMUM_NATIVE_OUTPUT_UTF16);
outputTruncated = true;
} else {
matcher.appendReplacement(output, replacement);
lastReplacementEnd = matcher.end();
}
}
if (!iterate) {
break;
}
}
if (output != null && !outputTruncated) {
long projectedLength = (long) output.length()
+ subject.length() - lastReplacementEnd;
if (projectedLength > MAXIMUM_NATIVE_OUTPUT_UTF16) {
appendBounded(
output,
subject,
lastReplacementEnd,
subject.length(),
MAXIMUM_NATIVE_OUTPUT_UTF16);
outputTruncated = true;
} else {
matcher.appendTail(output);
}
}
} catch (RuntimeException failure) {
String kind = replacement == null ? "execution-error" : "replacement-error";
String fallback = replacement == null
? "TeaVM failed while matching."
: "TeaVM Matcher rejected the replacement.";
return failure(kind, failure.getClass().getSimpleName(),
safeMessage(failure, fallback), -1);
}
FieldWriter result = new FieldWriter();
result.field("1");
result.field("ok");
result.number(groupCount);
result.bool(resultsTruncated);
result.number(matchCount);
result.raw(records);
if (output != null) {
result.bool(outputTruncated);
result.field(output.toString());
}
return result.toString();
}
private static int nativeFlags(int applicationFlags) {
int flags = 0;
if ((applicationFlags & FLAG_CASE_INSENSITIVE) != 0) {
flags |= Pattern.CASE_INSENSITIVE;
}
if ((applicationFlags & FLAG_MULTILINE) != 0) {
flags |= Pattern.MULTILINE;
}
if ((applicationFlags & FLAG_DOTALL) != 0) {
flags |= Pattern.DOTALL;
}
if ((applicationFlags & FLAG_UNICODE_CASE) != 0
|| (applicationFlags & FLAG_UNICODE_CHARACTER_COMPATIBILITY) != 0) {
flags |= Pattern.UNICODE_CASE;
}
if ((applicationFlags & FLAG_COMMENTS) != 0) {
flags |= Pattern.COMMENTS;
}
if ((applicationFlags & FLAG_UNIX_LINES) != 0) {
flags |= Pattern.UNIX_LINES;
}
return flags;
}
private static long replacementExpansionLength(Matcher matcher, String replacement) {
long length = 0;
for (int index = 0; index < replacement.length(); index++) {
char current = replacement.charAt(index);
if (current == '\\') {
index++;
if (index >= replacement.length()) {
throw new IndexOutOfBoundsException();
}
length++;
} else if (current == '$') {
index++;
if (index >= replacement.length()) {
throw new IllegalArgumentException("");
}
int group = Character.digit(replacement.charAt(index), 10);
if (group < 0) {
throw new IllegalArgumentException("");
}
String value = matcher.group(group);
// TeaVM 0.15.0's native replacement path dereferences this
// value too, including its unmatched-capture behaviour.
length += value.length();
} else {
length++;
}
if (length > MAXIMUM_NATIVE_OUTPUT_UTF16) {
return length;
}
}
return length;
}
private static void appendBounded(
StringBuffer output,
String value,
int start,
int end,
int maximumLength) {
int remaining = maximumLength - output.length();
if (remaining <= 0 || start >= end) {
return;
}
int boundedEnd = Math.min(end, start + remaining);
if (boundedEnd < end
&& boundedEnd > start
&& Character.isHighSurrogate(value.charAt(boundedEnd - 1))
&& Character.isLowSurrogate(value.charAt(boundedEnd))) {
boundedEnd--;
}
output.append(value, start, boundedEnd);
}
private static String failure(String status, String name, String message, int index) {
FieldWriter result = new FieldWriter();
result.field("1");
result.field(status);
result.field(name == null ? "Error" : name);
result.field(message == null ? "" : message);
result.number(index);
return result.toString();
}
private static String safeMessage(RuntimeException failure, String fallback) {
String message = failure.getMessage();
return message == null || message.length() == 0 ? fallback : message;
}
private static void appendNumber(StringBuilder output, int value) {
String encoded = Integer.toString(value);
output.append(encoded.length()).append(':').append(encoded);
}
private static final class FieldWriter {
private final StringBuilder output = new StringBuilder();
void field(String value) {
output.append(value.length()).append(':').append(value);
}
void number(int value) {
field(Integer.toString(value));
}
void bool(boolean value) {
field(value ? "1" : "0");
}
void raw(StringBuilder encodedFields) {
output.append(encodedFields);
}
@Override
public String toString() {
return output.toString();
}
}
}

View File

@@ -0,0 +1,207 @@
This software is Copyright (c) 2000 - 2017 by David Rolsky.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
The Artistic License 2.0
Copyright (c) 2000-2006, The Perl Foundation.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
This license establishes the terms under which a given free software
Package may be copied, modified, distributed, and/or redistributed.
The intent is that the Copyright Holder maintains some artistic
control over the development of that Package while still keeping the
Package available as open source and free software.
You are always permitted to make arrangements wholly outside of this
license directly with the Copyright Holder of a given Package. If the
terms of this license do not permit the full use that you propose to
make of the Package, you should contact the Copyright Holder and seek
a different licensing arrangement.
Definitions
"Copyright Holder" means the individual(s) or organization(s)
named in the copyright notice for the entire Package.
"Contributor" means any party that has contributed code or other
material to the Package, in accordance with the Copyright Holder's
procedures.
"You" and "your" means any person who would like to copy,
distribute, or modify the Package.
"Package" means the collection of files distributed by the
Copyright Holder, and derivatives of that collection and/or of
those files. A given Package may consist of either the Standard
Version, or a Modified Version.
"Distribute" means providing a copy of the Package or making it
accessible to anyone else, or in the case of a company or
organization, to others outside of your company or organization.
"Distributor Fee" means any fee that you charge for Distributing
this Package or providing support for this Package to another
party. It does not mean licensing fees.
"Standard Version" refers to the Package if it has not been
modified, or has been modified only in ways explicitly requested
by the Copyright Holder.
"Modified Version" means the Package, if it has been changed, and
such changes were not explicitly requested by the Copyright
Holder.
"Original License" means this Artistic License as Distributed with
the Standard Version of the Package, in its current version or as
it may be modified by The Perl Foundation in the future.
"Source" form means the source code, documentation source, and
configuration files for the Package.
"Compiled" form means the compiled bytecode, object code, binary,
or any other form resulting from mechanical transformation or
translation of the Source form.
Permission for Use and Modification Without Distribution
(1) You are permitted to use the Standard Version and create and use
Modified Versions for any purpose without restriction, provided that
you do not Distribute the Modified Version.
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the
Standard Version of this Package in any medium without restriction,
either gratis or for a Distributor Fee, provided that you duplicate
all of the original copyright notices and associated disclaimers. At
your discretion, such verbatim copies may or may not include a
Compiled form of the Package.
(3) You may apply any bug fixes, portability changes, and other
modifications made available from the Copyright Holder. The resulting
Package will still be considered the Standard Version, and as such
will be subject to the Original License.
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis
or for a Distributor Fee, and with or without a Compiled form of the
Modified Version) provided that you clearly document how it differs
from the Standard Version, including, but not limited to, documenting
any non-standard features, executables, or modules, and provided that
you do at least ONE of the following:
(a) make the Modified Version available to the Copyright Holder
of the Standard Version, under the Original License, so that the
Copyright Holder may include your modifications in the Standard
Version.
(b) ensure that installation of your Modified Version does not
prevent the user installing or running the Standard Version. In
addition, the Modified Version must bear a name that is different
from the name of the Standard Version.
(c) allow anyone who receives a copy of the Modified Version to
make the Source form of the Modified Version available to others
under
(i) the Original License or
(ii) a license that permits the licensee to freely copy,
modify and redistribute the Modified Version using the same
licensing terms that apply to the copy that the licensee
received, and requires that the Source form of the Modified
Version, and of any works derived from it, be made freely
available in that license fees are prohibited but Distributor
Fees are allowed.
Distribution of Compiled Forms of the Standard Version
or Modified Versions without the Source
(5) You may Distribute Compiled forms of the Standard Version without
the Source, provided that you include complete instructions on how to
get the Source of the Standard Version. Such instructions must be
valid at the time of your distribution. If these instructions, at any
time while you are carrying out such distribution, become invalid, you
must provide new instructions on demand or cease further distribution.
If you provide valid instructions or cease distribution within thirty
days after you become aware that the instructions are invalid, then
you do not forfeit any of your rights under this license.
(6) You may Distribute a Modified Version in Compiled form without
the Source, provided that you comply with Section 4 with respect to
the Source of the Modified Version.
Aggregating or Linking the Package
(7) You may aggregate the Package (either the Standard Version or
Modified Version) with other packages and Distribute the resulting
aggregation provided that you do not charge a licensing fee for the
Package. Distributor Fees are permitted, and licensing fees for other
components in the aggregation are permitted. The terms of this license
apply to the use and Distribution of the Standard or Modified Versions
as included in the aggregation.
(8) You are permitted to link Modified and Standard Versions with
other works, to embed the Package in a larger work of your own, or to
build stand-alone binary or bytecode versions of applications that
include the Package, and Distribute the result without restriction,
provided the result does not expose a direct interface to the Package.
Items That are Not Considered Part of a Modified Version
(9) Works (including, but not limited to, modules and scripts) that
merely extend or make use of the Package, do not, by themselves, cause
the Package to be a Modified Version. In addition, such works are not
considered parts of the Package itself, and are not subject to the
terms of this license.
General Provisions
(10) Any use, modification, and distribution of the Standard or
Modified Versions is governed by this Artistic License. By using,
modifying or distributing the Package, you accept this license. Do not
use, modify, or distribute the Package, if you do not accept this
license.
(11) If your Modified Version has been derived from a Modified
Version made by someone other than you, you are nevertheless required
to ensure that your Modified Version complies with the requirements of
this license.
(12) This license does not grant you the right to use any trademark,
service mark, tradename, or logo of the Copyright Holder.
(13) This license includes the non-exclusive, worldwide,
free-of-charge patent license to make, have made, use, offer to sell,
sell, import and otherwise transfer the Package with respect to any
patent claims licensable by the Copyright Holder that are necessarily
infringed by the Package. If you institute patent litigation
(including a cross-claim or counterclaim) against any party alleging
that the Package constitutes direct or contributory patent
infringement, then this Artistic License to you shall terminate on the
date that such litigation is filed.
(14) Disclaimer of Warranty:
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,101 @@
Emscripten is available under 2 licenses, the MIT license and the
University of Illinois/NCSA Open Source License.
Both are permissive open source licenses, with little if any
practical difference between them.
The reason for offering both is that (1) the MIT license is
well-known, while (2) the University of Illinois/NCSA Open Source
License allows Emscripten's code to be integrated upstream into
LLVM, which uses that license, should the opportunity arise.
The full text of both licenses follows.
==============================================================================
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal with the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimers.
Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimers
in the documentation and/or other materials provided with the
distribution.
Neither the names of Mozilla,
nor the names of its contributors may be used to endorse
or promote products derived from this Software without specific prior
written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
==============================================================================
This program uses portions of Node.js source code located in src/library_path.js,
in accordance with the terms of the MIT license. Node's license follows:
"""
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
"""
The musl libc project is bundled in this repo, and it has the MIT license, see
system/lib/libc/musl/COPYRIGHT
The third_party/ subdirectory contains code with other licenses. None of it is
used by default, but certain options use it (e.g., the optional closure compiler
flag will run closure compiler from third_party/).

68
engines/perl/NOTICE.txt Normal file
View File

@@ -0,0 +1,68 @@
Legacy WebPerl runtime notices
==============================
This directory contains the unmodified WebPerl v0.09-beta prebuilt runtime,
released in 2019 and explicitly treated by regex-tools as legacy beta software.
WebPerl
-------
Project: https://github.com/haukex/webperl
Release: v0.09-beta
Commit: 6f2173d29a2c2e3536e1de75ff5d291ae96ab348
Copyright (c) 2018 Hauke Daempfling, Leibniz Institute of Freshwater Ecology
and Inland Fisheries (IGB), Berlin, Germany.
WebPerl is distributed under the same terms as Perl 5: either the GNU General
Public License version 1 or later, or the Artistic License supplied with Perl 5.
The complete upstream texts are included as LICENSE-WebPerl-GPL.txt and
LICENSE-WebPerl-Artistic.txt.
Perl
----
The binary and data pack contain Perl v5.28.1 and its core library. Perl 5 is
distributed under the same GNU GPL / Artistic dual-license terms described
above. Exact upstream source is available from:
https://github.com/Perl/perl5/tree/v5.28.1
Emscripten
----------
The generated loader and WebAssembly runtime were built by upstream WebPerl
with Emscripten 1.38.28. Emscripten is dual-licensed under the MIT and
University of Illinois/NCSA licenses. The upstream 1.38.28 license text,
including its bundled-code notices, is included as LICENSE-Emscripten.txt.
Bundled CPAN additions
----------------------
The upstream prebuilt data pack also contains the modules selected by
WebPerl's pinned build:
- Cpanel::JSON::XS 4.09 — same terms as Perl 5;
- Devel::StackTrace 2.03 — Artistic License 2.0; its upstream distribution
license is included as LICENSE-Devel-StackTrace-Artistic-2.0.txt; and
- Future 0.39 — same terms as Perl 5.
The Devel::StackTrace license was reproduced byte-for-byte from
https://www.cpan.org/authors/id/D/DR/DROLSKY/Devel-StackTrace-2.03.tar.gz
(SHA-256 7618cd4ebe24e254c17085f4b418784ab503cb4cb3baf8f48a7be894e59ba848).
regex-tools uses Cpanel::JSON::XS only as the fixed bridge's bounded JSON
codec. It does not load Devel::StackTrace, Future, or WebPerl's JavaScript
interop module on the normal engine path. Those files remain present because
emperl.data is the unmodified, checksummed upstream prebuilt pack.
Security boundary
-----------------
The upstream generated emperl.js has one JavaScript eval(code) call in the
optional WebPerl JavaScript-interoperability import. regex-tools neither loads
nor calls that Perl module. User values cross the fixed bridge only as
exact-key, byte-bounded JSON in MEMFS; the sole Perl evaluator invocation is
the constant RegexTools::run_request(). The bounded metadata response is JSON,
while successful replacement UTF-8 bytes use a separate fixed MEMFS binary
file with exact worker-side length and encoding verification. Perl's
runtime-regex eval mode and regex code assertions are disabled.

66
engines/perl/README.md Normal file
View File

@@ -0,0 +1,66 @@
# Legacy Perl engine
This engine uses the unmodified prebuilt WebPerl `v0.09-beta` distribution,
which contains Perl `v5.28.1` compiled by Emscripten `1.38.28`. It is an
explicitly legacy, beta compatibility target. It is not current desktop Perl.
## Trust boundary
`regex_tools_bridge.pl` is fixed application source. The classic runtime worker
writes each exact-key, byte-bounded request as JSON to a fixed MEMFS path and
invokes only the constant Perl expression `RegexTools::run_request()`. The
metadata-only response uses a second bounded JSON file. Successful replacement
bytes use a third, fixed binary file; the worker checks its exact declared
length, output bound and canonical UTF-8 before supplying the decoded string to
the adapter. Pattern, subject, flags and replacement values are never
interpolated into Perl or JavaScript source.
The bridge:
- compiles a scalar pattern with `no re 'eval'`;
- independently rejects `(?{...})` and `(??{...})` outside escaped literals
and character classes;
- never imports the WebPerl JavaScript interoperability module;
- pre-tokenizes a deliberately bounded replacement grammar consisting of
literal text, `$$`, greedy `$n` and `${name}`;
- streams unmatched spans, literals and native capture values to the binary
output file in small UTF-8 chunks, stopping before a code point would cross
the output-byte bound;
- stops replacement at the match/capture-row result bound and preserves the
remaining subject as an unchanged tail;
- compares fixed named and numbered streaming fixtures with native Perl
`s///` output during the identity self-test;
- validates every request again inside Perl; and
- reports native Perl character offsets as Unicode code-point offsets.
Numbered capture participation and spans come from Perl's native `@-` and `@+`
arrays. The legacy runtime does not expose a stable name-to-number table, so
the adapter annotates those native capture rows with names from regex-tools'
syntax metadata. Numbered replacement values are streamed directly from their
native spans. Named replacement lookup itself uses Perl's native `%+`, and only
names present in the pre-tokenized template are read.
The prebuilt `emperl.js` contains one JavaScript `eval(code)` site in its
optional Perl-to-JavaScript interoperability import. The fixed bridge does not
load or call that facility. A Chromium CSP smoke succeeds with
`script-src 'self' 'wasm-unsafe-eval'` and without `'unsafe-eval'`.
The module worker remains responsive while the nested classic worker executes.
Terminating the supervised module worker terminates its worker descendants, so
catastrophic matching remains killable.
## Provenance
- WebPerl release: `v0.09-beta`
- Release commit: `6f2173d29a2c2e3536e1de75ff5d291ae96ab348`
- Prebuilt archive:
`https://github.com/haukex/webperl/releases/download/v0.09-beta/webperl_prebuilt_v0.09-beta.zip`
- Archive SHA-256:
`5f441249217e90ab378c666f473d4206ab4f44907f6bb0aa8d70834bc38c40dc`
- Perl runtime identity: `v5.28.1`
- Emscripten toolchain identified by the pinned upstream build configuration:
`1.38.28`
The deployed `emperl.js`, `emperl.wasm` and `emperl.data` files are copied
byte-for-byte from that archive. See `public/engines/perl/engine-metadata.json`,
`NOTICE.txt`, and the adjacent license files.

View File

@@ -0,0 +1,367 @@
"use strict";
/*
* Classic-worker wrapper for the pinned WebPerl 0.09-beta Emscripten runtime.
* User-controlled values cross into Perl only through a JSON file in MEMFS.
* Successful replacement bytes return through a separate fixed binary file;
* the bounded JSON response contains metadata only.
* The sole call through WebPerl's eval export is the fixed source string
* "RegexTools::run_request()"; no request data is interpolated into code.
*/
var BRIDGE_PROTOCOL_VERSION = 1;
var REQUEST_PATH = "/tmp/regex-tools-request.json";
var RESPONSE_PATH = "/tmp/regex-tools-response.json";
var OUTPUT_PATH = "/tmp/regex-tools-output.bin";
var HARNESS_PATH = "/tmp/regex-tools-bridge.pl";
var FIXED_INVOCATION = "RegexTools::run_request()";
var MAXIMUM_PATTERN_CHARACTERS = 64 * 1024;
var MAXIMUM_SUBJECT_BYTES = 16 * 1024 * 1024;
var MAXIMUM_REPLACEMENT_CHARACTERS = 64 * 1024;
var MAXIMUM_MATCHES = 10000;
var MAXIMUM_CAPTURE_ROWS = 100000;
var MAXIMUM_OUTPUT_BYTES = 64 * 1024 * 1024;
var MAXIMUM_REQUEST_JSON_BYTES =
6 *
(MAXIMUM_SUBJECT_BYTES +
MAXIMUM_PATTERN_CHARACTERS +
MAXIMUM_REPLACEMENT_CHARACTERS) +
16 * 1024;
var MAXIMUM_RESPONSE_JSON_BYTES = 8 * 1024 * 1024;
var utf8Encoder = new TextEncoder();
var runtimeRoot = new URL("./", self.location.href);
var runtimeResolve;
var runtimeReject;
var runtimeReady = new Promise(function (resolve, reject) {
runtimeResolve = resolve;
runtimeReject = reject;
});
var stderrTail = "";
function boundedRuntimeError(value) {
var message = value instanceof Error ? value.message : String(value);
if (stderrTail) {
message += " (" + stderrTail.slice(-512) + ")";
}
return message.slice(0, 1024);
}
function captureStderr(value) {
stderrTail = (stderrTail + String(value) + "\n").slice(-4096);
}
function isRecord(value) {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function owns(value, key) {
return Object.prototype.hasOwnProperty.call(value, key);
}
function isIntegerInRange(value, minimum, maximum) {
return Number.isSafeInteger(value) && value >= minimum && value <= maximum;
}
function hasExactKeys(value, expected) {
var actual = Object.keys(value).sort();
var wanted = expected.slice().sort();
if (actual.length !== wanted.length) return false;
for (var index = 0; index < actual.length; index += 1) {
if (actual[index] !== wanted[index]) return false;
}
return true;
}
function encodeRequest(request) {
if (
!isRecord(request) ||
request.abi !== 1 ||
typeof request.operation !== "string"
) {
throw new Error("The WebPerl bridge request is invalid.");
}
if (request.operation === "identity") {
if (!hasExactKeys(request, ["abi", "operation"])) {
throw new Error("The WebPerl identity request is invalid.");
}
} else {
var replacement = request.operation === "replace";
if (
(!replacement && request.operation !== "execute") ||
!hasExactKeys(
request,
[
"abi",
"operation",
"pattern",
"flags",
"options",
"subject",
"scanAll",
"maximumMatches",
"maximumCaptureRows",
].concat(replacement ? ["replacement", "maximumOutputBytes"] : []),
) ||
typeof request.pattern !== "string" ||
request.pattern.length > MAXIMUM_PATTERN_CHARACTERS ||
typeof request.flags !== "string" ||
request.flags.length > 10 ||
typeof request.subject !== "string" ||
typeof request.scanAll !== "boolean" ||
!isRecord(request.options) ||
Object.keys(request.options).length !== 0 ||
!isIntegerInRange(request.maximumMatches, 1, MAXIMUM_MATCHES) ||
!isIntegerInRange(request.maximumCaptureRows, 1, MAXIMUM_CAPTURE_ROWS)
) {
throw new Error("The WebPerl execution request is invalid.");
}
if (
utf8Encoder.encode(request.subject).byteLength > MAXIMUM_SUBJECT_BYTES
) {
throw new Error("The WebPerl subject exceeds its UTF-8 byte limit.");
}
if (
replacement &&
(typeof request.replacement !== "string" ||
request.replacement.length > MAXIMUM_REPLACEMENT_CHARACTERS ||
!isIntegerInRange(request.maximumOutputBytes, 1, MAXIMUM_OUTPUT_BYTES))
) {
throw new Error("The WebPerl replacement request is invalid.");
}
}
var encoded = utf8Encoder.encode(JSON.stringify(request));
if (encoded.byteLength > MAXIMUM_REQUEST_JSON_BYTES) {
throw new Error("The WebPerl request exceeds its JSON byte limit.");
}
return encoded;
}
function decodeUtf8Exact(encoded, label) {
var decoded;
try {
decoded = new TextDecoder("utf-8", { fatal: true }).decode(encoded);
} catch (_error) {
throw new Error(label + " is not valid UTF-8.");
}
var roundTrip = utf8Encoder.encode(decoded);
if (roundTrip.byteLength !== encoded.byteLength) {
throw new Error(label + " has an inconsistent UTF-8 length.");
}
for (var index = 0; index < encoded.byteLength; index += 1) {
if (roundTrip[index] !== encoded[index]) {
throw new Error(label + " is not canonical UTF-8.");
}
}
return decoded;
}
function readResponse() {
var encoded = FS.readFile(RESPONSE_PATH);
if (
Object.prototype.toString.call(encoded) !== "[object Uint8Array]" ||
encoded.byteLength === 0 ||
encoded.byteLength > MAXIMUM_RESPONSE_JSON_BYTES
) {
throw new Error("The fixed Perl bridge response exceeds its byte limit.");
}
var parsed;
try {
parsed = JSON.parse(decodeUtf8Exact(encoded, "The WebPerl response"));
} catch (error) {
if (error instanceof SyntaxError) {
throw new Error("The fixed Perl bridge returned malformed JSON.");
}
throw error;
}
if (!isRecord(parsed)) {
throw new Error("The fixed Perl bridge returned a non-object response.");
}
return parsed;
}
function injectReplacementOutput(response, maximumOutputBytes) {
if (
owns(response, "output") ||
!isIntegerInRange(response.outputBytes, 0, maximumOutputBytes) ||
typeof response.outputTruncated !== "boolean"
) {
throw new Error("The fixed Perl bridge returned invalid output metadata.");
}
var encoded = FS.readFile(OUTPUT_PATH);
if (
Object.prototype.toString.call(encoded) !== "[object Uint8Array]" ||
encoded.byteLength !== response.outputBytes ||
encoded.byteLength > maximumOutputBytes
) {
throw new Error(
"The fixed Perl bridge output file exceeds its bounded contract.",
);
}
response.output = decodeUtf8Exact(encoded, "The WebPerl output file");
}
function removeFixedFile(path) {
try {
FS.unlink(path);
} catch (_error) {
// The fixed file does not exist before its first use.
}
}
var Perl = {
trace: false,
glue: function () {
throw new Error("The WebPerl JavaScript bridge is disabled.");
},
unglue: function () {
throw new Error("The WebPerl JavaScript bridge is disabled.");
},
};
var Module = {
noInitialRun: true,
noExitRuntime: true,
arguments: ["--version"],
print: function () {},
printErr: captureStderr,
stdout: function () {},
stderr: function (character) {
if (character) {
stderrTail = (stderrTail + String.fromCharCode(character)).slice(-4096);
}
},
stdin: function () {
return null;
},
locateFile: function (file) {
return new URL(file, runtimeRoot).href;
},
preRun: [],
onRuntimeInitialized: function () {
runtimeResolve();
},
onAbort: function (reason) {
runtimeReject(
new Error("The legacy WebPerl runtime aborted: " + String(reason)),
);
},
};
importScripts(new URL("emperl.js", runtimeRoot).href);
var harnessPromise;
async function loadHarness() {
if (harnessPromise) return harnessPromise;
harnessPromise = (async function () {
await runtimeReady;
var response = await fetch(new URL("regex_tools_bridge.pl", runtimeRoot));
if (!response.ok) {
throw new Error(
"The fixed Perl bridge request failed with HTTP " +
response.status +
".",
);
}
var source = await response.text();
FS.writeFile(HARNESS_PATH, source, { encoding: "utf8" });
Module.callMain([HARNESS_PATH]);
return true;
})();
return harnessPromise;
}
async function invokeHarness(request) {
stderrTail = "";
await loadHarness();
if (stderrTail) {
throw new Error("The fixed Perl bridge failed to load: " + stderrTail);
}
removeFixedFile(REQUEST_PATH);
removeFixedFile(RESPONSE_PATH);
removeFixedFile(OUTPUT_PATH);
try {
FS.writeFile(REQUEST_PATH, encodeRequest(request));
var status = Module.ccall(
"webperl_eval_perl",
"string",
["string"],
[FIXED_INVOCATION],
);
if (status !== "ok") {
throw new Error("The fixed Perl bridge returned an invalid status.");
}
var parsed = readResponse();
if (request.operation === "replace" && parsed.ok === true) {
injectReplacementOutput(parsed, request.maximumOutputBytes);
} else if (
owns(parsed, "output") ||
owns(parsed, "outputBytes") ||
owns(parsed, "outputTruncated")
) {
throw new Error(
"The fixed Perl bridge returned output for a non-replacement result.",
);
}
return parsed;
} finally {
removeFixedFile(REQUEST_PATH);
removeFixedFile(RESPONSE_PATH);
removeFixedFile(OUTPUT_PATH);
}
}
async function handleMessage(message) {
if (
!message ||
message.protocolVersion !== BRIDGE_PROTOCOL_VERSION ||
!Number.isSafeInteger(message.requestId)
) {
throw new Error("The WebPerl bridge received an invalid message.");
}
if (message.kind === "load") {
return invokeHarness({ abi: 1, operation: "identity" });
}
if (message.kind === "run") {
if (
!message.request ||
typeof message.request !== "object" ||
Array.isArray(message.request)
) {
throw new Error("The WebPerl bridge received an invalid request.");
}
return invokeHarness(message.request);
}
throw new Error("The WebPerl bridge operation is unsupported.");
}
var operationQueue = Promise.resolve();
self.onmessage = function (event) {
var message = event.data;
var current = operationQueue.then(function () {
return handleMessage(message);
});
operationQueue = current.catch(function () {});
current.then(
function (payload) {
self.postMessage({
protocolVersion: BRIDGE_PROTOCOL_VERSION,
requestId: message && message.requestId,
ok: true,
payload: payload,
});
},
function (error) {
self.postMessage({
protocolVersion: BRIDGE_PROTOCOL_VERSION,
requestId: message && message.requestId,
ok: false,
error: {
name: error instanceof Error ? error.name : "Error",
message: boundedRuntimeError(error),
},
});
},
);
};

View File

@@ -0,0 +1,753 @@
package RegexTools;
use strict;
use warnings;
use utf8;
use Cpanel::JSON::XS ();
no re 'eval';
our $BRIDGE_ABI_VERSION = 1;
our $REQUEST_PATH = '/tmp/regex-tools-request.json';
our $RESPONSE_PATH = '/tmp/regex-tools-response.json';
our $OUTPUT_PATH = '/tmp/regex-tools-output.bin';
my $JSON = Cpanel::JSON::XS->new->utf8->canonical;
my $TRUE = Cpanel::JSON::XS::true;
my $FALSE = Cpanel::JSON::XS::false;
my $MAXIMUM_PATTERN_CHARACTERS = 64 * 1024;
my $MAXIMUM_SUBJECT_BYTES = 16 * 1024 * 1024;
my $MAXIMUM_REPLACEMENT_CHARACTERS = 64 * 1024;
my $MAXIMUM_MATCHES = 10_000;
my $MAXIMUM_CAPTURE_ROWS = 100_000;
my $MAXIMUM_CAPTURE_GROUPS = 1_000;
my $MAXIMUM_OUTPUT_BYTES = 64 * 1024 * 1024;
my $MAXIMUM_ERROR_CHARACTERS = 1_024;
my $OUTPUT_CHUNK_CHARACTERS = 4_096;
my $MAXIMUM_REQUEST_BYTES = 6 * (
$MAXIMUM_SUBJECT_BYTES
+ $MAXIMUM_PATTERN_CHARACTERS
+ $MAXIMUM_REPLACEMENT_CHARACTERS
) + 16 * 1024;
my $MAXIMUM_RESPONSE_BYTES = 8 * 1024 * 1024;
sub _bounded_message {
my ($value) = @_;
$value = defined($value) ? "$value" : 'Unknown Perl bridge error';
$value =~ s/\s+at \Q@{[$0]}\E line \d+\.?\s*\z//;
return length($value) <= $MAXIMUM_ERROR_CHARACTERS
? $value
: substr($value, 0, $MAXIMUM_ERROR_CHARACTERS - 1) . "\x{2026}";
}
sub _utf8_bytes {
my ($value) = @_;
my $encoded = $value;
utf8::encode($encoded);
return $encoded;
}
sub _failure {
my ($phase, $code, $message) = @_;
return {
abi => $BRIDGE_ABI_VERSION,
ok => $FALSE,
phase => $phase,
code => $code,
message => _bounded_message($message),
};
}
sub _is_plain_hash {
my ($value) = @_;
return ref($value) eq 'HASH';
}
sub _has_exact_keys {
my ($value, @expected) = @_;
return 0 if !_is_plain_hash($value);
return join("\0", sort keys %$value)
eq join("\0", sort @expected);
}
sub _is_integer_in_range {
my ($value, $minimum, $maximum) = @_;
return defined($value)
&& !ref($value)
&& "$value" =~ /\A(?:0|[1-9][0-9]*)\z/
&& $value >= $minimum
&& $value <= $maximum;
}
sub _read_request {
open my $input, '<:raw', $REQUEST_PATH
or die "Unable to open the fixed bridge request file: $!";
local $/;
my $encoded = <$input>;
close $input or die "Unable to close the fixed bridge request file: $!";
die 'The fixed bridge request exceeds its byte limit.'
if !defined($encoded) || length($encoded) > $MAXIMUM_REQUEST_BYTES;
return $JSON->decode($encoded);
}
sub _write_response {
my ($response) = @_;
my $encoded = $JSON->encode($response);
die 'The fixed bridge response exceeds its byte limit.'
if length($encoded) > $MAXIMUM_RESPONSE_BYTES;
open my $output, '>:raw', $RESPONSE_PATH
or die "Unable to open the fixed bridge response file: $!";
print {$output} $encoded
or die "Unable to write the fixed bridge response file: $!";
close $output
or die "Unable to close the fixed bridge response file: $!";
}
sub _contains_code_assertion {
my ($pattern) = @_;
my $escaped = 0;
my $character_class = 0;
my $quoted = 0;
for (my $index = 0; $index < length($pattern); $index++) {
my $current = substr($pattern, $index, 1);
if ($quoted) {
if ($current eq '\\'
&& substr($pattern, $index + 1, 1) eq 'E') {
$quoted = 0;
$index++;
}
next;
}
if ($escaped) {
$escaped = 0;
next;
}
if ($current eq '\\') {
if (substr($pattern, $index + 1, 1) eq 'Q') {
$quoted = 1;
$index++;
}
else {
$escaped = 1;
}
next;
}
if ($current eq '[' && !$character_class) {
$character_class = 1;
next;
}
if ($current eq ']' && $character_class) {
$character_class = 0;
next;
}
next if $character_class;
return 1 if substr($pattern, $index, 3) eq '(?{';
return 1 if substr($pattern, $index, 4) eq '(??{';
}
return 0;
}
sub _validate_flags {
my ($flags) = @_;
return 'Flags must be a string.' if !defined($flags) || ref($flags);
my %seen;
for my $flag (split //, $flags) {
return 'The request contains an unsupported or duplicate Perl flag.'
if $flag !~ /\A[gimsxnadlu]\z/ || $seen{$flag}++;
}
my $character_rules = grep { $seen{$_} } qw(a d l u);
return 'Perl character-set flags a, d, l and u are mutually exclusive.'
if $character_rules > 1;
return;
}
sub _validate_request {
my ($request) = @_;
return _failure('bridge', 'invalid-request', 'The request must be a JSON object.')
if !_is_plain_hash($request);
return _failure('bridge', 'abi-mismatch', 'The bridge ABI version is unsupported.')
if !defined($request->{abi})
|| ref($request->{abi})
|| $request->{abi} != $BRIDGE_ABI_VERSION;
if (defined($request->{operation})
&& !ref($request->{operation})
&& $request->{operation} eq 'identity') {
return _failure(
'bridge',
'invalid-request',
'The identity request contains missing or unexpected fields.',
) if !_has_exact_keys($request, qw(abi operation));
return;
}
return _failure('bridge', 'invalid-operation', 'The bridge operation is unsupported.')
if !defined($request->{operation})
|| ref($request->{operation})
|| ($request->{operation} ne 'execute'
&& $request->{operation} ne 'replace');
my @request_fields = qw(
abi
flags
maximumCaptureRows
maximumMatches
operation
options
pattern
scanAll
subject
);
push @request_fields, qw(maximumOutputBytes replacement)
if $request->{operation} eq 'replace';
return _failure(
'bridge',
'invalid-request',
'The request contains missing or unexpected fields.',
) if !_has_exact_keys($request, @request_fields);
return _failure('bridge', 'invalid-request', 'Pattern and subject must be strings.')
if !defined($request->{pattern})
|| ref($request->{pattern})
|| !defined($request->{subject})
|| ref($request->{subject});
return _failure('bridge', 'pattern-limit', 'The pattern exceeds the bridge limit.')
if length($request->{pattern}) > $MAXIMUM_PATTERN_CHARACTERS;
return _failure('bridge', 'subject-limit', 'The subject exceeds the bridge limit.')
if length(_utf8_bytes($request->{subject})) > $MAXIMUM_SUBJECT_BYTES;
return _failure('bridge', 'unsupported-option', 'Perl does not accept engine options.')
if !_is_plain_hash($request->{options})
|| keys(%{$request->{options}});
my $flag_error = _validate_flags($request->{flags});
return _failure('bridge', 'unsupported-flag', $flag_error) if $flag_error;
return _failure(
'bridge',
'result-limit',
'The requested result bounds are outside the bridge contract.',
) if !_is_integer_in_range(
$request->{maximumMatches},
1,
$MAXIMUM_MATCHES,
) || !_is_integer_in_range(
$request->{maximumCaptureRows},
1,
$MAXIMUM_CAPTURE_ROWS,
);
return _failure(
'compile',
'code-assertion-disabled',
'Perl code assertions (?{...}) and (??{...}) are disabled.',
) if _contains_code_assertion($request->{pattern});
if ($request->{operation} eq 'execute') {
return _failure(
'bridge',
'invalid-request',
'Execution requests cannot contain replacement fields.',
) if exists($request->{replacement})
|| exists($request->{maximumOutputBytes});
return;
}
return _failure(
'bridge',
'invalid-request',
'Replacement requests require a string template and output bound.',
) if !defined($request->{replacement})
|| ref($request->{replacement})
|| !_is_integer_in_range(
$request->{maximumOutputBytes},
1,
$MAXIMUM_OUTPUT_BYTES,
);
return _failure(
'bridge',
'replacement-limit',
'The replacement template exceeds the bridge limit.',
) if length($request->{replacement}) > $MAXIMUM_REPLACEMENT_CHARACTERS;
return;
}
sub _compile_pattern {
my ($pattern, $flags) = @_;
my $modifiers = join '', grep { index($flags, $_) >= 0 }
qw(i m s x n a d l u);
my $wrapped = length($modifiers)
? "(?$modifiers:$pattern)"
: "(?:$pattern)";
my $compiled;
my $error;
{
local $SIG{__WARN__} = sub { };
local $@;
$compiled = eval { qr/$wrapped/ };
$error = $@;
}
return ($compiled, $error);
}
sub _capture_group_count {
my ($compiled) = @_;
my $probe = qr/(?:$compiled)|()/;
'' =~ $probe;
return $#- - 1;
}
sub _snapshot_match {
my ($group_count, $starts, $ends) = @_;
my @captures;
for my $group (1 .. $group_count) {
push @captures, defined($starts->[$group])
&& $starts->[$group] >= 0
? [0 + $starts->[$group], 0 + $ends->[$group]]
: undef;
}
return {
span => [0 + $starts->[0], 0 + $ends->[0]],
captures => \@captures,
};
}
sub _push_literal_token {
my ($tokens, $literal) = @_;
return if !length($$literal);
push @$tokens, ['literal', $$literal];
$$literal = '';
}
sub _tokenize_replacement {
my ($template, $group_count) = @_;
my @tokens;
my $literal = '';
my $cursor = 0;
while ($cursor < length($template)) {
my $current = substr($template, $cursor, 1);
if ($current ne '$') {
$literal .= $current;
$cursor++;
next;
}
my $next = substr($template, $cursor + 1, 1);
if ($next eq '$') {
_push_literal_token(\@tokens, \$literal);
push @tokens, ['literal', '$'];
$cursor += 2;
next;
}
if (substr($template, $cursor + 1) =~ /\A([0-9]+)/) {
my $digits = $1;
my $canonical = $digits;
$canonical =~ s/\A0+(?=[0-9])//;
my $number = length($canonical) <= length("$group_count")
&& $canonical <= $group_count
? 0 + $canonical
: undef;
_push_literal_token(\@tokens, \$literal);
push @tokens, ['capture', $number];
$cursor += 1 + length($digits);
next;
}
if (substr($template, $cursor + 1)
=~ /\A\{([A-Za-z_][A-Za-z0-9_]*)\}/) {
my $name = $1;
_push_literal_token(\@tokens, \$literal);
push @tokens, ['named', $name];
$cursor += 3 + length($name);
next;
}
$literal .= '$';
$cursor++;
}
_push_literal_token(\@tokens, \$literal);
return \@tokens;
}
sub _write_encoded {
my ($state, $encoded) = @_;
return if !length($encoded);
print {$state->{handle}} $encoded
or die "Unable to write the fixed bridge output file: $!";
$state->{bytes} += length($encoded);
}
sub _append_piece {
my ($state, $value) = @_;
return 0 if $state->{truncated};
return 1 if !length($value);
my $encoded = _utf8_bytes($value);
my $remaining = $state->{maximum} - $state->{bytes};
if (length($encoded) <= $remaining) {
_write_encoded($state, $encoded);
return 1;
}
my ($low, $high) = (0, length($value));
while ($low < $high) {
my $middle = int(($low + $high + 1) / 2);
my $prefix_bytes = length(_utf8_bytes(substr($value, 0, $middle)));
if ($prefix_bytes <= $remaining) {
$low = $middle;
}
else {
$high = $middle - 1;
}
}
_write_encoded($state, _utf8_bytes(substr($value, 0, $low)))
if $low > 0;
$state->{truncated} = $TRUE;
return 0;
}
sub _append_text {
my ($state, $value) = @_;
return 0 if $state->{truncated};
my $cursor = 0;
while ($cursor < length($value)) {
my $length = length($value) - $cursor;
$length = $OUTPUT_CHUNK_CHARACTERS
if $length > $OUTPUT_CHUNK_CHARACTERS;
return 0
if !_append_piece($state, substr($value, $cursor, $length));
$cursor += $length;
}
return 1;
}
sub _append_span {
my ($state, $subject, $start, $end) = @_;
return 0 if $state->{truncated};
my $cursor = $start;
while ($cursor < $end) {
my $length = $end - $cursor;
$length = $OUTPUT_CHUNK_CHARACTERS
if $length > $OUTPUT_CHUNK_CHARACTERS;
return 0
if !_append_piece($state, substr($subject, $cursor, $length));
$cursor += $length;
}
return 1;
}
sub _resolve_named_spans {
my ($tokens, $subject, $starts, $ends, $named_values) = @_;
my %resolved;
for my $token (@$tokens) {
my ($kind, $name) = @$token;
next if $kind ne 'named'
|| exists($resolved{$name})
|| !exists($named_values->{$name})
|| !defined($named_values->{$name});
my $captured = $named_values->{$name};
for my $group (1 .. $#$ends) {
next if !defined($starts->[$group])
|| $starts->[$group] < 0
|| $ends->[$group] - $starts->[$group] != length($captured)
|| index($subject, $captured, $starts->[$group])
!= $starts->[$group];
$resolved{$name} = [
0 + $starts->[$group],
0 + $ends->[$group],
];
last;
}
die "Unable to resolve native span for named capture $name."
if !exists($resolved{$name});
}
return \%resolved;
}
sub _append_replacement_tokens {
my ($state, $tokens, $subject, $starts, $ends, $named_spans) = @_;
for my $token (@$tokens) {
return 0 if $state->{truncated};
my ($kind, $value) = @$token;
if ($kind eq 'literal') {
_append_text($state, $value);
}
elsif ($kind eq 'capture') {
_append_span(
$state,
$subject,
$starts->[$value],
$ends->[$value],
) if defined($value)
&& defined($starts->[$value])
&& $starts->[$value] >= 0;
}
elsif ($kind eq 'named') {
_append_span(
$state,
$subject,
$named_spans->{$value}->[0],
$named_spans->{$value}->[1],
) if exists($named_spans->{$value});
}
else {
die 'The fixed replacement tokenizer produced an invalid token.';
}
}
return !$state->{truncated};
}
sub _open_output {
my ($maximum, $path) = @_;
open my $handle, '>:raw', $path
or die "Unable to open the fixed bridge output file: $!";
return {
handle => $handle,
bytes => 0,
maximum => 0 + $maximum,
truncated => $FALSE,
};
}
sub _close_output {
my ($state) = @_;
close $state->{handle}
or die "Unable to close the fixed bridge output file: $!";
delete $state->{handle};
}
sub _run_regex {
my ($request) = @_;
my ($compiled, $compile_error) = _compile_pattern(
$request->{pattern},
$request->{flags},
);
return _failure('compile', 'compile-error', $compile_error)
if !defined($compiled);
my $group_count = _capture_group_count($compiled);
return _failure(
'compile',
'capture-group-limit',
"The pattern declares $group_count capture groups; "
. "the bridge limit is $MAXIMUM_CAPTURE_GROUPS.",
) if $group_count > $MAXIMUM_CAPTURE_GROUPS;
my $rows_per_match = $group_count > 0 ? $group_count : 1;
my $allowed_matches = $request->{maximumMatches};
my $row_bound = int($request->{maximumCaptureRows} / $rows_per_match);
$allowed_matches = $row_bound if $row_bound < $allowed_matches;
my $subject = $request->{subject};
my $global = index($request->{flags}, 'g') >= 0;
my $replacement_tokens = $request->{operation} eq 'replace'
? _tokenize_replacement($request->{replacement}, $group_count)
: undef;
my @matches;
my $results_truncated = $FALSE;
my $replacement_state = defined($replacement_tokens)
? _open_output($request->{maximumOutputBytes}, $OUTPUT_PATH)
: undef;
$replacement_state->{cursor} = 0 if defined($replacement_state);
pos($subject) = 0;
while ($subject =~ /$compiled/g) {
my @starts = @-;
my @ends = @+;
if (@matches >= $allowed_matches) {
$results_truncated = $TRUE;
last;
}
push @matches, _snapshot_match(
$group_count,
\@starts,
\@ends,
);
if (defined($replacement_state)) {
_append_span(
$replacement_state,
$subject,
$replacement_state->{cursor},
$starts[0],
);
if (!$replacement_state->{truncated}) {
my $named_spans = _resolve_named_spans(
$replacement_tokens,
$subject,
\@starts,
\@ends,
\%+,
);
_append_replacement_tokens(
$replacement_state,
$replacement_tokens,
$subject,
\@starts,
\@ends,
$named_spans,
);
}
$replacement_state->{cursor} = $ends[0];
if ($replacement_state->{truncated}) {
$results_truncated = $TRUE;
last;
}
}
last if !$global;
}
my $response = {
abi => $BRIDGE_ABI_VERSION,
ok => $TRUE,
groupCount => 0 + $group_count,
groupNames => [],
matches => \@matches,
resultsTruncated => $results_truncated,
};
if (defined($replacement_state)) {
_append_span(
$replacement_state,
$subject,
$replacement_state->{cursor},
length($subject),
);
_close_output($replacement_state);
$response->{outputBytes} = 0 + $replacement_state->{bytes};
$response->{outputTruncated} = $replacement_state->{truncated};
}
return $response;
}
sub _render_self_test_replacement {
my ($compiled, $subject, $template, $maximum) = @_;
my $group_count = _capture_group_count($compiled);
my $tokens = _tokenize_replacement($template, $group_count);
return if $subject !~ /$compiled/;
my @starts = @-;
my @ends = @+;
my $named_spans = _resolve_named_spans(
$tokens,
$subject,
\@starts,
\@ends,
\%+,
);
my $encoded = '';
my $state = _open_output($maximum, \$encoded);
_append_span($state, $subject, 0, $starts[0]);
_append_replacement_tokens(
$state,
$tokens,
$subject,
\@starts,
\@ends,
$named_spans,
);
_append_span($state, $subject, $ends[0], length($subject));
_close_output($state);
my $decoded = $encoded;
return if !utf8::decode($decoded);
return ($decoded, 0 + $state->{bytes}, $state->{truncated});
}
sub _self_test {
return $FALSE if "$^V" ne 'v5.28.1';
my ($compiled, $error) = _compile_pattern(
'(?<word>\x{1F600}+)',
'u',
);
return $FALSE if $error || !defined($compiled);
my $subject = "x\x{1F600}\x{1F600}";
return $FALSE if $subject !~ /$compiled/;
return $FALSE if $-[0] != 1 || $+[0] != 3;
return $FALSE if $+{word} ne "\x{1F600}\x{1F600}";
my ($named, $named_bytes, $named_truncated) =
_render_self_test_replacement(
$compiled,
$subject,
'<${word}>',
1_024,
);
return $FALSE if !defined($named)
|| $named ne "x<\x{1F600}\x{1F600}>"
|| $named_bytes != 11
|| $named_truncated;
my $native_named = $subject;
$native_named =~ s/$compiled/<$+{word}>/;
return $FALSE if $named ne $native_named;
my $numbered_compiled = qr/(a)(b)/;
my ($numbered, $numbered_bytes, $numbered_truncated) =
_render_self_test_replacement(
$numbered_compiled,
'ab',
'$1-$$',
1_024,
);
my $native_numbered = 'ab';
$native_numbered =~ s/$numbered_compiled/$1-\$/;
return $FALSE if !defined($numbered)
|| $numbered ne $native_numbered
|| $numbered_bytes != 3
|| $numbered_truncated;
my ($greedy, $greedy_bytes, $greedy_truncated) =
_render_self_test_replacement(
qr/(a)(b)/,
'ab',
'$12/$1/$$/${missing}/$',
1_024,
);
return $FALSE if !defined($greedy)
|| $greedy ne '/a/$//$'
|| $greedy_bytes != 7
|| $greedy_truncated;
my ($bounded, $bounded_bytes, $bounded_truncated) =
_render_self_test_replacement(
$compiled,
$subject,
'<${word}>',
5,
);
return $FALSE if !defined($bounded)
|| $bounded ne 'x<'
|| $bounded_bytes != 2
|| !$bounded_truncated;
return $TRUE;
}
sub _identity {
return {
abi => $BRIDGE_ABI_VERSION,
ok => $TRUE,
identity => {
bridge => 'regex-tools-webperl-json',
bridgeVersion => $BRIDGE_ABI_VERSION,
engine => 'Perl regular expressions',
engineVersion => '5.28.1',
perlVersion => "$^V",
webPerlVersion => '0.09-beta',
offsetUnit => 'code-point',
replacementGrammar => 'literal + $$ + $n + ${name}',
replacementTransport => 'fixed MEMFS binary output file',
replacementParityOracle => 'fixed native s/// fixtures',
legacy => $TRUE,
beta => $TRUE,
selfTest => _self_test(),
},
};
}
sub run_request {
my $response;
my $ok = eval {
my $request = _read_request();
my $validation_failure = _validate_request($request);
$response = $validation_failure
|| ($request->{operation} eq 'identity'
? _identity()
: _run_regex($request));
1;
};
if (!$ok) {
$response = _failure(
'bridge',
'bridge-error',
$@ || 'Unknown fixed Perl bridge failure',
);
}
eval { _write_response($response); 1 } or do {
my $fallback = _failure(
'bridge',
'serialization-error',
$@ || 'The fixed Perl bridge could not serialize its response.',
);
_write_response($fallback);
};
return 'ok';
}
1;

View File

@@ -0,0 +1,102 @@
Emscripten is available under 2 licenses, the MIT license and the
University of Illinois/NCSA Open Source License.
Both are permissive open source licenses, with little if any
practical difference between them.
The reason for offering both is that (1) the MIT license is
well-known, while (2) the University of Illinois/NCSA Open Source
License allows Emscripten's code to be integrated upstream into
LLVM, which uses that license, should the opportunity arise.
The full text of both licenses follows.
==============================================================================
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal with the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimers.
Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimers
in the documentation and/or other materials provided with the
distribution.
Neither the names of Mozilla,
nor the names of its contributors may be used to endorse
or promote products derived from this Software without specific prior
written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
==============================================================================
This program uses portions of Node.js source code located in src/library_path.js,
in accordance with the terms of the MIT license. Node's license follows:
"""
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
"""
The musl libc project is bundled in this repo, and it has the MIT license, see
system/lib/libc/musl/COPYRIGHT
The third_party/ subdirectory contains code with other licenses. None of it is
used by default, but certain options use it (e.g., the optional closure compiler
flag will run closure compiler from third_party/).

View File

@@ -0,0 +1,26 @@
Oniguruma LICENSE
-----------------
Copyright (c) 2002-2021 K.Kosako <kkosako0@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

View File

@@ -0,0 +1,125 @@
LICENSE ISSUES
==============
The OpenSSL toolkit stays under a double license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit.
See below for the actual license texts.
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/

View File

@@ -0,0 +1,94 @@
PCRE2 LICENCE
-------------
PCRE2 is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Releases 10.00 and above of PCRE2 are distributed under the terms of the "BSD"
licence, as specified below, with one exemption for certain binary
redistributions. The documentation for PCRE2, supplied in the "doc" directory,
is distributed under the same terms as the software itself. The data in the
testdata directory is not copyrighted and is in the public domain.
The basic library functions are written in C and are freestanding. Also
included in the distribution is a just-in-time compiler that can be used to
optimize pattern matching. This is an optional feature that can be omitted when
the library is built.
THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
Email local part: Philip.Hazel
Email domain: gmail.com
Retired from University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2024 University of Cambridge
All rights reserved.
PCRE2 JUST-IN-TIME COMPILATION SUPPORT
--------------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2010-2024 Zoltan Herczeg
All rights reserved.
STACK-LESS JUST-IN-TIME COMPILER
--------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2009-2024 Zoltan Herczeg
All rights reserved.
THE "BSD" LICENCE
-----------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notices,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notices, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of any
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
------------------------------------------
The second condition in the BSD licence (covering binary redistributions) does
not apply all the way down a chain of software. If binary package A includes
PCRE2, it must respect the condition, but if package B is software that
includes package A, the condition is not imposed on package B unless it uses
PCRE2 independently.
End

View File

@@ -0,0 +1,27 @@
Copyright © The PHP Group and Contributors.
Copyright © Zend Technologies Ltd., a subsidiary company of Perforce Software, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,19 @@
Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@@ -0,0 +1,56 @@
--------------------------------------------------------------------
The Zend Engine License, Version 2.00
Copyright (c) 1999-2006 Zend Technologies Ltd. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The names "Zend" and "Zend Engine" must not be used to endorse
or promote products derived from this software without prior
permission from Zend Technologies Ltd. For written permission,
please contact license@zend.com.
4. Zend Technologies Ltd. may publish revised and/or new versions
of the license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the
terms of that version. You may also choose to use such covered
code under the terms of any subsequent version of the license
published by Zend Technologies Ltd. No one other than Zend
Technologies Ltd. has the right to modify the terms applicable
to covered code created under this License.
5. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes the Zend Engine, freely available at
http://www.zend.com"
6. All advertising materials mentioning features or use of this
software must display the following acknowledgment:
"The Zend Engine is freely available at http://www.zend.com"
THIS SOFTWARE IS PROVIDED BY ZEND TECHNOLOGIES LTD. ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ZEND
TECHNOLOGIES LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
--------------------------------------------------------------------

View File

@@ -0,0 +1,512 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
<one line to give the library's name and a brief idea of what it
does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper
mail.
You should also get your employer (if you work as a programmer) or
your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -0,0 +1,26 @@
Copyright (c) 2021, Alliance for Open Media. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,29 @@
$File: COPYING,v 1.2 2018/09/09 20:33:28 christos Exp $
Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
Software written by Ian F. Darwin and others;
maintained 1994- Christos Zoulas.
This software is not subject to any export provision of the United States
Department of Commerce, and may be exported to any country or planet.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice immediately at the beginning of the file, without modification,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

View File

@@ -0,0 +1,516 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
"streamable kanji code filter and converter"
Copyright (c) 1998,1999,2000,2001 HappySize, Inc. All rights reserved.
This software is released under the GNU Lesser General Public License.
(Version 2.1, February 1999)
Please read the following detail of the licence (in japanese).
◆使用許諾条件◆
このソフトウェアは株式会社ハッピーサイズによって開発されました。株式会社ハッ
ピーサイズは、著作権法および万国著作権条約の定めにより、このソフトウェアに関
するすべての権利を留保する権利を持ち、ここに行使します。株式会社ハッピーサイ
ズは以下に明記した条件に従って、このソフトウェアを使用する排他的ではない権利
をお客様に許諾します。何人たりとも、以下の条件に反してこのソフトウェアを使用
することはできません。
このソフトウェアを「GNU Lesser General Public License (Version 2.1, February
1999)」に示された条件で使用することを、全ての方に許諾します。「GNU Lesser
General Public License」を満たさない使用には、株式会社ハッピーサイズから書面
による許諾を得る必要があります。
「GNU Lesser General Public License」の全文は以下のウェブページから取得でき
ます。「GNU Lesser General Public License」とは、これまでLibrary General
Public Licenseと呼ばれていたものです。
http://www.gnu.org/ --- GNUウェブサイト
http://www.gnu.org/copyleft/lesser.html --- ライセンス文面
このライセンスの内容がわからない方、守れない方には使用を許諾しません。
しかしながら、当社とGNUプロジェクトとの特定の関係を示唆または主張するもので
はありません。
◆保証内容◆
このソフトウェアは、期待された動作・機能・性能を持つことを目標として設計され
開発されていますが、これを保証するものではありません。このソフトウェアは「こ
のまま」の状態で提供されており、たとえばこのソフトウェアの有用性ないし特定の
目的に合致することといった、何らかの保証内容が、明示されたり暗黙に示されてい
る場合であっても、その保証は無効です。このソフトウェアを使用した結果ないし使
用しなかった結果によって、直接あるいは間接に受けた身体的な傷害、財産上の損害
、データの損失あるいはその他の全ての損害については、その損害の可能性が使用者
、当社あるいは第三者によって警告されていた場合であっても、当社はその損害の賠
償および補填を行いません。この規定は他の全ての、書面上または書面に無い保証・
契約・規定に優先します。
◆著作権者の連絡先および使用条件についての問い合わせ先◆
〒102-0073
東京都千代田区九段北1-13-5日本地所第一ビル4F
株式会社ハッピーサイズ
Phone: 03-3512-3655, Fax: 03-3512-3656
Email: sales@happysize.co.jp
Web: http://happysize.com/
◆著者◆
金本 茂 <sgk@happysize.co.jp>

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015-2021 Derick Rethans
Copyright (c) 2017-2019,2021 MongoDB, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,36 @@
uriparser - RFC 3986 URI parsing library
Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
3. Neither the name of the copyright holder nor the names of
its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,22 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2020, Daniel Stenberg, <daniel@haxx.se>, and many
contributors, see the THANKS file.
All rights reserved.
Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization of the copyright holder.

View File

@@ -0,0 +1,27 @@
Copyright (c) 2016, Alliance for Open Media. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,387 @@
Copyright 2019 Joe Drago. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
Files: src/obu.c
Copyright © 2018-2019, VideoLAN and dav1d authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
Files: third_party/iccjpeg/*
In plain English:
1. We don't promise that this software works. (But if you find any bugs,
please let us know!)
2. You can use this software for whatever you want. You don't have to pay us.
3. You may not pretend that you wrote this software. If you use it in a
program, you must acknowledge somewhere in your documentation that
you've used the IJG code.
In legalese:
The authors make NO WARRANTY or representation, either express or implied,
with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
software (or portions thereof) for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code for this software is distributed, then this
README file must be included, with this copyright and no-warranty notice
unaltered; and any additions, deletions, or changes to the original files
must be clearly indicated in accompanying documentation.
(2) If only executable code is distributed, then the accompanying
documentation must state that "this software is based in part on the work of
the Independent JPEG Group".
(3) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.
These conditions apply to any software derived from or based on the IJG code,
not just to the unmodified library. If you use our work, you ought to
acknowledge us.
Permission is NOT granted for the use of any IJG author's name or company name
in advertising or publicity relating to this software or products derived from
it. This software may be referred to only as "the Independent JPEG Group's
software".
We specifically permit and encourage the use of this software as the basis of
commercial products, provided that all warranty or liability claims are
assumed by the product vendor.
The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub,
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
but is also freely distributable.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent, GIF reading support has
been removed altogether, and the GIF writer has been simplified to produce
"uncompressed GIFs". This technique does not use the LZW algorithm; the
resulting GIF files are larger than usual, but are readable by all standard
GIF decoders.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated."
------------------------------------------------------------------------------
Files: contrib/gdk-pixbuf/*
Copyright 2020 Emmanuel Gil Peyrot. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
Files: android_jni/gradlew*
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
------------------------------------------------------------------------------
Files: third_party/libyuv/*
Copyright 2011 The LibYuv Project Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Google nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,311 @@
==============================================================================
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
==============================================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
==============================================================================
Software from third parties included in the LLVM Project:
==============================================================================
The LLVM Project contains third party software which is under different license
terms. All such code will be identified clearly using at least one of two
mechanisms:
1) It will be in a separate directory tree with its own `LICENSE.txt` or
`LICENSE` file at the top containing the specific license and restrictions
which apply to that software, or
2) It will contain specific license and restriction terms at the top of every
file.
==============================================================================
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
==============================================================================
The libc++ library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license. As a user of this code you may choose
to use it under either license. As a contributor, you agree to allow your code
to be used under both.
Full text of the relevant licenses is included below.
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,311 @@
==============================================================================
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
==============================================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
==============================================================================
Software from third parties included in the LLVM Project:
==============================================================================
The LLVM Project contains third party software which is under different license
terms. All such code will be identified clearly using at least one of two
mechanisms:
1) It will be in a separate directory tree with its own `LICENSE.txt` or
`LICENSE` file at the top containing the specific license and restrictions
which apply to that software, or
2) It will contain specific license and restriction terms at the top of every
file.
==============================================================================
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
==============================================================================
The libc++abi library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license. As a user of this code you may choose
to use it under either license. As a contributor, you agree to allow your code
to be used under both.
Full text of the relevant licenses is included below.
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,73 @@
Title: License
Credits and license terms:
In order to resolve any possible confusion regarding the authorship of
gd, the following copyright statement covers all of the authors who
have required such a statement. If you are aware of any oversights in
this copyright notice, please contact Pierre-A. Joye who will be
pleased to correct them.
* Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under
Grant P41-RR02188 by the National Institutes of Health.
* Portions copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004 by Boutell.Com, Inc.
* Portions relating to GD2 format copyright 1999, 2000, 2001, 2002,
2003, 2004 Philip Warner.
* Portions relating to PNG copyright 1999, 2000, 2001, 2002, 2003,
2004 Greg Roelofs.
* Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002,
2003, 2004 John Ellson (ellson@graphviz.org).
* Portions relating to gdft.c copyright 2001, 2002, 2003, 2004 John
Ellson (ellson@graphviz.org).
* Portions copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008 Pierre-Alain Joye (pierre@libgd.org).
* Portions relating to JPEG and to color quantization copyright
2000, 2001, 2002, 2003, 2004, Doug Becker and copyright (C) 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Thomas
G. Lane. This software is based in part on the work of the
Independent JPEG Group. See the file README-JPEG.TXT for more
information.
* Portions relating to GIF compression copyright 1989 by Jef
Poskanzer and David Rowley, with modifications for thread safety
by Thomas Boutell.
* Portions relating to GIF decompression copyright 1990, 1991, 1993
by David Koblas, with modifications for thread safety by Thomas
Boutell.
* Portions relating to WBMP copyright 2000, 2001, 2002, 2003, 2004
Maurice Szmurlo and Johan Van den Brande.
* Portions relating to GIF animations copyright 2004 Jaakko Hyvätti
(jaakko.hyvatti@iki.fi)
Permission has been granted to copy, distribute and modify gd in
any context without fee, including a commercial application,
provided that this notice is present in user-accessible supporting
documentation.
This does not affect your ownership of the derived work itself,
and the intent is to assure proper credit for the authors of gd,
not to interfere with your productive use of gd. If you have
questions, ask. "Derived works" includes all programs that utilize
the library. Credit must be given in user-accessible
documentation.
This software is provided "AS IS." The copyright holders disclaim
all warranties, either express or implied, including but not
limited to implied warranties of merchantability and fitness for a
particular purpose, with respect to this code and accompanying
documentation.
Although their code does not appear in the current release, the
authors wish to thank David Koblas, David Rowley, and Hutchison
Avenue Software Corporation for their prior contributions.

View File

@@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -0,0 +1,135 @@
libjpeg-turbo Licenses
======================
libjpeg-turbo is covered by two compatible BSD-style open source licenses:
- The IJG (Independent JPEG Group) License, which is listed in
[README.ijg](README.ijg)
This license applies to the libjpeg API library and associated programs,
including any code inherited from libjpeg and any modifications to that
code. Note that the libjpeg-turbo SIMD source code bears the
[zlib License](https://opensource.org/licenses/Zlib), but in the context of
the overall libjpeg API library, the terms of the zlib License are subsumed
by the terms of the IJG License.
- The Modified (3-clause) BSD License, which is listed below
This license applies to the TurboJPEG API library and associated programs, as
well as the build system. Note that the TurboJPEG API library wraps the
libjpeg API library, so in the context of the overall TurboJPEG API library,
both the terms of the IJG License and the terms of the Modified (3-clause)
BSD License apply.
Complying with the libjpeg-turbo Licenses
=========================================
This section provides a roll-up of the libjpeg-turbo licensing terms, to the
best of our understanding. This is not a license in and of itself. It is
intended solely for clarification.
1. If you are distributing a modified version of the libjpeg-turbo source,
then:
1. You cannot alter or remove any existing copyright or license notices
from the source.
**Origin**
- Clause 1 of the IJG License
- Clause 1 of the Modified BSD License
- Clauses 1 and 3 of the zlib License
2. You must add your own copyright notice to the header of each source
file you modified, so others can tell that you modified that file. (If
there is not an existing copyright header in that file, then you can
simply add a notice stating that you modified the file.)
**Origin**
- Clause 1 of the IJG License
- Clause 2 of the zlib License
3. You must include the IJG README file, and you must not alter any of the
copyright or license text in that file.
**Origin**
- Clause 1 of the IJG License
2. If you are distributing only libjpeg-turbo binaries without the source, or
if you are distributing an application that statically links with
libjpeg-turbo, then:
1. Your product documentation must include a message stating:
This software is based in part on the work of the Independent JPEG
Group.
**Origin**
- Clause 2 of the IJG license
2. If your binary distribution includes or uses the TurboJPEG API, then
your product documentation must include the text of the Modified BSD
License (see below.)
**Origin**
- Clause 2 of the Modified BSD License
3. You cannot use the name of the IJG or The libjpeg-turbo Project or the
contributors thereof in advertising, publicity, etc.
**Origin**
- IJG License
- Clause 3 of the Modified BSD License
4. The IJG and The libjpeg-turbo Project do not warrant libjpeg-turbo to be
free of defects, nor do we accept any liability for undesirable
consequences resulting from your use of the software.
**Origin**
- IJG License
- Modified BSD License
- zlib License
The Modified (3-clause) BSD License
===================================
Copyright (C)2009-2023 D. R. Commander. All Rights Reserved.<br>
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the libjpeg-turbo Project nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Why Two Licenses?
=================
The zlib License could have been used instead of the Modified (3-clause) BSD
License, and since the IJG License effectively subsumes the distribution
conditions of the zlib License, this would have effectively placed
libjpeg-turbo binary distributions under the IJG License. However, the IJG
License specifically refers to the Independent JPEG Group and does not extend
attribution and endorsement protections to other entities. Thus, it was
desirable to choose a license that granted us the same protections for new code
that were granted to the IJG for code derived from their software.

View File

@@ -0,0 +1,134 @@
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
=========================================
PNG Reference Library License version 2
---------------------------------------
* Copyright (c) 1995-2022 The PNG Reference Library Authors.
* Copyright (c) 2018-2022 Cosmin Truta.
* Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
* Copyright (c) 1996-1997 Andreas Dilger.
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
The software is supplied "as is", without warranty of any kind,
express or implied, including, without limitation, the warranties
of merchantability, fitness for a particular purpose, title, and
non-infringement. In no event shall the Copyright owners, or
anyone distributing the software, be liable for any damages or
other liability, whether in contract, tort or otherwise, arising
from, out of, or in connection with the software, or the use or
other dealings in the software, even if advised of the possibility
of such damage.
Permission is hereby granted to use, copy, modify, and distribute
this software, or portions hereof, for any purpose, without fee,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you
use this software in a product, an acknowledgment in the product
documentation would be appreciated, but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This Copyright notice may not be removed or altered from any
source or altered source distribution.
PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
-----------------------------------------------------------------------
libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are
Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same
disclaimer and license as libpng-1.0.6 with the following individuals
added to the list of Contributing Authors:
Simon-Pierre Cadieux
Eric S. Raymond
Mans Rullgard
Cosmin Truta
Gilles Vollant
James Yu
Mandar Sahastrabuddhe
Google Inc.
Vadim Barkov
and with the following additions to the disclaimer:
There is no warranty against interference with your enjoyment of
the library or against infringement. There is no warranty that our
efforts or the library will fulfill any of your particular purposes
or needs. This library is provided with all faults, and the entire
risk of satisfactory quality, performance, accuracy, and effort is
with the user.
Some files in the "contrib" directory and some configure-generated
files that are distributed with libpng have other copyright owners, and
are released under other open source licenses.
libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
libpng-0.96, and are distributed according to the same disclaimer and
license as libpng-0.96, with the following individuals added to the
list of Contributing Authors:
Tom Lane
Glenn Randers-Pehrson
Willem van Schaik
libpng versions 0.89, June 1996, through 0.96, May 1997, are
Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
and are distributed according to the same disclaimer and license as
libpng-0.88, with the following individuals added to the list of
Contributing Authors:
John Bowler
Kevin Bracey
Sam Bushell
Magnus Holmgren
Greg Roelofs
Tom Tanner
Some files in the "scripts" directory have other copyright owners,
but are released under this license.
libpng versions 0.5, May 1995, through 0.88, January 1996, are
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
For the purposes of this copyright and license, "Contributing Authors"
is defined as the following set of individuals:
Andreas Dilger
Dave Martindale
Guy Eric Schalnat
Paul Schmidt
Tim Wegner
The PNG Reference Library is supplied "AS IS". The Contributing
Authors and Group 42, Inc. disclaim all warranties, expressed or
implied, including, without limitation, the warranties of
merchantability and of fitness for any purpose. The Contributing
Authors and Group 42, Inc. assume no liability for direct, indirect,
incidental, special, exemplary, or consequential damages, which may
result from the use of the PNG Reference Library, even if advised of
the possibility of such damage.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, without fee, subject
to the following restrictions:
1. The origin of this source code must not be misrepresented.
2. Altered versions must be plainly marked as such and must not
be misrepresented as being the original source.
3. This Copyright notice may not be removed or altered from any
source or altered source distribution.
The Contributing Authors and Group 42, Inc. specifically permit,
without fee, and encourage the use of this source code as a component
to supporting the PNG file format in commercial products. If you use
this source code in a product, acknowledgment is not required but would
be appreciated.

View File

@@ -0,0 +1,30 @@
Copyright (c) 2010, Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Google nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,23 @@
Except where otherwise noted in the source code (e.g. the files hash.c,
list.c and the trio files, which are covered by a similar licence but
with different Copyright notices) all the files are:
Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is fur-
nished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,29 @@
Copyright 2011 The LibYuv Project Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Google nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,31 @@
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,311 @@
==============================================================================
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
==============================================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
==============================================================================
Software from third parties included in the LLVM Project:
==============================================================================
The LLVM Project contains third party software which is under different license
terms. All such code will be identified clearly using at least one of two
mechanisms:
1) It will be in a separate directory tree with its own `LICENSE.txt` or
`LICENSE` file at the top containing the specific license and restrictions
which apply to that software, or
2) It will contain specific license and restriction terms at the top of every
file.
==============================================================================
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
==============================================================================
The compiler_rt library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license. As a user of this code you may choose
to use it under either license. As a contributor, you agree to allow your code
to be used under both.
Full text of the relevant licenses is included below.
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,193 @@
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
A. Wilcox
Ada Worcester
Alex Dowad
Alex Suykov
Alexander Monakov
Andre McCurdy
Andrew Kelley
Anthony G. Basile
Aric Belsito
Arvid Picciani
Bartosz Brachaczek
Benjamin Peterson
Bobby Bingham
Boris Brezillon
Brent Cook
Chris Spiegel
Clément Vasseur
Daniel Micay
Daniel Sabogal
Daurnimator
David Carlier
David Edelsohn
Denys Vlasenko
Dmitry Ivanov
Dmitry V. Levin
Drew DeVault
Emil Renner Berthing
Fangrui Song
Felix Fietkau
Felix Janda
Gianluca Anzolin
Hauke Mehrtens
He X
Hiltjo Posthuma
Isaac Dunham
Jaydeep Patil
Jens Gustedt
Jeremy Huntwork
Jo-Philipp Wich
Joakim Sindholt
John Spencer
Julien Ramseier
Justin Cormack
Kaarle Ritvanen
Khem Raj
Kylie McClain
Leah Neukirchen
Luca Barbato
Luka Perkov
M Farkas-Dyck (Strake)
Mahesh Bodapati
Markus Wichmann
Masanori Ogino
Michael Clark
Michael Forney
Mikhail Kremnyov
Natanael Copa
Nicholas J. Kain
orc
Pascal Cuoq
Patrick Oppenlander
Petr Hosek
Petr Skocik
Pierre Carrier
Reini Urban
Rich Felker
Richard Pennington
Ryan Fairfax
Samuel Holland
Segev Finer
Shiz
sin
Solar Designer
Stefan Kristiansson
Stefan O'Rear
Szabolcs Nagy
Timo Teräs
Trutz Behn
Valentin Ochs
Will Dietz
William Haddon
William Pitcock
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/* and src/complex/*) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier or
Copyright © 2017-2018 Arm Limited
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The AArch64 memcpy and memset code (src/string/aarch64/*) are
Copyright © 1999-2019, Arm Limited.
The implementation of DES for crypt (src/crypt/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Valentin Ochs and is licensed under an MIT-style license.
The x86_64 port was written by Nicholas J. Kain and is licensed under
the standard MIT terms.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The mips64 port was contributed by Imagination Technologies and is
licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
In addition, permission is hereby granted for all public header files
(include/* and arch/*/bits/*) and crt files intended to be linked into
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
the copyright notice and permission notice otherwise required by the
license, and to use these files without any requirement of
attribution. These files include substantial contributions from:
Bobby Bingham
John Spencer
Nicholas J. Kain
Rich Felker
Richard Pennington
Stefan Kristiansson
Szabolcs Nagy
all of whom have explicitly granted such permission.
This file previously contained text expressing a belief that most of
the files covered by the above exception were sufficiently trivial not
to be subject to copyright, resulting in confusion over whether it
negated the permissions granted in the license. In the spirit of
permissive licensing, and of not having licensing issues being an
obstacle to adoption, that text has been removed.

View File

@@ -0,0 +1,22 @@
Copyright notice:
(C) 1995-2022 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu

View File

@@ -0,0 +1,12 @@
IANA Time Zone Database 2026.1
==============================
PHP 8.5.8 embeds IANA Time Zone Database version 2026.1 in:
https://github.com/php/php-src/blob/26b97507444c4fbda072f57dda1820f7b7d5e467/ext/date/lib/timezonedb.h
The IANA Time Zone Database is public-domain material. Its authoritative
source and public-domain notice are available at:
https://www.iana.org/time-zones
https://data.iana.org/time-zones/tz-link.html

View File

@@ -0,0 +1,16 @@
Lexbor.
Copyright 2018-2020 Alexander Borisov
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,682 @@
1. libmagic (ext/fileinfo) see ext/fileinfo/libmagic/LICENSE
2. libmbfl (ext/mbstring) see ext/mbstring/libmbfl/LICENSE
3. pcre2lib (ext/pcre)
4. ext/standard crypt
5. ext/standard crypt's blowfish implementation
6. ext/standard/rand
7. ext/standard/scanf
8. ext/standard/strnatcmp.c
9. ext/standard/uuencode
10. main/snprintf.c
11. main/strlcat
12. main/strlcpy
13. libgd (ext/gd)
14. ext/phar portions of tar implementations
15. ext/phar/zip.c portion extracted from libzip
16. libbcmath (ext/bcmath) see ext/bcmath/libbcmath/LICENSE
17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
18. avifinfo (ext/standard/libavifinfo) see ext/standard/libavifinfo/LICENSE
19. xxHash (ext/hash/xxhash)
20. Lexbor (ext/lexbor/lexbor) see ext/lexbor/LICENSE
21. Portions of libcperciva (ext/hash/hash_sha_{ni,sse2}.c) see the header in the source file
22. uriparser (ext/uri/uriparser) see ext/uri/uriparser/COPYING
3. pcre2lib (ext/pcre)
PCRE2 LICENCE
-------------
PCRE2 is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Releases 10.00 and above of PCRE2 are distributed under the terms of the "BSD"
licence, as specified below, with one exemption for certain binary
redistributions. The documentation for PCRE2, supplied in the "doc" directory,
is distributed under the same terms as the software itself. The data in the
testdata directory is not copyrighted and is in the public domain.
The basic library functions are written in C and are freestanding. Also
included in the distribution is a just-in-time compiler that can be used to
optimize pattern matching. This is an optional feature that can be omitted when
the library is built.
THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2019 University of Cambridge
All rights reserved.
PCRE2 JUST-IN-TIME COMPILATION SUPPORT
--------------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2010-2019 Zoltan Herczeg
All rights reserved.
STACK-LESS JUST-IN-TIME COMPILER
--------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2009-2019 Zoltan Herczeg
All rights reserved.
THE "BSD" LICENCE
-----------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notices,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notices, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of any
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
------------------------------------------
The second condition in the BSD licence (covering binary redistributions) does
not apply all the way down a chain of software. If binary package A includes
PCRE2, it must respect the condition, but if package B is software that
includes package A, the condition is not imposed on package B unless it uses
PCRE2 independently.
End
4. ext/standard crypt
FreeSec: libcrypt for NetBSD
Copyright (c) 1994 David Burren
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the author nor the names of other contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
5. ext/standard crypt's blowfish implementation
The crypt_blowfish homepage is:
http://www.openwall.com/crypt/
This code comes from John the Ripper password cracker, with reentrant
and crypt(3) interfaces added, but optimizations specific to password
cracking removed.
Written by Solar Designer <solar at openwall.com> in 1998-2011.
No copyright is claimed, and the software is hereby placed in the public
domain. In case this attempt to disclaim copyright and place the software
in the public domain is deemed null and void, then the software is
Copyright (c) 1998-2011 Solar Designer and it is hereby released to the
general public under the following terms:
Redistribution and use in source and binary forms, with or without
modification, are permitted.
There's ABSOLUTELY NO WARRANTY, express or implied.
It is my intent that you should be able to use this on your system,
as part of a software package, or anywhere else to improve security,
ensure compatibility, or for any other purpose. I would appreciate
it if you give credit where it is due and keep your modifications in
the public domain as well, but I don't require that in order to let
you place this code and any modifications you make under a license
of your choice.
This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
"$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
ideas. The password hashing algorithm was designed by David Mazieres
<dm at lcs.mit.edu>. For more information on the level of compatibility,
please refer to the comments in BF_set_key() and to the crypt(3) man page
included in the crypt_blowfish tarball.
There's a paper on the algorithm that explains its design decisions:
http://www.usenix.org/events/usenix99/provos.html
Some of the tricks in BF_ROUND might be inspired by Eric Young's
Blowfish library (I can't be sure if I would think of something if I
hadn't seen his code).
6. ext/standard/rand
The following php_mt_...() functions are based on a C++ class MTRand by
Richard J. Wagner. For more information see the web page at
http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html
Mersenne Twister random number generator -- a C++ class MTRand
Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
The Mersenne Twister is an algorithm for generating random numbers. It
was designed with consideration of the flaws in various other generators.
The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
are far greater. The generator is also fast; it avoids multiplication and
division, and it benefits from caches and pipelines. For more information
see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
Reference
M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
Copyright (C) 2000 - 2003, Richard J. Wagner
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7. ext/standard/scanf
scanf.c --
This file contains the base code which implements sscanf and by extension
fscanf. Original code is from TCL8.3.0 and bears the following copyright:
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., Scriptics Corporation,
and other parties. The following terms apply to all files associated
with the software unless explicitly disclaimed in individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors
and need not follow the licensing terms described here, provided that
the new terms are clearly indicated on the first page of each file where
they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights"
in the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
are acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.
8. ext/standard/strnatcmp.c
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
9. ext/standard/uuencode
Portions of this code are based on Berkeley's uuencode/uudecode
implementation.
Copyright (c) 1983, 1993
The Regents of the University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the University of
California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
10. main/snprintf.c
Copyright (c) 2002, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Sponsored in part by the Defense Advanced Research Projects
Agency (DARPA) and Air Force Research Laboratory, Air Force
Materiel Command, USAF, under agreement number F39502-99-1-0512.
main/spprintf
Copyright (c) 1995-1998 The Apache Group. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. All advertising materials mentioning features or use of this
software must display the following acknowledgment:
"This product includes software developed by the Apache Group
for use in the Apache HTTP server project (http://www.apache.org/)."
4. The names "Apache Server" and "Apache Group" must not be used to
endorse or promote products derived from this software without
prior written permission.
5. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes software developed by the Apache Group
for use in the Apache HTTP server project (http://www.apache.org/)."
THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================
This software consists of voluntary contributions made by many
individuals on behalf of the Apache Group and was originally based
on public domain software written at the National Center for
Supercomputing Applications, University of Illinois, Urbana-Champaign.
For more information on the Apache Group and the Apache HTTP server
project, please see <http://www.apache.org/>.
This code is based on, and used with the permission of, the
SIO stdio-replacement strx_* functions by Panos Tsirigotis
<panos@alumni.cs.colorado.edu> for xinetd.
11. main/strlcat
12. main/strlcpy
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13. libgd (ext/gd)
* Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under
Grant P41-RR02188 by the National Institutes of Health.
* Portions copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004 by Boutell.Com, Inc.
* Portions relating to GD2 format copyright 1999, 2000, 2001, 2002,
2003, 2004 Philip Warner.
* Portions relating to PNG copyright 1999, 2000, 2001, 2002, 2003,
2004 Greg Roelofs.
* Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002,
2003, 2004 John Ellson (ellson@graphviz.org).
* Portions relating to gdft.c copyright 2001, 2002, 2003, 2004 John
Ellson (ellson@graphviz.org).
* Portions copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Pierre-Alain Joye (pierre@libgd.org).
* Portions relating to JPEG and to color quantization copyright
2000, 2001, 2002, 2003, 2004, Doug Becker and copyright (C) 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Thomas
G. Lane. This software is based in part on the work of the
Independent JPEG Group. See the file README-JPEG.TXT for more
information.
* Portions relating to GIF compression copyright 1989 by Jef
Poskanzer and David Rowley, with modifications for thread safety
by Thomas Boutell.
* Portions relating to GIF decompression copyright 1990, 1991, 1993
by David Koblas, with modifications for thread safety by Thomas
Boutell.
* Portions relating to WBMP copyright 2000, 2001, 2002, 2003, 2004
Maurice Szmurlo and Johan Van den Brande.
* Portions relating to GIF animations copyright 2004 Jaakko Hyvätti
(jaakko.hyvatti@iki.fi)
Permission has been granted to copy, distribute and modify gd in
any context without fee, including a commercial application,
provided that this notice is present in user-accessible supporting
documentation.
This does not affect your ownership of the derived work itself,
and the intent is to assure proper credit for the authors of gd,
not to interfere with your productive use of gd. If you have
questions, ask. "Derived works" includes all programs that utilize
the library. Credit must be given in user-accessible
documentation.
This software is provided "AS IS." The copyright holders disclaim
all warranties, either express or implied, including but not
limited to implied warranties of merchantability and fitness for a
particular purpose, with respect to this code and accompanying
documentation.
Although their code does not appear in the current release, the
authors wish to thank David Koblas, David Rowley, and Hutchison
Avenue Software Corporation for their prior contributions.
END OF COPYRIGHT STATEMENT
14. ext/phar portions of tar implementations
portions of tar implementations in ext/phar - phar_tar_octal() are based on an
implementation by Tim Kientzle from libarchive, licensed with this license:
Copyright (c) 2003-2007 Tim Kientzle
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15. ext/phar/zip.c portion extracted from libzip
zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
This function is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <nih@giga.or.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
The OpenLDAP Public License
Version 2.8, 17 August 2003
Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions in source form must retain copyright statements
and notices,
2. Redistributions in binary form must reproduce applicable copyright
statements and notices, this list of conditions, and the following
disclaimer in the documentation and/or other materials provided
with the distribution, and
3. Redistributions must contain a verbatim copy of this document.
The OpenLDAP Foundation may revise this license from time to time.
Each revision is distinguished by a version number. You may use
this Software under terms of this license revision or under the
terms of any subsequent revision of the license.
THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
The names of the authors and copyright holders must not be used in
advertising or otherwise to promote the sale, use or other dealing
in this Software without specific, written prior permission. Title
to copyright in this Software shall at all times remain with copyright
holders.
OpenLDAP is a registered trademark of the OpenLDAP Foundation.
Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
California, USA. All Rights Reserved. Permission to copy and
distribute verbatim copies of this document is granted.
19. xxHash
xxHash - Extremely Fast Hash algorithm
Header File
Copyright (C) 2012-2020 Yann Collet
BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at:
- xxHash homepage: https://www.xxhash.com
- xxHash source repository: https://github.com/Cyan4973/xxHash

View File

@@ -0,0 +1,45 @@
PHP 8.5.8 bundled hashing notices
=================================
Source identity: php-src commit 26b97507444c4fbda072f57dda1820f7b7d5e467.
The final PHP runtime exposes the corresponding MurmurHash3, SHA-3 and FNV
algorithms. The exact source-file identities and upstream statements follow.
ext/hash/murmur/PMurHash.c
SHA-256: 1250fc4212bf980dfd97efb3dfae8fed0dac3bdcfec3f2605a1c19a65a0141ce
MurmurHash3 was written by Austin Appleby, and is placed in the public
domain.
This implementation was written by Shane Day, and is also public domain.
ext/hash/murmur/PMurHash128.c
SHA-256: 09233b7dedf9c8d35da5ba3ffaa57f6e66fa89bb85b32cc9c69b3342d6c164cf
MurmurHash3 was written by Austin Appleby, and is placed in the public
domain.
This is a c++ implementation of MurmurHash3_128 with support for progressive
processing based on PMurHash implementation written by Shane Day.
ext/hash/sha3/generic64lc/KeccakHash.c
SHA-256: 78f55671fa3eb01d6bdc11a22e1c2a58b94340983186733ac0fbce39a6065220
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
denoted as "the implementer".
For more information, feedback or questions, please refer to our websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
ext/hash/hash_fnv.c
SHA-256: 7ed6c5a27cb567babb9202ed281f1c7446331f75e125bf11dc9d6f40f4a6266b
Based on the public domain algorithm found at:
http://www.isthe.com/chongo/tech/comp/fnv/index.html

View File

@@ -0,0 +1,20 @@
SQLite 3.51.0 public-domain notice
==================================
Source archive: https://sqlite.org/2025/sqlite-autoconf-3510000.tar.gz
Source archive SHA-256:
42e26dfdd96aa2e6b1b1be5c88b0887f9959093f650d693cb02eb9c36d146ca5
Amalgamation source identifier:
fb2c931ae597f8d00a37574ff67aeed3eced
The exact sqlite3.c amalgamation in that archive states:
The author disclaims copyright to this source code. In place of
a legal notice, here is a blessing:
May you do good and not evil.
May you find forgiveness for yourself and forgive others.
May you share freely, never taking more than you give.
Authoritative copyright and public-domain status:
https://sqlite.org/copyright.html

View File

@@ -0,0 +1,14 @@
dlmalloc 2.8.6 public-domain notice
====================================
The exact source bundled by Emscripten 4.0.19 is:
https://github.com/emscripten-core/emscripten/blob/08e2de1031913e4ba7963b1c56f35f036a7d4d56/system/lib/dlmalloc.c
Its source header states:
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
http://creativecommons.org/publicdomain/zero/1.0/
Version 2.8.6, 29 August 2012.

View File

@@ -0,0 +1,107 @@
Alliance for Open Media Patent License 1.0
1. License Terms.
1.1. Patent License. Subject to the terms and conditions of this License, each
Licensor, on behalf of itself and successors in interest and assigns,
grants Licensee a non-sublicensable, perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as expressly stated in this
License) patent license to its Necessary Claims to make, use, sell, offer
for sale, import or distribute any Implementation.
1.2. Conditions.
1.2.1. Availability. As a condition to the grant of rights to Licensee to make,
sell, offer for sale, import or distribute an Implementation under
Section 1.1, Licensee must make its Necessary Claims available under
this License, and must reproduce this License with any Implementation
as follows:
a. For distribution in source code, by including this License in the
root directory of the source code with its Implementation.
b. For distribution in any other form (including binary, object form,
and/or hardware description code (e.g., HDL, RTL, Gate Level Netlist,
GDSII, etc.)), by including this License in the documentation, legal
notices, and/or other written materials provided with the
Implementation.
1.2.2. Additional Conditions. This license is directly from Licensor to
Licensee. Licensee acknowledges as a condition of benefiting from it
that no rights from Licensor are received from suppliers, distributors,
or otherwise in connection with this License.
1.3. Defensive Termination. If any Licensee, its Affiliates, or its agents
initiates patent litigation or files, maintains, or voluntarily
participates in a lawsuit against another entity or any person asserting
that any Implementation infringes Necessary Claims, any patent licenses
granted under this License directly to the Licensee are immediately
terminated as of the date of the initiation of action unless 1) that suit
was in response to a corresponding suit regarding an Implementation first
brought against an initiating entity, or 2) that suit was brought to
enforce the terms of this License (including intervention in a third-party
action by a Licensee).
1.4. Disclaimers. The Reference Implementation and Specification are provided
"AS IS" and without warranty. The entire risk as to implementing or
otherwise using the Reference Implementation or Specification is assumed
by the implementer and user. Licensor expressly disclaims any warranties
(express, implied, or otherwise), including implied warranties of
merchantability, non-infringement, fitness for a particular purpose, or
title, related to the material. IN NO EVENT WILL LICENSOR BE LIABLE TO
ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF
ACTION OF ANY KIND WITH RESPECT TO THIS LICENSE, WHETHER BASED ON BREACH
OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR
NOT THE OTHER PARTRY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2. Definitions.
2.1. Affiliate. "Affiliate" means an entity that directly or indirectly
Controls, is Controlled by, or is under common Control of that party.
2.2. Control. "Control" means direct or indirect control of more than 50% of
the voting power to elect directors of that corporation, or for any other
entity, the power to direct management of such entity.
2.3. Decoder. "Decoder" means any decoder that conforms fully with all
non-optional portions of the Specification.
2.4. Encoder. "Encoder" means any encoder that produces a bitstream that can
be decoded by a Decoder only to the extent it produces such a bitstream.
2.5. Final Deliverable. "Final Deliverable" means the final version of a
deliverable approved by the Alliance for Open Media as a Final
Deliverable.
2.6. Implementation. "Implementation" means any implementation, including the
Reference Implementation, that is an Encoder and/or a Decoder. An
Implementation also includes components of an Implementation only to the
extent they are used as part of an Implementation.
2.7. License. "License" means this license.
2.8. Licensee. "Licensee" means any person or entity who exercises patent
rights granted under this License.
2.9. Licensor. "Licensor" means (i) any Licensee that makes, sells, offers
for sale, imports or distributes any Implementation, or (ii) a person
or entity that has a licensing obligation to the Implementation as a
result of its membership and/or participation in the Alliance for Open
Media working group that developed the Specification.
2.10. Necessary Claims. "Necessary Claims" means all claims of patents or
patent applications, (a) that currently or at any time in the future,
are owned or controlled by the Licensor, and (b) (i) would be an
Essential Claim as defined by the W3C Policy as of February 5, 2004
(https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential)
as if the Specification was a W3C Recommendation; or (ii) are infringed
by the Reference Implementation.
2.11. Reference Implementation. "Reference Implementation" means an Encoder
and/or Decoder released by the Alliance for Open Media as a Final
Deliverable.
2.12. Specification. "Specification" means the specification designated by
the Alliance for Open Media as a Final Deliverable for which this
License was issued.

View File

@@ -0,0 +1,108 @@
Alliance for Open Media Patent License 1.0
1. License Terms.
1.1. Patent License. Subject to the terms and conditions of this License, each
Licensor, on behalf of itself and successors in interest and assigns,
grants Licensee a non-sublicensable, perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as expressly stated in this
License) patent license to its Necessary Claims to make, use, sell, offer
for sale, import or distribute any Implementation.
1.2. Conditions.
1.2.1. Availability. As a condition to the grant of rights to Licensee to make,
sell, offer for sale, import or distribute an Implementation under
Section 1.1, Licensee must make its Necessary Claims available under
this License, and must reproduce this License with any Implementation
as follows:
a. For distribution in source code, by including this License in the
root directory of the source code with its Implementation.
b. For distribution in any other form (including binary, object form,
and/or hardware description code (e.g., HDL, RTL, Gate Level Netlist,
GDSII, etc.)), by including this License in the documentation, legal
notices, and/or other written materials provided with the
Implementation.
1.2.2. Additional Conditions. This license is directly from Licensor to
Licensee. Licensee acknowledges as a condition of benefiting from it
that no rights from Licensor are received from suppliers, distributors,
or otherwise in connection with this License.
1.3. Defensive Termination. If any Licensee, its Affiliates, or its agents
initiates patent litigation or files, maintains, or voluntarily
participates in a lawsuit against another entity or any person asserting
that any Implementation infringes Necessary Claims, any patent licenses
granted under this License directly to the Licensee are immediately
terminated as of the date of the initiation of action unless 1) that suit
was in response to a corresponding suit regarding an Implementation first
brought against an initiating entity, or 2) that suit was brought to
enforce the terms of this License (including intervention in a third-party
action by a Licensee).
1.4. Disclaimers. The Reference Implementation and Specification are provided
"AS IS" and without warranty. The entire risk as to implementing or
otherwise using the Reference Implementation or Specification is assumed
by the implementer and user. Licensor expressly disclaims any warranties
(express, implied, or otherwise), including implied warranties of
merchantability, non-infringement, fitness for a particular purpose, or
title, related to the material. IN NO EVENT WILL LICENSOR BE LIABLE TO
ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF
ACTION OF ANY KIND WITH RESPECT TO THIS LICENSE, WHETHER BASED ON BREACH
OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR
NOT THE OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2. Definitions.
2.1. Affiliate. "Affiliate" means an entity that directly or indirectly
Controls, is Controlled by, or is under common Control of that party.
2.2. Control. "Control" means direct or indirect control of more than 50% of
the voting power to elect directors of that corporation, or for any other
entity, the power to direct management of such entity.
2.3. Decoder. "Decoder" means any decoder that conforms fully with all
non-optional portions of the Specification.
2.4. Encoder. "Encoder" means any encoder that produces a bitstream that can
be decoded by a Decoder only to the extent it produces such a bitstream.
2.5. Final Deliverable. "Final Deliverable" means the final version of a
deliverable approved by the Alliance for Open Media as a Final
Deliverable.
2.6. Implementation. "Implementation" means any implementation, including the
Reference Implementation, that is an Encoder and/or a Decoder. An
Implementation also includes components of an Implementation only to the
extent they are used as part of an Implementation.
2.7. License. "License" means this license.
2.8. Licensee. "Licensee" means any person or entity who exercises patent
rights granted under this License.
2.9. Licensor. "Licensor" means (i) any Licensee that makes, sells, offers
for sale, imports or distributes any Implementation, or (ii) a person
or entity that has a licensing obligation to the Implementation as a
result of its membership and/or participation in the Alliance for Open
Media working group that developed the Specification.
2.10. Necessary Claims. "Necessary Claims" means all claims of patents or
patent applications, (a) that currently or at any time in the future,
are owned or controlled by the Licensor, and (b) (i) would be an
Essential Claim as defined by the W3C Policy as of February 5, 2004
(https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential)
as if the Specification was a W3C Recommendation; or (ii) are infringed
by the Reference Implementation.
2.11. Reference Implementation. "Reference Implementation" means an Encoder
and/or Decoder released by the Alliance for Open Media as a Final
Deliverable.
2.12. Specification. "Specification" means the specification designated by
the Alliance for Open Media as a Final Deliverable for which this
License was issued.

View File

@@ -0,0 +1,23 @@
Additional IP Rights Grant (Patents)
------------------------------------
"These implementations" means the copyrightable works that implement the WebM
codecs distributed by Google as part of the WebM Project.
Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable (except as stated in this section) patent license to
make, have made, use, offer to sell, sell, import, transfer, and otherwise
run, modify and propagate the contents of these implementations of WebM, where
such license applies only to those patent claims, both currently owned by
Google and acquired in the future, licensable by Google that are necessarily
infringed by these implementations of WebM. This grant does not include claims
that would be infringed only as a consequence of further modification of these
implementations. If you or your agent or exclusive licensee institute or order
or agree to the institution of patent litigation or any other patent
enforcement activity against any entity (including a cross-claim or
counterclaim in a lawsuit) alleging that any of these implementations of WebM
or any code incorporated within any of these implementations of WebM
constitute direct or contributory patent infringement, or inducement of
patent infringement, then any patent rights granted to you under this License
for these implementations of WebM shall terminate as of the date such
litigation is filed.

83
engines/php/README.md Normal file
View File

@@ -0,0 +1,83 @@
# PHP preg regular-expression engine
Regex Tools runs patterns in the actual PHP 8.5.8 `preg` implementation,
backed by PCRE2 10.44. The browser runtime is the Asyncify build from
`@php-wasm/web-8-5@3.1.46`; its host API is
`@php-wasm/universal@3.1.46`.
The fixed `bridge.php` file is installed in PHP's private virtual filesystem.
Pattern, flags, subject, limits, and replacement are written separately as
JSON. No user-controlled value is evaluated or interpolated into PHP source.
The bridge selects a safe preg delimiter and passes only validated modifiers.
PHP reports `PREG_OFFSET_CAPTURE` positions as UTF-8 bytes. The adapter retains
those native ranges and normalizes code-point boundaries to browser UTF-16.
Unpaired UTF-16 surrogates are rejected before entering the runtime. Without
the `u` modifier, a byte-oriented match that splits a UTF-8 character is
reported as unsupported because it cannot be represented losslessly in a
browser string.
Replacement never asks `preg_replace` to materialize an unbounded result.
Native `preg_match` records remain authoritative; a fixed bridge parser mirrors
PHP 8.5.8's `preg_get_backref()` rules and streams literal/capture bytes into
the requested cap. The identity self-test compares that fixed implementation
with `preg_replace` only as a parity oracle. The bridge returns bounded bytes as
base64 so JSON escaping cannot unexpectedly multiply the transport envelope.
A timeout, cancellation, supersession, or crash terminates the dedicated
worker and its entire PHP WebAssembly heap.
## Exact source and native-component boundary
The shipped `php.wasm` is SHA-256
`ed97ea5422dbf23e0687c98203cc8c6d7f2772a3d71b03d4991d2fdd93a048f0`
from `@php-wasm/web-8-5@3.1.46`. That npm package records WordPress Playground
commit `581c7c172428159eb4e6c5309054a568cd39a97a` (`v3.1.46`). The PHP source
base is tag `php-8.5.8`, tag object
`8a3b5a5124006c11a8fbfce838ec7dd53615cc77`, peeled commit
`26b97507444c4fbda072f57dda1820f7b7d5e467`; the final main module uses
Emscripten 4.0.19 at
`08e2de1031913e4ba7963b1c56f35f036a7d4d56`.
`native-components.json` is the machine-readable inventory for this exact
binary. It records 32 linked source/component surfaces:
- PHP and its bundled PCRE2, libbcmath, timelib/tzdata, libmagic, Lexbor,
libmbfl, uriparser and libavifinfo code;
- zlib, libzip, libxml2, SQLite, libgd, libjpeg-turbo, libpng,
libwebp/libsharpyuv, libavif, libaom/libyuv, OpenSSL, curl, libiconv and
Oniguruma;
- the WordPress Playground wrapper plus the Emscripten runtime, musl,
compiler-rt, libc++, libc++abi and dlmalloc surfaces.
Every versioned external archive or Git route, available archive hash/commit,
runtime evidence, licence/notice route and patent notice is recorded there.
The Oniguruma recipe is the one upstream exception: it cloned its default
branch without a revision. The inventory therefore does not falsely identify
the release tag as the build commit. It pins the exact committed `libonig.a`
blob and SHA-256, its Emscripten 4.0.5 compiler provenance, the installed header
blob, runtime version 6.9.10, audited release source and the bounded upstream
source interval `005482a…3eb317d` before the header changed.
The same inventory explicitly records why GMP, libsodium, tidy and ICU/intl
names found by a raw string scan are not linked extensions: those names are
Zend optimizer metadata or an unshipped side module, and the runtime verifier
asserts their absence. It also records that FreeType is disabled in the exact
libgd recipe even though the recipe's synthetic `gdlib-config --features`
string makes `gd_info()` report it, that ImageMagick/imagick is disabled, and
that libavif's local AOM 3.12.1—not the adjacent standalone AOM 3.13.1
recipe—is linked. Positive extension/library versions, negative detections and
AOM/libjpeg binary markers are executable pack-verification gates.
## Redistribution
The pack explicitly elects PHP License version 4 (`BSD-3-Clause`) for the PHP
8.5.8 codebase through the earlier licence's later-version option.
The pack also carries the exact Zend Engine licence, php-src's official binary
redistribution notice, the CLI HTTP parser's MIT terms, and the
public-domain, CC0 and FNV permission statements for the linked hash
implementations. `@php-wasm` retains GPL-2.0-or-later. Linked LGPL, BSD, MIT,
Apache, zlib, public-domain and patent-notice obligations are carried in 42
independently SHA-256-pinned legal files. The builder copies the inventory and
those exact files into the closed pack; `SHA256SUMS` and
`engine-metadata.json` cover them again, but cannot replace the independent
hashes in the verifier lock.

1082
engines/php/bridge.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,414 @@
{
"schemaVersion": 1,
"scope": {
"asset": "@php-wasm/web-8-5 3.1.46 Asyncify php_8_5.wasm",
"assetSha256": "ed97ea5422dbf23e0687c98203cc8c6d7f2772a3d71b03d4991d2fdd93a048f0",
"assetBytes": 21019221,
"phpVersion": "8.5.8",
"phpBuildDate": "Jul 8 2026 07:06:40",
"platform": "wasm32-emscripten",
"purpose": "Complete legal and source inventory for the exact shipped PHP WebAssembly main module"
},
"buildProvenance": {
"wordpressPlayground": {
"release": "v3.1.46",
"commit": "581c7c172428159eb4e6c5309054a568cd39a97a",
"repository": "https://github.com/WordPress/wordpress-playground",
"packageGitHead": "581c7c172428159eb4e6c5309054a568cd39a97a"
},
"php": {
"version": "8.5.8",
"tag": "php-8.5.8",
"tagObject": "8a3b5a5124006c11a8fbfce838ec7dd53615cc77",
"commit": "26b97507444c4fbda072f57dda1820f7b7d5e467",
"repository": "https://github.com/php/php-src"
},
"emscripten": {
"version": "4.0.19",
"commit": "08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"repository": "https://github.com/emscripten-core/emscripten"
},
"recipe": {
"path": "packages/php-wasm/compile/php/Dockerfile",
"variant": "web Asyncify with the platform-default feature set",
"sourceUrl": "https://github.com/WordPress/wordpress-playground/blob/581c7c172428159eb4e6c5309054a568cd39a97a/packages/php-wasm/compile/php/Dockerfile"
}
},
"linkedComponents": [
{
"id": "wordpress-playground-php-wasm",
"version": "3.1.46",
"source": "WordPress Playground commit 581c7c172428159eb4e6c5309054a568cd39a97a",
"license": "GPL-2.0-or-later",
"legalFiles": ["LICENSE.php-wasm-GPL-2.0-or-later.txt"],
"evidence": "npm package gitHead and integrity plus exact loader/WebAssembly hashes"
},
{
"id": "php",
"version": "8.5.8",
"source": "php-src commit 26b97507444c4fbda072f57dda1820f7b7d5e467, patched by the pinned WordPress Playground recipe",
"license": "PHP-4.0 (BSD-3-Clause) plus separately identified bundled-source terms",
"legalFiles": [
"LICENSE.PHP-4.0.txt",
"LICENSE.PHP-Zend-2.0.txt",
"NOTICE.PHP-REDIST-BINS.txt",
"LICENSE.PHP-CLI-http-parser-MIT.txt",
"NOTICE.PHP-public-domain-hash-code.txt"
],
"bundledSourceNotices": [
{
"component": "Zend Engine",
"source": "php-src Zend/LICENSE at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "Zend Engine License version 2.00",
"legalFile": "LICENSE.PHP-Zend-2.0.txt"
},
{
"component": "php-src binary redistribution notices",
"source": "php-src README.REDIST.BINS at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"legalFile": "NOTICE.PHP-REDIST-BINS.txt"
},
{
"component": "CLI HTTP parser",
"source": "php-src sapi/cli/php_http_parser.c at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"sourceSha256": "5c601ebbeaceda9ae3018be99e56cedc1568211a22ecdc19a9ac7bcb9f8a303e",
"license": "MIT",
"legalFile": "LICENSE.PHP-CLI-http-parser-MIT.txt"
},
{
"component": "bundled hash implementations",
"source": "php-src ext/hash at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"algorithms": ["FNV", "Keccak/SHA-3", "MurmurHash3"],
"license": "Public-Domain, CC0-1.0 and MIT-like permission",
"legalFile": "NOTICE.PHP-public-domain-hash-code.txt"
}
],
"evidence": "PHP_VERSION and PHP_BUILD_DATE runtime constants; the loaded Zend engine, CLI SAPI source marker and hash_algos() runtime audit"
},
{
"id": "pcre2",
"version": "10.44",
"source": "php-src ext/pcre/pcre2lib at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "PCRE2 BSD licence",
"legalFiles": ["LICENSE.PCRE2-10.44.txt"],
"evidence": "PCRE_VERSION=10.44 2024-06-07"
},
{
"id": "php-libbcmath",
"version": "PHP 8.5.8 vendored snapshot",
"source": "php-src ext/bcmath/libbcmath at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "LGPL-2.0-or-later",
"legalFiles": ["LICENSE.PHP-bcmath-LGPL-2.1.txt"],
"evidence": "loaded bcmath extension and exact php-src source identity"
},
{
"id": "timelib",
"version": "2022.15",
"source": "php-src ext/date/lib at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "MIT",
"legalFiles": ["LICENSE.PHP-timelib-MIT.txt"],
"evidence": "timelib version in runtime module information"
},
{
"id": "iana-tzdata",
"version": "2026.1",
"source": "php-src ext/date/lib/timezonedb.h at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "Public-Domain",
"legalFiles": ["NOTICE.IANA-TZDATA-2026.1.txt"],
"evidence": "runtime Timezone Database Version=2026.1"
},
{
"id": "php-libmagic",
"version": "PHP 8.5.8 vendored snapshot",
"source": "php-src ext/fileinfo/libmagic at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "BSD-2-Clause",
"legalFiles": ["LICENSE.PHP-libmagic-BSD.txt"],
"evidence": "loaded fileinfo extension and exact php-src source identity"
},
{
"id": "lexbor",
"version": "2.7.0",
"source": "php-src ext/lexbor at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "Apache-2.0",
"legalFiles": [
"LICENSE.PHP-Lexbor-Apache-2.0.txt",
"NOTICE.PHP-Lexbor.txt"
],
"evidence": "loaded lexbor extension and runtime Lexbor version=2.7.0"
},
{
"id": "libmbfl",
"version": "1.3.2",
"source": "php-src ext/mbstring/libmbfl at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "LGPL-2.1",
"legalFiles": ["LICENSE.PHP-libmbfl-LGPL-2.1.txt"],
"evidence": "loaded mbstring extension and runtime libmbfl version=1.3.2"
},
{
"id": "php-uriparser",
"version": "1.0.2",
"source": "php-src ext/uri/uriparser at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "BSD-3-Clause",
"legalFiles": ["LICENSE.PHP-uriparser-BSD-3-Clause.txt"],
"evidence": "loaded uri extension and runtime bundled version=1.0.2"
},
{
"id": "php-libavifinfo",
"version": "PHP 8.5.8 vendored snapshot",
"source": "php-src ext/standard/libavifinfo at commit 26b97507444c4fbda072f57dda1820f7b7d5e467",
"license": "BSD-2-Clause with Alliance for Open Media Patent License 1.0",
"legalFiles": [
"LICENSE.PHP-libavifinfo-BSD-2-Clause.txt",
"PATENTS.PHP-libavifinfo.txt"
],
"evidence": "loaded standard extension and exact php-src source identity"
},
{
"id": "zlib",
"version": "1.2.13",
"source": "https://www.zlib.net/fossils/zlib-1.2.13.tar.gz",
"sourceArchiveSha256": "b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30",
"sourceCommit": "04f42ceca40f73e2978b50e93806c2a18c1281fc",
"license": "Zlib",
"legalFiles": ["LICENSE.zlib-1.2.13.txt"],
"evidence": "ZLIB_VERSION=1.2.13 and cURL linked zlib version"
},
{
"id": "libzip",
"version": "1.9.2",
"source": "https://libzip.org/download/libzip-1.9.2.tar.gz",
"sourceArchiveSha256": "fd6a7f745de3d69cf5603edc9cb33d2890f0198e415255d0987a0cf10d824c6f",
"sourceCommit": "5532f9baa0c44cc5435ad135686a4ea009075b9a",
"license": "BSD-3-Clause",
"legalFiles": ["LICENSE.libzip-1.9.2.txt"],
"evidence": "ZipArchive::LIBZIP_VERSION=1.9.2"
},
{
"id": "libxml2",
"version": "2.9.10",
"source": "https://gitlab.gnome.org/GNOME/libxml2/-/tree/41a34e1f4ffae2ce401600dbb5fe43f8fe402641",
"sourceCommit": "41a34e1f4ffae2ce401600dbb5fe43f8fe402641",
"license": "MIT",
"legalFiles": ["LICENSE.libxml2-2.9.10.txt"],
"evidence": "LIBXML_DOTTED_VERSION=2.9.10 and loaded version=20910-GITv2.9.10"
},
{
"id": "sqlite",
"version": "3.51.0",
"source": "https://sqlite.org/2025/sqlite-autoconf-3510000.tar.gz",
"sourceArchiveSha256": "42e26dfdd96aa2e6b1b1be5c88b0887f9959093f650d693cb02eb9c36d146ca5",
"sourceId": "fb2c931ae597f8d00a37574ff67aeed3eced",
"license": "Public-Domain",
"legalFiles": ["NOTICE.SQLite-3.51.0.txt"],
"evidence": "SQLite3::version()=3.51.0"
},
{
"id": "libgd",
"version": "2.3.3",
"source": "https://github.com/libgd/libgd/releases/download/gd-2.3.3/libgd-2.3.3.tar.gz",
"sourceArchiveSha256": "dd3f1f0bb016edcc0b2d082e8229c822ad1d02223511997c80461481759b1ed2",
"sourceCommit": "b5319a41286107b53daa0e08e402aa1819764bdc",
"license": "BSD-like bundled terms",
"legalFiles": ["LICENSE.libgd-2.3.3.txt"],
"evidence": "GD_VERSION=2.3.3"
},
{
"id": "libjpeg-turbo",
"version": "3.0.3",
"source": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.0.3/libjpeg-turbo-3.0.3.tar.gz",
"sourceArchiveSha256": "343e789069fc7afbcdfe44dbba7dbbf45afa98a15150e079a38e60e44578865d",
"sourceCommit": "7fa4b5b762c9a99b46b0b7838f5fd55071b92ea5",
"license": "IJG AND BSD-3-Clause AND Zlib",
"legalFiles": ["LICENSE.libjpeg-turbo-3.0.3.txt"],
"evidence": "binary version marker libjpeg-turbo 3.0.3"
},
{
"id": "libpng",
"version": "1.6.39",
"source": "https://prdownloads.sourceforge.net/libpng/libpng-1.6.39.tar.gz?download",
"sourceArchiveSha256": "af4fb7f260f839919e5958e5ab01a275d4fe436d45442a36ee62f73e5beb75ba",
"sourceCommit": "07b8803110da160b158ebfef872627da6c85cbdf",
"license": "Libpng",
"legalFiles": ["LICENSE.libpng-1.6.39.txt"],
"evidence": "binary version marker 1.6.39 and GD PNG support"
},
{
"id": "libwebp-and-libsharpyuv",
"version": "commit 845d5476a866141ba35ac133f856fa62f0b7445f",
"source": "https://chromium.googlesource.com/webm/libwebp/+archive/845d5476a866141ba35ac133f856fa62f0b7445f.tar.gz",
"sourceArchiveSha256": "c68cbb9501e11d2686ec027b550867214c2e9232678a28ddafaa0abcb96ab4c4",
"sourceCommit": "845d5476a866141ba35ac133f856fa62f0b7445f",
"license": "BSD-3-Clause with WebM patent grant",
"legalFiles": ["LICENSE.libwebp.txt", "PATENTS.libwebp.txt"],
"evidence": "exact WordPress build-recipe commit and linked libwebp/libsharpyuv archives"
},
{
"id": "libavif",
"version": "1.3.0",
"source": "https://github.com/AOMediaCodec/libavif/archive/refs/tags/v1.3.0.tar.gz",
"sourceArchiveSha256": "0a545e953cc049bf5bcf4ee467306a2f113a75110edf59e61248873101cd26c1",
"sourceCommit": "1aadfad932c98c069a1204261b1856f81f3bc199",
"license": "BSD-2-Clause plus bundled component terms",
"legalFiles": ["LICENSE.libavif-1.3.0.txt"],
"evidence": "WordPress build recipe uses AVIF_CODEC_AOM=LOCAL and GD reports AVIF support"
},
{
"id": "libaom",
"version": "3.12.1",
"source": "https://aomedia.googlesource.com/aom/+archive/v3.12.1.tar.gz",
"sourceArchiveSha256": "8ecd25e39c4c94240d3aba272f8bde80f7a1c0448843c50d17a3eba54bd68586",
"sourceCommit": "10aece4157eb79315da205f39e19bf6ab3ee30d0",
"license": "BSD-2-Clause with Alliance for Open Media Patent License 1.0",
"legalFiles": ["LICENSE.libaom-3.12.1.txt", "PATENTS.libaom-3.12.1.txt"],
"evidence": "libavif v1.3.0 LocalAom.cmake pins v3.12.1; binary encoder and decoder version markers confirm 3.12.1"
},
{
"id": "libyuv",
"version": "snapshot vendored by libaom 3.12.1",
"source": "third_party/libyuv in the exact libaom v3.12.1 archive",
"license": "BSD-3-Clause",
"legalFiles": ["LICENSE.libyuv.txt"],
"evidence": "libavif LOCAL AOM build enables AOM's bundled libyuv path"
},
{
"id": "openssl",
"version": "1.1.1t",
"source": "https://www.openssl.org/source/openssl-1.1.1t.tar.gz",
"sourceArchiveSha256": "8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b",
"sourceCommit": "830bf8e1e4749ad65c51b6a1d0d769ae689404ba",
"license": "OpenSSL and Original SSLeay licences",
"legalFiles": ["LICENSE.OpenSSL-1.1.1t.txt"],
"evidence": "OPENSSL_VERSION_TEXT and cURL SSL version both report OpenSSL 1.1.1t"
},
{
"id": "curl",
"version": "7.69.1",
"source": "https://curl.se/download/curl-7.69.1.tar.gz",
"sourceArchiveSha256": "01ae0c123dee45b01bbaef94c0bc00ed2aec89cb2ee0fd598e0d302a6b5e0a98",
"sourceCommit": "b81e0b07784dc4c1e8d0a86194b9d28776d071c0",
"license": "curl",
"legalFiles": ["LICENSE.curl-7.69.1.txt"],
"evidence": "curl_version()=7.69.1"
},
{
"id": "libiconv",
"version": "1.17",
"source": "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.17.tar.gz",
"sourceArchiveSha256": "8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313",
"license": "LGPL-2.1-or-later",
"legalFiles": ["LICENSE.libiconv-1.17-LGPL-2.1.txt"],
"evidence": "ICONV_VERSION=1.17"
},
{
"id": "oniguruma",
"version": "6.9.10",
"source": "WordPress Playground prebuilt archive at commit b38db761632d860bd519021d33a2230117841ee4",
"linkedArchiveGitBlob": "1e4a8d4f15b680d2f93433cb1adbb7dcd499b0a5",
"linkedArchiveSha256": "d040c88febc3d7f3548860b096640966647b34c118887041f25f51f3259eb36f",
"buildCompiler": "Emscripten 4.0.5 (the archive was later linked into the Emscripten 4.0.19 main module)",
"auditedReleaseCommit": "4ef89209a239c1aea328cf13c05a2807e5c146d1",
"auditedReleaseArchiveSha256": "ad92309d0d13eebc27f6592e875f3efbfa3dda2bf6da5952e00f0a2120c921a8",
"upstreamSourceRange": {
"firstCommitWithExactInstalledHeader": "005482a534c821017882bc5ab1940b842b426081",
"lastCommitBeforeHeaderChanged": "3eb317dc4413692e4eaa92a68839c74aa74fbc77",
"excludingCommit": "ba9abef9cdbeed860c18d02a66b682f549b35a82",
"installedHeaderGitBlob": "22e9b317b95bb55ac8e9d9da93fc4f64d3930f4a"
},
"buildCommitStatus": "The upstream recipe cloned its default branch without a revision. The exact build-time HEAD is not recoverable; the committed archive, installed header, runtime version and bounded upstream source interval are pinned instead of falsely claiming the v6.9.10 tag.",
"license": "BSD-2-Clause",
"legalFiles": ["LICENSE.Oniguruma-6.9.10.txt"],
"evidence": "MB_ONIGURUMA_VERSION=6.9.10; exact committed archive and header blobs; the exact shipped WebAssembly hash remains the final binary identity"
},
{
"id": "emscripten-runtime",
"version": "4.0.19",
"source": "Emscripten commit 08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"license": "MIT OR NCSA",
"legalFiles": ["LICENSE.Emscripten-4.0.19.txt"],
"evidence": "pinned WordPress base-image recipe and generated main-module loader/runtime"
},
{
"id": "musl-libc",
"version": "Emscripten 4.0.19 snapshot",
"source": "Emscripten system/lib/libc/musl at commit 08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"license": "MIT and component notices",
"legalFiles": ["LICENSE.musl.txt"],
"evidence": "Emscripten libc linked into the main module"
},
{
"id": "llvm-compiler-rt",
"version": "Emscripten 4.0.19 snapshot",
"source": "Emscripten system/lib/compiler-rt at commit 08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"license": "Apache-2.0 WITH LLVM-exception (current code) and NCSA OR MIT (legacy code)",
"legalFiles": ["LICENSE.llvm-compiler-rt.txt"],
"evidence": "compiler-rt builtins such as __extenddftf2 are defined in the main module"
},
{
"id": "llvm-libcxx",
"version": "Emscripten 4.0.19 snapshot",
"source": "Emscripten system/lib/libcxx at commit 08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"license": "Apache-2.0 WITH LLVM-exception",
"legalFiles": ["LICENSE.libcxx.txt"],
"evidence": "C++ standard-library symbols are defined in the main module"
},
{
"id": "llvm-libcxxabi",
"version": "Emscripten 4.0.19 snapshot",
"source": "Emscripten system/lib/libcxxabi at commit 08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"license": "Apache-2.0 WITH LLVM-exception",
"legalFiles": ["LICENSE.libcxxabi.txt"],
"evidence": "__cxa and C++ RTTI symbols are defined in the main module"
},
{
"id": "dlmalloc",
"version": "2.8.6",
"source": "Emscripten system/lib/dlmalloc.c at commit 08e2de1031913e4ba7963b1c56f35f036a7d4d56",
"license": "Public-Domain",
"legalFiles": ["NOTICE.dlmalloc-2.8.6.txt"],
"evidence": "Emscripten default allocator source for this build"
}
],
"excludedDetections": [
{
"id": "gmp",
"status": "not linked",
"runtimeEvidence": "extension_loaded('gmp')=false and function_exists('gmp_init')=false",
"rawStringExplanation": "gmp_* names are compiled into Zend/Optimizer/zend_func_infos.h for optimization metadata even when ext/gmp is absent"
},
{
"id": "libsodium",
"status": "not linked",
"runtimeEvidence": "extension_loaded('sodium')=false and function_exists('sodium_crypto_box')=false",
"rawStringExplanation": "sodium_* names are compiled into Zend/Optimizer/zend_func_infos.h for optimization metadata even when ext/sodium is absent"
},
{
"id": "tidy",
"status": "not linked",
"runtimeEvidence": "extension_loaded('tidy')=false, function_exists('tidy_parse_string')=false and class_exists('tidy')=false",
"rawStringExplanation": "generic tidy strings and PHP credit/name tables are not evidence of libtidy"
},
{
"id": "intl-and-icu",
"status": "not shipped",
"runtimeEvidence": "extension_loaded('intl')=false and class_exists('IntlDateFormatter')=false",
"rawStringExplanation": "intlcal_* names come from Zend optimizer metadata; the npm package's separate intl.so side module is outside the pack's closed file set"
},
{
"id": "freetype",
"status": "not linked",
"runtimeEvidence": "the exact libgd recipe sets ENABLE_FREETYPE=OFF and supplies stubs",
"rawStringExplanation": "phpinfo reports a synthetic gdlib-config feature string, but the final link contains no FreeType archive"
},
{
"id": "imagemagick-and-imagick",
"status": "not linked",
"runtimeEvidence": "extension_loaded('imagick')=false and class_exists('Imagick')=false",
"rawStringExplanation": "the web build sets WITH_IMAGICK=no"
},
{
"id": "standalone-libaom-3.13.1-recipe",
"status": "not linked",
"runtimeEvidence": "the final link consumes libavif's LOCAL AOM 3.12.1 build and the binary reports encoder/decoder 3.12.1",
"rawStringExplanation": "the neighbouring 3.13.1 library recipe is not a dependency of this libavif build"
}
]
}

285
engines/python/bridge.py Normal file
View File

@@ -0,0 +1,285 @@
"""Fixed, bounded CPython ``re`` bridge used by the Python engine worker.
This file is bundled as source by Vite and evaluated once while the trusted
Pyodide runtime starts. User-controlled values are passed as function
arguments; they are never evaluated as Python source.
"""
import base64
import json
import re
import sys
_BRIDGE_ABI_VERSION = 1
_MAX_CAPTURE_GROUPS = 1_000
_MAX_NATIVE_EXPANSION_CODE_POINTS = 16 * 1024 * 1024
def _json_result(value):
return json.dumps(value, ensure_ascii=True, separators=(",", ":"))
def _error(phase, code, error, position=None):
message = str(error)
if len(message) > 1_024:
message = message[:1_023] + "\N{HORIZONTAL ELLIPSIS}"
result = {
"abi": _BRIDGE_ABI_VERSION,
"ok": False,
"phase": phase,
"code": code,
"message": message,
}
if isinstance(position, int) and position >= 0:
result["position"] = position
return _json_result(result)
def _flag_bits(flags):
bits = 0
if "a" in flags:
bits |= re.ASCII
if "i" in flags:
bits |= re.IGNORECASE
if "m" in flags:
bits |= re.MULTILINE
if "s" in flags:
bits |= re.DOTALL
if "x" in flags:
bits |= re.VERBOSE
return bits
def _match_record(match, group_count):
captures = []
for group_number in range(1, group_count + 1):
start, end = match.span(group_number)
captures.append(None if start < 0 else [start, end])
start, end = match.span(0)
return {"span": [start, end], "captures": captures}
def _utf8_width(character):
code_point = ord(character)
if code_point <= 0x7F:
return 1
if code_point <= 0x7FF:
return 2
if code_point <= 0xFFFF:
return 3
return 4
def _append_utf8_bounded(chunks, value, byte_count, maximum_bytes):
remaining = maximum_bytes - byte_count
if not value:
return byte_count, True
end = 0
for character in value:
width = _utf8_width(character)
if width > remaining:
break
remaining -= width
byte_count += width
end += 1
if end:
chunks.append(value[:end])
return byte_count, end == len(value)
def _expansion_code_points(parsed_template, match):
total = 0
for part in parsed_template:
if isinstance(part, int):
start, end = match.span(part)
if start >= 0:
total += end - start
else:
total += len(part)
if total > _MAX_NATIVE_EXPANSION_CODE_POINTS:
return total
return total
def _identity():
return _json_result(
{
"abi": _BRIDGE_ABI_VERSION,
"ok": True,
"identity": {
"implementation": sys.implementation.name,
"pythonVersion": ".".join(
str(part) for part in sys.version_info[:3]
),
"reModule": re.__name__,
},
}
)
def _regex_tools_run(
operation,
pattern,
flags,
subject,
maximum_matches,
maximum_capture_rows,
replacement,
maximum_output_bytes,
):
if operation == "identity":
return _identity()
if operation not in ("execute", "replace"):
return _error("bridge", "invalid-operation", "Unsupported bridge operation.")
try:
compiled = re.compile(pattern, _flag_bits(flags))
except re.PatternError as error:
return _error(
"compile",
"compile-error",
error,
getattr(error, "pos", None),
)
except Exception as error:
return _error("compile", "compile-error", error)
group_count = compiled.groups
if group_count > _MAX_CAPTURE_GROUPS:
return _error(
"compile",
"capture-group-limit",
(
f"The pattern declares {group_count} capture groups; "
f"the bridge limit is {_MAX_CAPTURE_GROUPS}."
),
)
group_names = sorted(
([group_number, name] for name, group_number in compiled.groupindex.items()),
key=lambda item: item[0],
)
parsed_template = None
if operation == "replace":
try:
parsed_template = re._parser.parse_template(replacement, compiled)
except (re.PatternError, IndexError) as error:
return _error(
"replacement",
"replacement-error",
error,
getattr(error, "pos", None),
)
except Exception as error:
return _error("replacement", "replacement-error", error)
iterate = "g" in flags
try:
matches = compiled.finditer(subject) if iterate else (
candidate for candidate in (compiled.search(subject),) if candidate
)
records = []
capture_rows = 0
results_truncated = False
output_chunks = []
output_bytes = 0
output_truncated = False
output_stopped = False
next_source_position = 0
for match in matches:
rows_for_match = max(1, group_count)
if (
len(records) >= maximum_matches
or capture_rows + rows_for_match > maximum_capture_rows
):
results_truncated = True
break
records.append(_match_record(match, group_count))
capture_rows += rows_for_match
if operation == "replace" and not output_stopped:
start, end = match.span(0)
output_bytes, complete = _append_utf8_bounded(
output_chunks,
subject[next_source_position:start],
output_bytes,
maximum_output_bytes,
)
if not complete:
output_truncated = True
output_stopped = True
else:
expansion_size = _expansion_code_points(
parsed_template, match
)
if expansion_size > _MAX_NATIVE_EXPANSION_CODE_POINTS:
return _error(
"replacement",
"replacement-expansion-limit",
(
"One native match expansion exceeds the "
f"{_MAX_NATIVE_EXPANSION_CODE_POINTS} "
"code-point safety limit."
),
)
expanded = match.expand(replacement)
output_bytes, complete = _append_utf8_bounded(
output_chunks,
expanded,
output_bytes,
maximum_output_bytes,
)
if not complete:
output_truncated = True
output_stopped = True
next_source_position = end
if operation == "replace" and not output_stopped:
output_bytes, complete = _append_utf8_bounded(
output_chunks,
subject[next_source_position:],
output_bytes,
maximum_output_bytes,
)
if not complete:
output_truncated = True
result = {
"abi": _BRIDGE_ABI_VERSION,
"ok": True,
"groupCount": group_count,
"groupNames": group_names,
"matches": records,
"resultsTruncated": results_truncated,
}
if operation == "replace":
output = "".join(output_chunks).encode("utf-8")
if len(output) != output_bytes:
return _error(
"bridge",
"output-byte-count-mismatch",
"The bounded Python output byte count is inconsistent.",
)
result.update(
{
"outputBase64": base64.b64encode(output).decode("ascii"),
"outputBytes": output_bytes,
"outputTruncated": output_truncated,
}
)
return _json_result(result)
except re.PatternError as error:
phase = "replacement" if operation == "replace" else "match"
code = "replacement-error" if operation == "replace" else "match-error"
return _error(phase, code, error, getattr(error, "pos", None))
except Exception as error:
phase = "replacement" if operation == "replace" else "match"
code = "replacement-error" if operation == "replace" else "match-error"
return _error(phase, code, error)
_regex_tools_run

37
engines/ruby/README.md Normal file
View File

@@ -0,0 +1,37 @@
# Ruby regular-expression engine
Regex Tools executes Ruby expressions in the actual CRuby 4.0.0 engine built
for `wasm32-wasi` by ruby.wasm. The reviewed runtime is the minimal
`ruby.wasm` from `@ruby/4.0-wasm-wasi@2.9.3-2.9.4`; the JavaScript host API is
`@ruby/wasm-wasi@2.9.3-2.9.4`.
The fixed `bridge.rb` module is evaluated once during worker start. Pattern,
flags, subject, limits and replacement travel through a bounded,
length-prefixed file in the worker-local WASI memory filesystem. Bounded inert
JSON returns metadata only; replacement output is written as UTF-8 to a
separate bounded worker-local file. No user-controlled value is evaluated or
interpolated as Ruby or JavaScript source, and the bridge does not use the
ruby.wasm `JS.eval` conversion path.
CRuby performs compilation and matching and reports character offsets, which
the adapter exposes as Unicode code-point native offsets and normalizes to
browser UTF-16 ranges. Native `String#gsub`/`String#sub` block iteration drives
replacement matching without materializing expanded output. A fixed streaming
implementation of CRuby 4.0.0's `rb_reg_regsub` grammar handles `\1` through
`\9`, `\k<name>`, `\0`, `\&`, ``\` ``, `\'`, `\+`, and `\\`; a load-time
bounded fixture verifies parity with CRuby. The expander stops on a valid UTF-8
boundary at the configured byte limit. Unpaired browser UTF-16 surrogates are
rejected before request encoding. A workbench timeout, cancellation,
supersession or crash terminates the dedicated worker and its complete
WebAssembly heap.
The deterministic pack contains only:
- `ruby.wasm`;
- `engine-metadata.json`;
- `SHA256SUMS`;
- ruby.wasm's exact `LICENSE.txt`;
- ruby.wasm's complete `NOTICE.txt`, including CRuby and bundled third-party
notices; and
- the exact browser WASI shim and `tslib` license texts required by the
JavaScript host bundle.

605
engines/ruby/bridge.rb Normal file
View File

@@ -0,0 +1,605 @@
# frozen_string_literal: true
# Fixed bridge evaluated once inside the bundled CRuby WebAssembly runtime.
#
# JavaScript writes one bounded, length-prefixed request to the worker-local
# WASI memory filesystem. User-controlled pattern, subject and replacement
# strings are never interpolated into Ruby or JavaScript source. Replacement
# matching is driven by CRuby String#gsub/String#sub block iteration, while a
# fixed streaming implementation of CRuby 4.0.0's rb_reg_regsub grammar writes
# only the requested UTF-8 prefix to a separate worker-local output file.
module RegexToolsRubyBridge
ABI_VERSION = 2
MAXIMUM_CAPTURE_GROUPS = 1_000
MAXIMUM_ERROR_CHARACTERS = 1_024
MAXIMUM_REQUEST_BYTES = 18 * 1024 * 1024
MAXIMUM_RESPONSE_BYTES = 16 * 1024 * 1024
MAXIMUM_MATCHES = 10_000
MAXIMUM_CAPTURE_ROWS = 100_000
MAXIMUM_OUTPUT_BYTES = 64 * 1024 * 1024
REQUEST_FIELD_COUNT = 8
REQUEST_FILE = "/regex-tools-request.bin"
OUTPUT_FILE = "/regex-tools-output.bin"
REQUEST_MAGIC = "RGXRUBY1".b
REPLACEMENT_STOP = :regex_tools_replacement_stop
HEX_DIGITS = "0123456789abcdef"
class ReplacementFailure < StandardError
attr_reader :original
def initialize(original)
@original = original
super(original.message)
set_backtrace(original.backtrace)
end
end
class BoundedUtf8Output
attr_reader :bytes
def initialize(maximum_bytes)
@maximum_bytes = maximum_bytes
@value = String.new(capacity: [maximum_bytes, 64 * 1024].min)
@value.force_encoding(Encoding::UTF_8)
@bytes = 0
@truncated = false
end
def append(value, byte_start = 0, byte_length = nil)
byte_length ||= value.bytesize - byte_start
return true if byte_length <= 0
return false if @truncated
remaining = @maximum_bytes - @bytes
if byte_length <= remaining
@value << value.byteslice(byte_start, byte_length)
@bytes += byte_length
return true
end
prefix = value.byteslice(byte_start, remaining)
prefix = prefix.byteslice(0, prefix.bytesize - 1) until prefix.valid_encoding?
@value << prefix
@bytes += prefix.bytesize
@truncated = true
false
end
def truncated?
@truncated
end
def value
@value
end
end
class << self
def run
reset_output
encode_json(run_record(*read_request))
rescue StandardError => error
begin
reset_output
rescue StandardError
# The original bridge error is more useful than a secondary cleanup
# failure. The adapter will still reject a stale output byte count.
end
encode_json(error_record("bridge", "bridge-error", error))
end
private
def reset_output
File.binwrite(OUTPUT_FILE, "".b)
end
def read_request
data = File.binread(REQUEST_FILE)
unless data.bytesize <= MAXIMUM_REQUEST_BYTES &&
data.byteslice(0, REQUEST_MAGIC.bytesize) == REQUEST_MAGIC
raise ArgumentError, "Invalid Ruby bridge request."
end
offset = REQUEST_MAGIC.bytesize
fields = REQUEST_FIELD_COUNT.times.map do
raise ArgumentError, "Truncated Ruby bridge request." if offset + 4 > data.bytesize
length = data.getbyte(offset) << 24 |
data.getbyte(offset + 1) << 16 |
data.getbyte(offset + 2) << 8 |
data.getbyte(offset + 3)
offset += 4
raise ArgumentError, "Truncated Ruby bridge field." if offset + length > data.bytesize
field = data.byteslice(offset, length)
offset += length
field.force_encoding(Encoding::UTF_8)
raise ArgumentError, "Invalid UTF-8 Ruby bridge field." unless field.valid_encoding?
field
end
raise ArgumentError, "Trailing Ruby bridge request data." unless offset == data.bytesize
fields
end
def bounded_integer(value, label, maximum)
text = value.to_s
unless /\A[1-9][0-9]*\z/.match?(text)
raise ArgumentError, "#{label} must be a positive decimal integer."
end
number = text.to_i
unless number <= maximum
raise ArgumentError, "#{label} exceeds the Ruby bridge limit."
end
number
end
def run_record(
operation_value,
pattern_value,
flags_value,
subject_value,
maximum_matches_value,
maximum_capture_rows_value,
replacement_value,
maximum_output_bytes_value
)
operation = operation_value.to_s
return identity if operation == "identity"
unless operation == "execute" || operation == "replace"
return error_record(
"bridge",
"invalid-operation",
"Unsupported Ruby bridge operation."
)
end
pattern = pattern_value.to_s
flags = flags_value.to_s
subject = subject_value.to_s
replacement = replacement_value.to_s
maximum_matches = bounded_integer(
maximum_matches_value,
"maximumMatches",
MAXIMUM_MATCHES
)
maximum_capture_rows = bounded_integer(
maximum_capture_rows_value,
"maximumCaptureRows",
MAXIMUM_CAPTURE_ROWS
)
maximum_output_bytes = bounded_integer(
maximum_output_bytes_value,
"maximumOutputBytes",
MAXIMUM_OUTPUT_BYTES
)
unless /\A[gimx]*\z/.match?(flags) && flags.each_char.uniq.length == flags.length
return error_record(
"bridge",
"invalid-flags",
"The Ruby bridge received unsupported or duplicate flags."
)
end
regexp = compile(pattern, flags)
return regexp if regexp.is_a?(Hash)
group_count = capture_group_count(regexp)
if group_count > MAXIMUM_CAPTURE_GROUPS
return error_record(
"compile",
"capture-group-limit",
"The pattern declares #{group_count} capture groups; " \
"the bridge limit is #{MAXIMUM_CAPTURE_GROUPS}."
)
end
begin
collected = collect_matches(
regexp,
subject,
flags.include?("g"),
group_count,
maximum_matches,
maximum_capture_rows,
operation == "replace" ? replacement : nil,
maximum_output_bytes
)
rescue ReplacementFailure => error
return error_record(
"replacement",
"replacement-error",
error.original
)
rescue StandardError => error
return error_record("match", "match-error", error)
end
result = {
"abi" => ABI_VERSION,
"ok" => true,
"groupCount" => group_count,
"groupNames" => capture_group_names(regexp),
"matches" => collected["matches"],
"resultsTruncated" => collected["resultsTruncated"]
}
return result if operation == "execute"
File.binwrite(OUTPUT_FILE, collected["output"])
result.merge(
"outputBytes" => collected["outputBytes"],
"outputTruncated" => collected["outputTruncated"]
)
rescue StandardError => error
error_record("bridge", "bridge-error", error)
end
# RbValue#toJS delegates Hash/Array conversion to the ruby.wasm `js` gem,
# whose generic conversion path constructs objects through JS.eval. The
# Toolbox CSP deliberately disallows that capability. Return one inert,
# metadata-only JSON string, assembled incrementally without per-value
# arrays or the potentially 6x JSON escaping amplification of output text.
def encode_json(value)
output = String.new(capacity: 4 * 1024)
output.force_encoding(Encoding::UTF_8)
append_json(output, value)
if output.bytesize > MAXIMUM_RESPONSE_BYTES
raise RangeError, "Ruby bridge metadata exceeds its response limit."
end
output
end
def append_json(output, value)
case value
when Hash
output << "{"
first = true
value.each do |key, item|
output << "," unless first
first = false
append_json_string(output, key.to_s)
output << ":"
append_json(output, item)
end
output << "}"
when Array
output << "["
value.each_with_index do |item, index|
output << "," unless index.zero?
append_json(output, item)
end
output << "]"
when String
append_json_string(output, value)
when Integer
output << value.to_s
when true
output << "true"
when false
output << "false"
when nil
output << "null"
else
append_json_string(output, value.to_s)
end
if output.bytesize > MAXIMUM_RESPONSE_BYTES
raise RangeError, "Ruby bridge metadata exceeds its response limit."
end
end
def append_json_string(output, value)
text = value.valid_encoding? \
? value \
: value.encode(
Encoding::UTF_8,
invalid: :replace,
undef: :replace,
replace: "\uFFFD"
)
output << "\""
text.each_codepoint do |codepoint|
case codepoint
when 0x08 then output << "\\b"
when 0x09 then output << "\\t"
when 0x0A then output << "\\n"
when 0x0C then output << "\\f"
when 0x0D then output << "\\r"
when 0x22 then output << "\\\""
when 0x5C then output << "\\\\"
when 0x00..0x1F
output << "\\u00"
output << HEX_DIGITS.getbyte(codepoint >> 4)
output << HEX_DIGITS.getbyte(codepoint & 0x0F)
else
output << codepoint
end
end
output << "\""
end
def identity
verify_replacement_parity
{
"abi" => ABI_VERSION,
"ok" => true,
"identity" => {
"implementation" => RUBY_ENGINE,
"rubyVersion" => RUBY_VERSION,
"platform" => RUBY_PLATFORM,
"defaultExternalEncoding" => Encoding.default_external.name
}
}
end
def compile(pattern, flags)
options = 0
options |= Regexp::IGNORECASE if flags.include?("i")
options |= Regexp::MULTILINE if flags.include?("m")
options |= Regexp::EXTENDED if flags.include?("x")
Regexp.new(pattern, options)
rescue RegexpError => error
error_record("compile", "compile-error", error)
rescue StandardError => error
error_record("compile", "compile-error", error)
end
def capture_group_count(regexp)
# Alternating with an empty non-capturing branch makes a match available
# without changing the original capture numbering.
Regexp.union(regexp, /(?:)/).match("").length - 1
end
def capture_group_names(regexp)
regexp.named_captures.flat_map do |name, numbers|
numbers.map { |number| [number, name] }
end.sort_by { |number, name| [number, name] }
end
def match_record(match, group_count)
captures = (1..group_count).map do |group_number|
start_offset = match.begin(group_number)
start_offset.nil? \
? nil \
: [start_offset, match.end(group_number)]
end
{
"span" => [match.begin(0), match.end(0)],
"captures" => captures
}
end
def collect_matches(
regexp,
subject,
global,
group_count,
maximum_matches,
maximum_capture_rows,
replacement = nil,
maximum_output_bytes = 1
)
records = []
capture_rows = 0
results_truncated = false
output = replacement.nil? \
? nil \
: BoundedUtf8Output.new(maximum_output_bytes)
last_replacement_end = 0
callback = proc do
match = Regexp.last_match
rows_for_match = [1, group_count].max
if records.length >= maximum_matches ||
capture_rows + rows_for_match > maximum_capture_rows
results_truncated = true
throw REPLACEMENT_STOP
end
records << match_record(match, group_count)
capture_rows += rows_for_match
unless output.nil? || output.truncated?
match_start = match.bytebegin(0)
output.append(
subject,
last_replacement_end,
match_start - last_replacement_end
)
unless output.truncated?
begin
append_replacement(
output,
replacement,
subject,
match,
regexp.names.empty?
)
rescue StandardError => error
raise ReplacementFailure, error
end
end
end
last_replacement_end = match.byteend(0)
""
end
catch(REPLACEMENT_STOP) do
global ? subject.gsub(regexp, &callback) : subject.sub(regexp, &callback)
end
unless output.nil? || output.truncated?
output.append(
subject,
last_replacement_end,
subject.bytesize - last_replacement_end
)
end
result = {
"matches" => records,
"resultsTruncated" => results_truncated
}
unless output.nil?
result["output"] = output.value
result["outputBytes"] = output.bytes
result["outputTruncated"] = output.truncated?
end
result
end
# Mirrors CRuby 4.0.0 rb_reg_regsub: \1..\9, \k<name>, \0, \&, \`,
# \', \+, \\ and literal preservation for every other escaped character.
# Match selection and byte offsets remain native MatchData results.
def append_replacement(
output,
replacement,
subject,
match,
numeric_backrefs_active
)
bytes = replacement.b
cursor = 0
while cursor < bytes.bytesize && !output.truncated?
slash = bytes.index("\\", cursor)
if slash.nil?
output.append(replacement, cursor, bytes.bytesize - cursor)
break
end
output.append(replacement, cursor, slash - cursor) if slash > cursor
break if output.truncated?
if slash + 1 >= bytes.bytesize
output.append(replacement, slash, 1)
break
end
marker = bytes.getbyte(slash + 1)
cursor = slash + 2
case marker
when 0x31..0x39
append_capture(
output,
subject,
match,
marker - 0x30
) if numeric_backrefs_active
when 0x6B # k
if cursor < bytes.bytesize && bytes.getbyte(cursor) == 0x3C # <
name_start = cursor + 1
name_end = bytes.index(">", name_start)
if name_end.nil?
raise RuntimeError, "invalid group name reference format"
end
name = replacement.byteslice(name_start, name_end - name_start)
append_capture(output, subject, match, name)
cursor = name_end + 1
else
output.append(replacement, slash, 2)
end
when 0x30, 0x26 # 0, &
append_capture(output, subject, match, 0)
when 0x60 # `
output.append(subject, 0, match.bytebegin(0))
when 0x27 # '
match_end = match.byteend(0)
output.append(subject, match_end, subject.bytesize - match_end)
when 0x2B # +
group_number = match.length - 1
group_number -= 1 while group_number > 0 && match.bytebegin(group_number).nil?
append_capture(output, subject, match, group_number) if group_number > 0
when 0x5C # \
output.append(replacement, slash + 1, 1)
else
if marker >= 0x80
cursor += 1 while cursor < bytes.bytesize &&
(bytes.getbyte(cursor) & 0xC0) == 0x80
end
output.append(replacement, slash, cursor - slash)
end
end
end
def append_capture(output, subject, match, group)
if group.is_a?(Integer) && group >= match.length
return
end
byte_start, byte_end = match.byteoffset(group)
return if byte_start.nil?
output.append(subject, byte_start, byte_end - byte_start)
end
def verify_replacement_parity
return if @replacement_parity_verified
slash = 92.chr
fixtures = [
[
/(a)(b)?/,
"ab a",
[
"<",
"#{slash}0",
"|#{slash}&",
"|#{slash}1",
"|#{slash}2",
"|#{slash}9",
"|#{slash}+",
"|#{slash}#{slash}",
"|#{slash}q",
"|#{slash}`",
"|#{slash}'",
">"
].join,
true
],
[
/(?<left>a)(?<right>b)?/,
"ab a",
"<#{slash}k<left>|#{slash}k<right>|#{slash}1>",
true
],
[/(é)/, "xéy", "#{slash}é/#{slash}1", false]
]
fixtures.each do |regexp, subject, replacement, global|
native = global \
? subject.gsub(regexp, replacement) \
: subject.sub(regexp, replacement)
bounded = collect_matches(
regexp,
subject,
global,
capture_group_count(regexp),
MAXIMUM_MATCHES,
MAXIMUM_CAPTURE_ROWS,
replacement,
1024 * 1024
)
unless !bounded["resultsTruncated"] &&
!bounded["outputTruncated"] &&
bounded["output"] == native
raise "Bounded Ruby replacement semantics failed the CRuby parity test."
end
end
@replacement_parity_verified = true
end
def error_record(phase, code, error)
message = error.is_a?(Exception) ? error.message : error.to_s
if message.length > MAXIMUM_ERROR_CHARACTERS
message = "#{message[0, MAXIMUM_ERROR_CHARACTERS - 1]}"
end
{
"abi" => ABI_VERSION,
"ok" => false,
"phase" => phase,
"code" => code,
"message" => message
}
end
end
end
RegexToolsRubyBridge

216
engines/rust/Cargo.lock generated Normal file
View File

@@ -0,0 +1,216 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "bumpalo"
version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
[[package]]
name = "regex-tools-rust-engine"
version = "0.1.0"
dependencies = [
"regex",
"serde",
"serde_json",
"wasm-bindgen",
]
[[package]]
name = "rustversion"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasm-bindgen"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
dependencies = [
"unicode-ident",
]
[[package]]
name = "zmij"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"

23
engines/rust/Cargo.toml Normal file
View File

@@ -0,0 +1,23 @@
[package]
name = "regex-tools-rust-engine"
version = "0.1.0"
edition = "2024"
rust-version = "1.97.1"
license = "GPL-3.0-or-later"
publish = false
[lib]
crate-type = ["cdylib"]
[dependencies]
regex = "=1.13.1"
serde = { version = "=1.0.228", features = ["derive"] }
serde_json = "=1.0.150"
wasm-bindgen = "=0.2.126"
[profile.release]
codegen-units = 1
lto = true
opt-level = "z"
panic = "abort"
strip = "symbols"

25
engines/rust/README.md Normal file
View File

@@ -0,0 +1,25 @@
# Rust regex WebAssembly engine
This directory builds the actual Rust `regex` crate 1.13.1 for
`wasm32-unknown-unknown` with Rust 1.97.1 and wasm-bindgen 0.2.126.
The fixed bridge accepts JSON values only. The adapter measures the exact
encoded request size, and the native cap includes JSON's worst-case sixfold
escaping for every accepted string field. It exposes native UTF-8 byte offsets,
capture names, iteration, and `Captures::expand` replacement syntax. It does
not evaluate user values as Rust or JavaScript source.
Replacement uses a bounded streaming implementation of
`Captures::expand` grammar. Load-time differential fixtures compare it with
the native API, and capture references stop expanding as soon as the UTF-8
output cap is reached.
The bounded bytes cross the JSON bridge as base64, so control-heavy output has
a fixed 4:3 transport expansion instead of JSON's content-dependent escaping.
Flags `i`, `m`, `s`, `U`, `x`, and `R` map directly to `RegexBuilder`.
Unicode is the crate's native default; the accepted `u` flag explicitly
affirms that default. `g` selects the crate's native iterator.
The crate deliberately excludes look-around and backreferences. Compile-size,
DFA-cache, pattern, subject, match, capture-row, and output limits are enforced
inside the module. Replacement output is clipped only at a UTF-8 boundary.

View File

@@ -0,0 +1,4 @@
[toolchain]
channel = "1.97.1"
profile = "minimal"
targets = ["wasm32-unknown-unknown"]

574
engines/rust/src/lib.rs Normal file
View File

@@ -0,0 +1,574 @@
//! Fixed, bounded WebAssembly bridge for Rust's `regex` crate 1.13.1.
//!
//! User-controlled pattern, subject and replacement values enter through
//! deserialized JSON. They are never interpreted as Rust or JavaScript source.
#![forbid(unsafe_code)]
use regex::{Captures, Regex, RegexBuilder};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::collections::{BTreeMap, BTreeSet};
use wasm_bindgen::prelude::*;
const BRIDGE_ABI_VERSION: u32 = 1;
const REGEX_CRATE_VERSION: &str = "1.13.1";
const RUSTC_VERSION: &str = env!("REGEX_TOOLS_RUSTC_VERSION");
const EXPECTED_RUSTC_VERSION: &str = "rustc 1.97.1 (8bab26f4f 2026-07-14)";
const MAXIMUM_PATTERN_BYTES: usize = 256 * 1024;
const MAXIMUM_SUBJECT_BYTES: usize = 16 * 1024 * 1024;
const MAXIMUM_REPLACEMENT_BYTES: usize = 256 * 1024;
const MAXIMUM_MATCHES: usize = 10_000;
const MAXIMUM_CAPTURE_ROWS: usize = 100_000;
const MAXIMUM_CAPTURE_GROUPS: usize = 1_000;
const MAXIMUM_OUTPUT_BYTES: usize = 64 * 1024 * 1024;
const MAXIMUM_REQUEST_JSON_BYTES: usize =
6 * (MAXIMUM_SUBJECT_BYTES + MAXIMUM_PATTERN_BYTES + MAXIMUM_REPLACEMENT_BYTES)
+ 64 * 1024;
const MAXIMUM_ERROR_MESSAGE_BYTES: usize = 1_024;
const COMPILED_SIZE_LIMIT_BYTES: usize = 10 * 1024 * 1024;
const DFA_SIZE_LIMIT_BYTES: usize = 2 * 1024 * 1024;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct BridgeRequest {
abi: u32,
operation: String,
pattern: String,
flags: String,
options: BTreeMap<String, Value>,
subject: String,
scan_all: bool,
maximum_matches: usize,
maximum_capture_rows: usize,
replacement: Option<String>,
maximum_output_bytes: Option<usize>,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct BridgeFailure {
abi: u32,
ok: bool,
phase: &'static str,
code: &'static str,
message: String,
}
#[derive(Serialize)]
struct NativeMatch {
span: [usize; 2],
captures: Vec<Option<[usize; 2]>>,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct BridgeSuccess {
abi: u32,
ok: bool,
group_count: usize,
group_names: Vec<(usize, String)>,
matches: Vec<NativeMatch>,
results_truncated: bool,
#[serde(skip_serializing_if = "Option::is_none")]
output_base64: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
output_bytes: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
output_truncated: Option<bool>,
}
fn bounded_message(value: impl std::fmt::Display) -> String {
let value = value.to_string();
if value.len() <= MAXIMUM_ERROR_MESSAGE_BYTES {
return value;
}
let mut end = MAXIMUM_ERROR_MESSAGE_BYTES - "".len();
while !value.is_char_boundary(end) {
end -= 1;
}
format!("{}", &value[..end])
}
fn serialize<T: Serialize>(value: &T) -> String {
match serde_json::to_string(value) {
Ok(encoded) => encoded,
Err(_) => {
"{\"abi\":1,\"ok\":false,\"phase\":\"bridge\",\"code\":\"serialization-error\",\"message\":\"The Rust bridge could not serialize its bounded result.\"}".to_owned()
}
}
}
fn failure(phase: &'static str, code: &'static str, message: impl std::fmt::Display) -> String {
serialize(&BridgeFailure {
abi: BRIDGE_ABI_VERSION,
ok: false,
phase,
code,
message: bounded_message(message),
})
}
fn validate_request(request: &BridgeRequest) -> Result<(), String> {
if request.abi != BRIDGE_ABI_VERSION {
return Err(failure(
"bridge",
"abi-mismatch",
"The bridge ABI version is unsupported.",
));
}
if request.operation != "execute" && request.operation != "replace" {
return Err(failure(
"bridge",
"invalid-operation",
"The bridge operation is unsupported.",
));
}
if !request.options.is_empty() {
return Err(failure(
"bridge",
"unsupported-option",
"Rust regex does not accept engine options.",
));
}
if request.pattern.len() > MAXIMUM_PATTERN_BYTES {
return Err(failure(
"bridge",
"pattern-limit",
"The pattern exceeds the bridge limit.",
));
}
if request.subject.len() > MAXIMUM_SUBJECT_BYTES {
return Err(failure(
"bridge",
"subject-limit",
"The subject exceeds the bridge limit.",
));
}
if request.maximum_matches == 0
|| request.maximum_matches > MAXIMUM_MATCHES
|| request.maximum_capture_rows == 0
|| request.maximum_capture_rows > MAXIMUM_CAPTURE_ROWS
{
return Err(failure(
"bridge",
"result-limit",
"The requested result bounds are outside the bridge contract.",
));
}
let mut seen = BTreeSet::new();
for flag in request.flags.chars() {
if !"gimsUuxR".contains(flag) || !seen.insert(flag) {
return Err(failure(
"bridge",
"unsupported-flag",
"The request contains an unsupported or duplicate Rust flag.",
));
}
}
if request.operation == "execute" {
if request.replacement.is_some() || request.maximum_output_bytes.is_some() {
return Err(failure(
"bridge",
"invalid-request",
"Execution requests cannot contain replacement fields.",
));
}
return Ok(());
}
let Some(replacement) = &request.replacement else {
return Err(failure(
"bridge",
"invalid-request",
"Replacement requests require a template.",
));
};
let Some(output_limit) = request.maximum_output_bytes else {
return Err(failure(
"bridge",
"invalid-request",
"Replacement requests require an output bound.",
));
};
if replacement.len() > MAXIMUM_REPLACEMENT_BYTES {
return Err(failure(
"bridge",
"replacement-limit",
"The replacement exceeds the bridge limit.",
));
}
if output_limit == 0 || output_limit > MAXIMUM_OUTPUT_BYTES {
return Err(failure(
"bridge",
"output-limit",
"The output bound is outside the bridge contract.",
));
}
Ok(())
}
fn compile(request: &BridgeRequest) -> Result<Regex, String> {
let has = |flag| request.flags.contains(flag);
let mut builder = RegexBuilder::new(&request.pattern);
builder
.case_insensitive(has('i'))
.multi_line(has('m'))
.dot_matches_new_line(has('s'))
.swap_greed(has('U'))
// Unicode is Rust regex's native default. The accepted `u` flag is an
// explicit affirmation, not a request to disable Unicode when absent.
.unicode(true)
.ignore_whitespace(has('x'))
.crlf(has('R'))
.size_limit(COMPILED_SIZE_LIMIT_BYTES)
.dfa_size_limit(DFA_SIZE_LIMIT_BYTES);
builder
.build()
.map_err(|error| failure("compile", "compile-error", error))
}
fn materialize(captures: &Captures<'_>, group_count: usize) -> NativeMatch {
let whole = captures
.get(0)
.expect("regex captures always contain the complete match");
let groups = (1..=group_count)
.map(|group| {
captures
.get(group)
.map(|capture| [capture.start(), capture.end()])
})
.collect();
NativeMatch {
span: [whole.start(), whole.end()],
captures: groups,
}
}
fn collect_matches(
compiled: &Regex,
request: &BridgeRequest,
group_count: usize,
) -> (Vec<NativeMatch>, bool) {
let rows_per_match = group_count.max(1);
let allowed = request
.maximum_matches
.min(request.maximum_capture_rows / rows_per_match);
let global = request.flags.contains('g');
let mut records = Vec::with_capacity(allowed.min(256));
let mut truncated = false;
if global {
for captures in compiled.captures_iter(&request.subject) {
if records.len() == allowed {
truncated = true;
break;
}
records.push(materialize(&captures, group_count));
}
} else if let Some(captures) = compiled.captures(&request.subject) {
if allowed == 0 {
truncated = true;
} else {
records.push(materialize(&captures, group_count));
}
}
(records, truncated)
}
struct BoundedOutput {
value: String,
maximum: usize,
truncated: bool,
}
impl BoundedOutput {
fn new(maximum: usize) -> Self {
Self {
value: String::with_capacity(maximum.min(64 * 1024)),
maximum,
truncated: false,
}
}
fn append(&mut self, value: &str) {
if self.truncated || value.is_empty() {
return;
}
let remaining = self.maximum - self.value.len();
if value.len() <= remaining {
self.value.push_str(value);
return;
}
let mut end = remaining;
while !value.is_char_boundary(end) {
end -= 1;
}
self.value.push_str(&value[..end]);
self.truncated = true;
}
}
enum ReplacementReference<'a> {
Number(usize),
Named(&'a str),
}
fn capture_reference(replacement: &str) -> Option<(ReplacementReference<'_>, usize)> {
let bytes = replacement.as_bytes();
if bytes.len() <= 1 || bytes[0] != b'$' {
return None;
}
let (name, end) = if bytes[1] == b'{' {
let close = bytes[2..].iter().position(|&byte| byte == b'}')? + 2;
(&replacement[2..close], close + 1)
} else {
let mut end = 1;
while bytes
.get(end)
.is_some_and(|byte| byte.is_ascii_alphanumeric() || *byte == b'_')
{
end += 1;
}
if end == 1 {
return None;
}
(&replacement[1..end], end)
};
let reference = match name.parse::<usize>() {
Ok(number) => ReplacementReference::Number(number),
Err(_) => ReplacementReference::Named(name),
};
Some((reference, end))
}
fn expand_replacement_bounded(
output: &mut BoundedOutput,
captures: &Captures<'_>,
mut replacement: &str,
) {
while !replacement.is_empty() && !output.truncated {
let Some(dollar) = replacement.as_bytes().iter().position(|&byte| byte == b'$') else {
output.append(replacement);
return;
};
output.append(&replacement[..dollar]);
if output.truncated {
return;
}
replacement = &replacement[dollar..];
if replacement.as_bytes().get(1) == Some(&b'$') {
output.append("$");
replacement = &replacement[2..];
continue;
}
let Some((reference, end)) = capture_reference(replacement) else {
output.append("$");
replacement = &replacement[1..];
continue;
};
replacement = &replacement[end..];
let capture = match reference {
ReplacementReference::Number(number) => captures.get(number),
ReplacementReference::Named(name) => captures.name(name),
};
if let Some(capture) = capture {
output.append(capture.as_str());
}
}
}
fn encode_base64(input: &[u8]) -> String {
const ALPHABET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut encoded = String::with_capacity(input.len().div_ceil(3) * 4);
for chunk in input.chunks(3) {
let first = chunk[0];
let second = chunk.get(1).copied().unwrap_or(0);
let third = chunk.get(2).copied().unwrap_or(0);
encoded.push(ALPHABET[usize::from(first >> 2)] as char);
encoded.push(ALPHABET[usize::from(((first & 0x03) << 4) | (second >> 4))] as char);
encoded.push(if chunk.len() > 1 {
ALPHABET[usize::from(((second & 0x0f) << 2) | (third >> 6))] as char
} else {
'='
});
encoded.push(if chunk.len() > 2 {
ALPHABET[usize::from(third & 0x3f)] as char
} else {
'='
});
}
encoded
}
fn replace_bounded(
compiled: &Regex,
request: &BridgeRequest,
accepted_matches: usize,
) -> (String, usize, bool) {
let replacement = request
.replacement
.as_deref()
.expect("validated replacement request");
let output_limit = request
.maximum_output_bytes
.expect("validated replacement request");
let mut output = BoundedOutput::new(output_limit);
let mut cursor = 0;
let global = request.flags.contains('g');
let maximum = if global {
accepted_matches
} else {
accepted_matches.min(1)
};
for captures in compiled.captures_iter(&request.subject).take(maximum) {
let whole = captures
.get(0)
.expect("regex captures always contain the complete match");
output.append(&request.subject[cursor..whole.start()]);
expand_replacement_bounded(&mut output, &captures, replacement);
cursor = whole.end();
}
output.append(&request.subject[cursor..]);
let bytes = output.value.len();
(
encode_base64(output.value.as_bytes()),
bytes,
output.truncated,
)
}
fn execute(encoded: &str) -> String {
if encoded.len() > MAXIMUM_REQUEST_JSON_BYTES {
return failure(
"bridge",
"request-limit",
"The encoded request exceeds the bridge limit.",
);
}
let request: BridgeRequest = match serde_json::from_str(encoded) {
Ok(request) => request,
Err(error) => return failure("bridge", "invalid-request", error),
};
if let Err(error) = validate_request(&request) {
return error;
}
// Reading the field also keeps the transport contract explicit: matching
// is selected by the normalized native `g` flag, while scanAll records the
// application request that caused an internal `g` to be added.
let _scan_all = request.scan_all;
let compiled = match compile(&request) {
Ok(compiled) => compiled,
Err(error) => return error,
};
let group_count = compiled.captures_len() - 1;
if group_count > MAXIMUM_CAPTURE_GROUPS {
return failure(
"compile",
"capture-group-limit",
format!(
"The pattern declares {group_count} capture groups; the bridge limit is {MAXIMUM_CAPTURE_GROUPS}."
),
);
}
let group_names = compiled
.capture_names()
.enumerate()
.filter_map(|(number, name)| name.map(|name| (number, name.to_owned())))
.filter(|(number, _)| *number > 0)
.collect();
let (matches, results_truncated) = collect_matches(&compiled, &request, group_count);
let mut result = BridgeSuccess {
abi: BRIDGE_ABI_VERSION,
ok: true,
group_count,
group_names,
matches,
results_truncated,
output_base64: None,
output_bytes: None,
output_truncated: None,
};
if request.operation == "replace" {
let (output_base64, output_bytes, output_truncated) =
replace_bounded(&compiled, &request, result.matches.len());
result.output_base64 = Some(output_base64);
result.output_bytes = Some(output_bytes);
result.output_truncated = Some(output_truncated);
}
serialize(&result)
}
fn self_test() -> bool {
if RUSTC_VERSION != EXPECTED_RUSTC_VERSION || encode_base64("😀".as_bytes()) != "8J+YgA==" {
return false;
}
let Ok(compiled) = Regex::new(r"(?P<word>😀+)") else {
return false;
};
let Some(captures) = compiled.captures("x😀😀") else {
return false;
};
let Some(whole) = captures.get(0) else {
return false;
};
let Some(word) = captures.name("word") else {
return false;
};
if whole.start() != 1 || whole.end() != 9 || word.start() != 1 || word.end() != 9 {
return false;
}
for template in [
"${word}-$word-$$",
"$1x|${1}x",
"${missing}|$|${word",
"$01|${01}|$123456789012345678901234567890",
"${}|${word}",
] {
let mut native = String::new();
captures.expand(template, &mut native);
let mut bounded = BoundedOutput::new(4 * 1024);
expand_replacement_bounded(&mut bounded, &captures, template);
if bounded.truncated || bounded.value != native {
return false;
}
}
let mut adversarial = BoundedOutput::new(5);
expand_replacement_bounded(&mut adversarial, &captures, &"${word}".repeat(32 * 1024));
adversarial.truncated && adversarial.value == "😀"
}
#[wasm_bindgen]
pub fn identity() -> String {
let mut identity = Map::new();
identity.insert(
"bridge".to_owned(),
Value::String("regex-tools-rust-json".to_owned()),
);
identity.insert("bridgeVersion".to_owned(), Value::from(BRIDGE_ABI_VERSION));
identity.insert(
"engine".to_owned(),
Value::String("Rust regex crate".to_owned()),
);
identity.insert(
"engineVersion".to_owned(),
Value::String(REGEX_CRATE_VERSION.to_owned()),
);
identity.insert(
"offsetUnit".to_owned(),
Value::String("utf8-byte".to_owned()),
);
identity.insert(
"rustcVersion".to_owned(),
Value::String(RUSTC_VERSION.to_owned()),
);
identity.insert("selfTest".to_owned(), Value::Bool(self_test()));
let mut envelope = Map::new();
envelope.insert("abi".to_owned(), Value::from(BRIDGE_ABI_VERSION));
envelope.insert("ok".to_owned(), Value::Bool(true));
envelope.insert("identity".to_owned(), Value::Object(identity));
serialize(&Value::Object(envelope))
}
#[wasm_bindgen]
pub fn run(encoded: &str) -> String {
execute(encoded)
}

207
package-lock.json generated
View File

@@ -1,16 +1,16 @@
{
"name": "regex-tools",
"version": "0.2.0",
"version": "0.4.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "regex-tools",
"version": "0.2.0",
"version": "0.4.2",
"license": "GPL-3.0-or-later",
"dependencies": {
"@add-ideas/toolbox-contract": "0.2.2",
"@add-ideas/toolbox-shell-react": "0.2.2",
"@add-ideas/toolbox-contract": "0.2.3",
"@add-ideas/toolbox-shell-react": "0.2.3",
"@codemirror/commands": "6.10.4",
"@codemirror/language": "6.12.4",
"@codemirror/search": "6.7.1",
@@ -23,9 +23,14 @@
"react-dom": "19.2.7"
},
"devDependencies": {
"@add-ideas/toolbox-testkit": "0.2.2",
"@add-ideas/toolbox-testkit": "0.2.3",
"@bjorn3/browser_wasi_shim": "0.4.2",
"@eslint/js": "10.0.1",
"@php-wasm/universal": "3.1.46",
"@php-wasm/web-8-5": "3.1.46",
"@playwright/test": "1.61.1",
"@ruby/4.0-wasm-wasi": "2.9.3-2.9.4",
"@ruby/wasm-wasi": "2.9.3-2.9.4",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.1",
@@ -39,6 +44,7 @@
"globals": "17.7.0",
"jsdom": "29.1.1",
"prettier": "3.9.5",
"pyodide": "314.0.3",
"typescript": "6.0.3",
"typescript-eslint": "8.64.0",
"vite": "8.1.5",
@@ -49,18 +55,18 @@
}
},
"node_modules/@add-ideas/toolbox-contract": {
"version": "0.2.2",
"resolved": "https://git.add-ideas.de/api/packages/zemion/npm/%40add-ideas%2Ftoolbox-contract/-/0.2.2/toolbox-contract-0.2.2.tgz",
"integrity": "sha512-VcZ8j4O2PgFaIYgxs6r9u0uPxA+hHKwhCW+omfeVCtbjAAYhH2KhRlBGm0ERVVYcK5kchyzZLXrC4LKWRotVzg==",
"version": "0.2.3",
"resolved": "https://git.add-ideas.de/api/packages/lotobo/npm/%40add-ideas%2Ftoolbox-contract/-/0.2.3/toolbox-contract-0.2.3.tgz",
"integrity": "sha512-T0PVSuMT40GjTDfQJhEEY3ZawQq8zz1/ry95JdKI6W39CdLacaRXdGnEpDCMHt+jUbf1Jz7Nat/M5dFCgKVM9A==",
"license": "Apache-2.0"
},
"node_modules/@add-ideas/toolbox-shell-react": {
"version": "0.2.2",
"resolved": "https://git.add-ideas.de/api/packages/zemion/npm/%40add-ideas%2Ftoolbox-shell-react/-/0.2.2/toolbox-shell-react-0.2.2.tgz",
"integrity": "sha512-w/xbLCd50a2Jq7vQ9Z9ygUOuqlOCRkIYlk4vSJx0mf4REJNeMYi3PE2MbaLUC4DkQWyrmatsa5HNT89o0l91BA==",
"version": "0.2.3",
"resolved": "https://git.add-ideas.de/api/packages/lotobo/npm/%40add-ideas%2Ftoolbox-shell-react/-/0.2.3/toolbox-shell-react-0.2.3.tgz",
"integrity": "sha512-DT5lQDH48BFkFcmFLZnQh7+Cm73JzBPcmp5WzUXypfkUXpEyDYHzaXgmW4kZ0edSwh4RK4sPmx+JPtK0X4aKCQ==",
"license": "Apache-2.0",
"dependencies": {
"@add-ideas/toolbox-contract": "0.2.2"
"@add-ideas/toolbox-contract": "0.2.3"
},
"peerDependencies": {
"react": ">=18 <20",
@@ -68,13 +74,13 @@
}
},
"node_modules/@add-ideas/toolbox-testkit": {
"version": "0.2.2",
"resolved": "https://git.add-ideas.de/api/packages/zemion/npm/%40add-ideas%2Ftoolbox-testkit/-/0.2.2/toolbox-testkit-0.2.2.tgz",
"integrity": "sha512-ZxrRYiJI/j5aXwcd3mQItgDl1iOJ6N26+MpIG18qVZNwKKFCTCfSTzgzRooPt8rRc1MQYTPo4c+l/QpOWuTXxA==",
"version": "0.2.3",
"resolved": "https://git.add-ideas.de/api/packages/lotobo/npm/%40add-ideas%2Ftoolbox-testkit/-/0.2.3/toolbox-testkit-0.2.3.tgz",
"integrity": "sha512-sq1MwhKWfFKen+N+124hl74qQimRSvmQ9sOU7jdcI+2qCKZ67+2B8rWyezeV80uTFu4Jv6deHksfYQ/tKNV6XQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@add-ideas/toolbox-contract": "0.2.2"
"@add-ideas/toolbox-contract": "0.2.3"
},
"bin": {
"toolbox-check": "dist/cli.js"
@@ -388,6 +394,13 @@
"node": ">=6.9.0"
}
},
"node_modules/@bjorn3/browser_wasi_shim": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@bjorn3/browser_wasi_shim/-/browser_wasi_shim-0.4.2.tgz",
"integrity": "sha512-/iHkCVUG3VbcbmEHn5iIUpIrh7a7WPiwZ3sHy4HZKZzBdSadwdddYDZAII2zBvQYV0Lfi8naZngPCN7WPHI/hA==",
"dev": true,
"license": "MIT OR Apache-2.0"
},
"node_modules/@bramus/specificity": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz",
@@ -953,6 +966,84 @@
"url": "https://github.com/sponsors/Boshen"
}
},
"node_modules/@php-wasm/logger": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/@php-wasm/logger/-/logger-3.1.46.tgz",
"integrity": "sha512-PfnDq5ammh5FXxkGX1TGEck9gmW3i76IvBCqtX4D45xnSBIuCeu8uf2oWuty2j/c8wTEO8vyRDdvCj5oow7bXw==",
"dev": true,
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=20.10.0",
"npm": ">=10.2.3"
}
},
"node_modules/@php-wasm/progress": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/@php-wasm/progress/-/progress-3.1.46.tgz",
"integrity": "sha512-WmmgEm6yz322M3pzgAUjxckyhpVxr2WWlHyVYDyaMZWU6UIDUHfiRZRPzADohNyYvV3g0/zMNaDGmxz+TTXwQQ==",
"dev": true,
"license": "GPL-2.0-or-later",
"dependencies": {
"@php-wasm/logger": "3.1.46"
},
"engines": {
"node": ">=20.10.0",
"npm": ">=10.2.3"
}
},
"node_modules/@php-wasm/stream-compression": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/@php-wasm/stream-compression/-/stream-compression-3.1.46.tgz",
"integrity": "sha512-+oUw4CPX52FgYXEh5C+MgJAg7Cy5OeaVuh7HnQR6oxb69nU63/r8tHTLV/WrWRyjBYh321uJzLV7Gg29qmiUtg==",
"dev": true,
"license": "GPL-2.0-or-later",
"dependencies": {
"@php-wasm/util": "3.1.46"
}
},
"node_modules/@php-wasm/universal": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/@php-wasm/universal/-/universal-3.1.46.tgz",
"integrity": "sha512-sx0KyN5kcsCMzwy+XJAyoOukSA5TEZYd0LK3l9kRP3I0CSd5h6JItkf5eZ42WltB+wD+aTRdqSwc/Mvkc7qBjQ==",
"dev": true,
"license": "GPL-2.0-or-later",
"dependencies": {
"@php-wasm/logger": "3.1.46",
"@php-wasm/progress": "3.1.46",
"@php-wasm/stream-compression": "3.1.46",
"@php-wasm/util": "3.1.46",
"ini": "4.1.2"
},
"engines": {
"node": ">=20.10.0",
"npm": ">=10.2.3"
}
},
"node_modules/@php-wasm/util": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/@php-wasm/util/-/util-3.1.46.tgz",
"integrity": "sha512-Yh9HNbx+rB2R1tScUvvAsbJVIB7msjWceWYogyR2YvAOqlDL0ymZyaQ65+K3QcHh/8HostTRwwgQh5oK4DLDrA==",
"dev": true,
"engines": {
"node": ">=20.10.0",
"npm": ">=10.2.3"
}
},
"node_modules/@php-wasm/web-8-5": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/@php-wasm/web-8-5/-/web-8-5-3.1.46.tgz",
"integrity": "sha512-j9wwlY6aNXuKBr4JPJzqE+vkM3Onk+byJsxLqaJs4U0gYDUBLr8CuKuVr+p13apSTUosConePYTAs0214aNxYA==",
"dev": true,
"license": "GPL-2.0-or-later",
"dependencies": {
"@php-wasm/universal": "3.1.46",
"wasm-feature-detect": "1.8.0"
},
"engines": {
"node": ">=20.10.0",
"npm": ">=10.2.3"
}
},
"node_modules/@playwright/test": {
"version": "1.61.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.1.tgz",
@@ -1251,6 +1342,27 @@
"dev": true,
"license": "MIT"
},
"node_modules/@ruby/4.0-wasm-wasi": {
"version": "2.9.3-2.9.4",
"resolved": "https://registry.npmjs.org/@ruby/4.0-wasm-wasi/-/4.0-wasm-wasi-2.9.3-2.9.4.tgz",
"integrity": "sha512-USLEWmCjM/DIota/9c7Mwzzl3v8mvmg4x24m+zMq8+vLx5+AdOS6dyXvsL/B8+XjQn5UgYhh3c8ekaUdWFkUMA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ruby/wasm-wasi": "2.9.3-2.9.4"
}
},
"node_modules/@ruby/wasm-wasi": {
"version": "2.9.3-2.9.4",
"resolved": "https://registry.npmjs.org/@ruby/wasm-wasi/-/wasm-wasi-2.9.3-2.9.4.tgz",
"integrity": "sha512-WxW9wON/TIf+8Ktng8qDJeV/6iH8kw+YwxOsOyXdAdLJgfYDPAXOqpIVd/96y2C9V8VJ2yqZm/IRv6nLeV6EKg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@bjorn3/browser_wasi_shim": "^0.4.2",
"tslib": "^2.8.1"
}
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
@@ -1385,6 +1497,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/emscripten": {
"version": "1.41.5",
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz",
"integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/esrecurse": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz",
@@ -2606,6 +2725,16 @@
"node": ">=8"
}
},
"node_modules/ini": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/ini/-/ini-4.1.2.tgz",
"integrity": "sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -3405,6 +3534,20 @@
"node": ">=6"
}
},
"node_modules/pyodide": {
"version": "314.0.3",
"resolved": "https://registry.npmjs.org/pyodide/-/pyodide-314.0.3.tgz",
"integrity": "sha512-sK40My6m8tmBUYtYH9au9rXUeh9x0wfahtHdOlGmJxZDsKBGKtP6KznyFB2+u/klbQTdDionR0uaVd176zVQzQ==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
"@types/emscripten": "^1.41.4",
"ws": "^8.5.0"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/react": {
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
@@ -3709,8 +3852,7 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"optional": true
"license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -4023,6 +4165,13 @@
"node": ">=18"
}
},
"node_modules/wasm-feature-detect": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz",
"integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/webidl-conversions": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
@@ -4101,6 +4250,28 @@
"node": ">=0.10.0"
}
},
"node_modules/ws": {
"version": "8.21.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
"integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xml-name-validator": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",

View File

@@ -1,16 +1,16 @@
{
"name": "regex-tools",
"version": "0.2.0",
"version": "0.4.2",
"description": "Develop, explain, test and apply regular expressions locally in the browser.",
"license": "GPL-3.0-or-later",
"author": "Albrecht Degering",
"repository": {
"type": "git",
"url": "git+https://git.add-ideas.de/zemion/regex-tools.git"
"url": "git+https://git.add-ideas.de/lotobo/regex-tools.git"
},
"homepage": "https://git.add-ideas.de/zemion/regex-tools",
"homepage": "https://git.add-ideas.de/lotobo/regex-tools",
"bugs": {
"url": "https://git.add-ideas.de/zemion/regex-tools/issues"
"url": "https://git.add-ideas.de/lotobo/regex-tools/issues"
},
"private": true,
"type": "module",
@@ -35,6 +35,33 @@
"engines:pcre2:build": "node scripts/build-engines.mjs --pcre2",
"engines:pcre2:install": "node scripts/install-pcre2-engine.mjs",
"engines:pcre2:verify": "node scripts/verify-engine-assets.mjs --pcre2-pack .engine-build/pcre2",
"engines:cpp:build": "node scripts/cpp-engine-pack.mjs",
"engines:cpp:install": "node scripts/install-cpp-engine.mjs",
"engines:cpp:verify": "node scripts/verify-engine-assets.mjs --cpp-pack public/engines/cpp",
"engines:dotnet:build": "node scripts/dotnet-engine-pack.mjs",
"engines:dotnet:install": "node scripts/install-dotnet-engine.mjs",
"engines:dotnet:verify": "node scripts/verify-engine-assets.mjs --dotnet-pack public/engines/dotnet",
"engines:go:build": "node scripts/build-go-engine.mjs",
"engines:go:install": "node scripts/install-go-engine.mjs",
"engines:go:verify": "node scripts/verify-engine-assets.mjs --go-pack public/engines/go",
"engines:python:build": "node scripts/python-engine-pack.mjs",
"engines:python:install": "node scripts/install-python-engine.mjs",
"engines:python:verify": "node scripts/verify-engine-assets.mjs --python-pack public/engines/python",
"engines:java:build": "node scripts/java-engine-pack.mjs",
"engines:java:install": "node scripts/install-java-engine.mjs",
"engines:java:verify": "node scripts/verify-engine-assets.mjs --java-pack public/engines/java",
"engines:perl:build": "node scripts/perl-engine-pack.mjs",
"engines:perl:install": "node scripts/install-perl-engine.mjs",
"engines:perl:verify": "node scripts/verify-engine-assets.mjs --perl-pack public/engines/perl",
"engines:php:build": "node scripts/php-engine-pack.mjs",
"engines:php:install": "node scripts/install-php-engine.mjs",
"engines:php:verify": "node scripts/verify-engine-assets.mjs --php-pack public/engines/php",
"engines:ruby:build": "node scripts/ruby-engine-pack.mjs",
"engines:ruby:install": "node scripts/install-ruby-engine.mjs",
"engines:ruby:verify": "node scripts/verify-engine-assets.mjs --ruby-pack public/engines/ruby",
"engines:rust:build": "node scripts/build-rust-engine.mjs",
"engines:rust:install": "node scripts/install-rust-engine.mjs",
"engines:rust:verify": "node scripts/verify-engine-assets.mjs --rust-pack public/engines/rust",
"engines:verify": "node scripts/verify-engine-assets.mjs",
"manifest:generate": "node scripts/generate-toolbox-manifest.mjs",
"manifest:check": "node scripts/generate-toolbox-manifest.mjs --check",
@@ -45,8 +72,8 @@
"release:artifact": "npm run check && npm run test:browser && npm run package:release"
},
"dependencies": {
"@add-ideas/toolbox-contract": "0.2.2",
"@add-ideas/toolbox-shell-react": "0.2.2",
"@add-ideas/toolbox-contract": "0.2.3",
"@add-ideas/toolbox-shell-react": "0.2.3",
"@codemirror/commands": "6.10.4",
"@codemirror/language": "6.12.4",
"@codemirror/search": "6.7.1",
@@ -59,9 +86,14 @@
"react-dom": "19.2.7"
},
"devDependencies": {
"@add-ideas/toolbox-testkit": "0.2.2",
"@add-ideas/toolbox-testkit": "0.2.3",
"@bjorn3/browser_wasi_shim": "0.4.2",
"@eslint/js": "10.0.1",
"@php-wasm/universal": "3.1.46",
"@php-wasm/web-8-5": "3.1.46",
"@playwright/test": "1.61.1",
"@ruby/4.0-wasm-wasi": "2.9.3-2.9.4",
"@ruby/wasm-wasi": "2.9.3-2.9.4",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.1",
@@ -75,6 +107,7 @@
"globals": "17.7.0",
"jsdom": "29.1.1",
"prettier": "3.9.5",
"pyodide": "314.0.3",
"typescript": "6.0.3",
"typescript-eslint": "8.64.0",
"vite": "8.1.5",

View File

@@ -3,6 +3,7 @@ import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests/browser",
fullyParallel: false,
workers: 4,
timeout: 120_000,
expect: { timeout: 10_000 },
reporter: [["list"]],

View File

@@ -1,9 +1,42 @@
# Engine assets
Regex Tools executes ECMAScript through the browser's native `RegExp` engine.
It also ships the declared, self-hosted PCRE2 10.47 WebAssembly pack in
`pcre2/`.
It also ships ten declared, self-hosted runtime packs:
The PCRE2 pack is built from pinned, documented open-source code and
toolchain revisions. `engine-metadata.json`, `SHA256SUMS` and `LICENSE.txt`
travel with the runtime files and are verified by the release gate.
- `pcre2/`: official standalone PCRE2 10.47, 8-bit WebAssembly;
- `php/`: PHP 8.5.8 `preg_*` through `@php-wasm/web-8-5` 3.1.46; this runtime
reports PCRE2 10.44;
- `perl/`: Perl 5.28.1 through the legacy WebPerl 0.09-beta prebuilt runtime;
- `python/`: Pyodide 314.0.3 with CPython 3.14.2 `re`, a complete linked
base-runtime inventory (including vendored loader ports),
preferred-form/patch manifest and independently pinned legal closure;
- `ruby/`: minimal ruby.wasm 2.9.3-2.9.4 with CRuby 4.0.0 `Regexp`;
- `java/`: TeaVM 0.15.0's `java.util.regex` class library compiled to an
ES2015 module; this module is not OpenJDK;
- `cpp/`: Emscripten 6.0.4 libc++ `std::wregex`, with an exact traced native
component/source/legal manifest;
- `go/`: Go 1.26.5 standard-library `regexp` for `js/wasm`;
- `rust/`: Rust `regex` crate 1.13.1 for `wasm32-unknown-unknown`; and
- `dotnet/`: .NET 10.0.10 `System.Text.RegularExpressions` for browser
WebAssembly.
The selectable Scala/JVM compatibility profile intentionally shares
`java/`. It does not contain or claim a Scala runtime.
The packs come from pinned, documented open-source inputs. Runtime files travel
with deterministic metadata, closed-set checksums and the applicable upstream
licence/notice material, all of which are verified by the release gate.
The Python pack's `SOURCE-MANIFEST.json` records exact source archives or Git
trees, both vendored stack-parser source ports, all Pyodide
CPython/Emscripten patches and the evidence for every component already linked
into its loader or base WebAssembly module. The C++ source manifest similarly
binds its exact module to the traced Emscripten runtime, musl, emmalloc,
compiler-rt, libc++ and libc++abi inputs and the explicit non-selection of
libunwind. The
hundreds of optional entries in `pyodide-lock.json` are a package catalogue;
their wheels are not part of this pack.
The Perl pack remains an explicit exception in age, not in identity: its
upstream beta assets are retained byte-for-byte and labelled legacy everywhere.
Its loader contains a dormant optional JavaScript-interoperability `eval` site;
the fixed bridge does not import or call it.

View File

@@ -0,0 +1,102 @@
Emscripten is available under 2 licenses, the MIT license and the
University of Illinois/NCSA Open Source License.
Both are permissive open source licenses, with little if any
practical difference between them.
The reason for offering both is that (1) the MIT license is
well-known, while (2) the University of Illinois/NCSA Open Source
License allows Emscripten's code to be integrated upstream into
LLVM, which uses that license, should the opportunity arise.
The full text of both licenses follows.
==============================================================================
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal with the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimers.
Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimers
in the documentation and/or other materials provided with the
distribution.
Neither the names of Mozilla,
nor the names of its contributors may be used to endorse
or promote products derived from this Software without specific prior
written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
==============================================================================
This program uses portions of Node.js source code located in src/library_path.js,
in accordance with the terms of the MIT license. Node's license follows:
"""
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
"""
The musl libc project is bundled in this repo, and it has the MIT license, see
system/lib/libc/musl/COPYRIGHT
The third_party/ subdirectory contains code with other licenses. None of it is
used by default, but certain options use it (e.g., the optional closure compiler
flag will run closure compiler from third_party/).

Some files were not shown because too many files have changed in this diff Show More