237 lines
7.2 KiB
C
237 lines
7.2 KiB
C
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
|
|
|
#ifndef REGEX_TOOLS_PCRE2_BRIDGE_H
|
|
#define REGEX_TOOLS_PCRE2_BRIDGE_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#define REGEX_PCRE2_BRIDGE_ABI_VERSION 3u
|
|
#define REGEX_PCRE2_MAX_PATTERN_BYTES 1048576u
|
|
#define REGEX_PCRE2_MAX_SUBJECT_BYTES 16777216u
|
|
#define REGEX_PCRE2_MAX_REPLACEMENT_BYTES 262144u
|
|
#define REGEX_PCRE2_MAX_MATCHES 10000u
|
|
#define REGEX_PCRE2_MAX_CAPTURE_ROWS 100000u
|
|
#define REGEX_PCRE2_MAX_CAPTURE_GROUPS 1000u
|
|
#define REGEX_PCRE2_MAX_MATCH_LIMIT 100000000u
|
|
#define REGEX_PCRE2_MAX_DEPTH_LIMIT 100000u
|
|
#define REGEX_PCRE2_MAX_HEAP_LIMIT_KIB 131072u
|
|
#define REGEX_PCRE2_MAX_TRACE_EVENTS 50000u
|
|
#define REGEX_PCRE2_MAX_TRACE_BYTES 10485760u
|
|
#define REGEX_PCRE2_MAX_TRACE_MARK_BYTES 1024u
|
|
#define REGEX_PCRE2_UNSET_OFFSET UINT32_MAX
|
|
|
|
enum regex_pcre2_flag {
|
|
REGEX_PCRE2_CASELESS = 1u << 0,
|
|
REGEX_PCRE2_MULTILINE = 1u << 1,
|
|
REGEX_PCRE2_DOTALL = 1u << 2,
|
|
REGEX_PCRE2_EXTENDED = 1u << 3,
|
|
REGEX_PCRE2_UNGREEDY = 1u << 4,
|
|
REGEX_PCRE2_UTF = 1u << 5,
|
|
REGEX_PCRE2_UCP = 1u << 6,
|
|
REGEX_PCRE2_DUPNAMES = 1u << 7,
|
|
REGEX_PCRE2_GLOBAL = 1u << 8
|
|
};
|
|
|
|
enum regex_pcre2_config_flag {
|
|
REGEX_PCRE2_CONFIG_UNICODE = 1u << 0,
|
|
REGEX_PCRE2_CONFIG_JIT = 1u << 1
|
|
};
|
|
|
|
enum regex_pcre2_bridge_error {
|
|
REGEX_PCRE2_ERROR_INVALID_ARGUMENT = -10001,
|
|
REGEX_PCRE2_ERROR_UNSUPPORTED_FLAGS = -10002,
|
|
REGEX_PCRE2_ERROR_PATTERN_TOO_LARGE = -10003,
|
|
REGEX_PCRE2_ERROR_CONFIG = -10004,
|
|
REGEX_PCRE2_ERROR_SUBJECT_TOO_LARGE = -10005,
|
|
REGEX_PCRE2_ERROR_REPLACEMENT_TOO_LARGE = -10006,
|
|
REGEX_PCRE2_ERROR_LIMIT_OUT_OF_RANGE = -10007,
|
|
REGEX_PCRE2_ERROR_CAPTURE_LIMIT = -10008,
|
|
REGEX_PCRE2_ERROR_OUTPUT_BUFFER = -10009
|
|
};
|
|
|
|
enum regex_pcre2_error_phase {
|
|
REGEX_PCRE2_PHASE_NONE = 0,
|
|
REGEX_PCRE2_PHASE_BRIDGE = 1,
|
|
REGEX_PCRE2_PHASE_COMPILE = 2,
|
|
REGEX_PCRE2_PHASE_MATCH = 3,
|
|
REGEX_PCRE2_PHASE_SUBSTITUTE = 4
|
|
};
|
|
|
|
/*
|
|
* This 20-byte, five-u32 record is retained for deterministic compile-only
|
|
* build verification. Runtime callers should use the bounded APIs below.
|
|
*/
|
|
typedef struct regex_pcre2_compile_result {
|
|
int32_t status;
|
|
uint32_t error_offset;
|
|
uint32_t capture_count;
|
|
uint32_t name_count;
|
|
uint32_t effective_options;
|
|
} regex_pcre2_compile_result;
|
|
|
|
/* All values are required and validated against the bridge hard maxima. */
|
|
typedef struct regex_pcre2_limits {
|
|
uint32_t maximum_matches;
|
|
uint32_t maximum_capture_rows;
|
|
uint32_t match_limit;
|
|
uint32_t depth_limit;
|
|
uint32_t heap_limit_kib;
|
|
} regex_pcre2_limits;
|
|
|
|
/*
|
|
* One record is emitted for group zero and every capture group of each
|
|
* retained match. Unset captures use REGEX_PCRE2_UNSET_OFFSET for both bounds.
|
|
*/
|
|
typedef struct regex_pcre2_match_record {
|
|
uint32_t match_number;
|
|
uint32_t group_number;
|
|
uint32_t start_byte;
|
|
uint32_t end_byte;
|
|
} regex_pcre2_match_record;
|
|
|
|
/* Names are UTF-8 slices into the caller-owned name byte buffer. */
|
|
typedef struct regex_pcre2_name_record {
|
|
uint32_t group_number;
|
|
uint32_t name_offset;
|
|
uint32_t name_length;
|
|
} regex_pcre2_name_record;
|
|
|
|
/*
|
|
* Trace collection has an independent bound from match materialization. The
|
|
* byte cap covers the fixed event records plus copied mark bytes.
|
|
*/
|
|
typedef struct regex_pcre2_trace_limits {
|
|
uint32_t maximum_events;
|
|
uint32_t maximum_trace_bytes;
|
|
uint32_t match_limit;
|
|
uint32_t depth_limit;
|
|
uint32_t heap_limit_kib;
|
|
} regex_pcre2_trace_limits;
|
|
|
|
/*
|
|
* Every field except the mark slice is copied directly from a PCRE2 callout
|
|
* block. Positions and lengths are offsets in the 8-bit UTF-8 pattern or
|
|
* subject supplied to the engine.
|
|
*/
|
|
typedef struct regex_pcre2_trace_event {
|
|
uint32_t callout_number;
|
|
uint32_t pattern_position_byte;
|
|
uint32_t next_item_length_byte;
|
|
uint32_t subject_position_byte;
|
|
uint32_t capture_top;
|
|
uint32_t capture_last;
|
|
uint32_t mark_offset;
|
|
uint32_t mark_length;
|
|
} regex_pcre2_trace_event;
|
|
|
|
/*
|
|
* A zero status means that a bounded trace was returned. native_match_status
|
|
* retains pcre2_match()'s exact result, including PCRE2_ERROR_CALLOUT when the
|
|
* bridge deliberately stopped at a trace cap. last_complete_event is
|
|
* UINT32_MAX when no complete event was copied.
|
|
*/
|
|
typedef struct regex_pcre2_trace_result {
|
|
int32_t status;
|
|
uint32_t error_phase;
|
|
uint32_t error_offset;
|
|
int32_t native_match_status;
|
|
uint32_t effective_options;
|
|
uint32_t event_count;
|
|
uint32_t total_event_count;
|
|
uint32_t mark_bytes_length;
|
|
uint32_t trace_bytes_length;
|
|
uint32_t events_truncated;
|
|
uint32_t marks_truncated;
|
|
uint32_t last_complete_event;
|
|
uint32_t matched;
|
|
} regex_pcre2_trace_result;
|
|
|
|
/*
|
|
* This fixed 60-byte record contains no native pointers. `status` is zero on
|
|
* success. Otherwise `error_phase` distinguishes bridge validation, compile,
|
|
* match and replacement errors; `error_offset` is a UTF-8 byte offset when the
|
|
* phase provides one.
|
|
*/
|
|
typedef struct regex_pcre2_run_result {
|
|
int32_t status;
|
|
uint32_t error_phase;
|
|
uint32_t error_offset;
|
|
uint32_t capture_count;
|
|
uint32_t name_count;
|
|
uint32_t match_count;
|
|
uint32_t record_count;
|
|
uint32_t name_record_count;
|
|
uint32_t name_bytes_length;
|
|
uint32_t effective_options;
|
|
uint32_t results_truncated;
|
|
uint32_t names_truncated;
|
|
uint32_t output_length;
|
|
uint32_t substitution_count;
|
|
uint32_t output_truncated;
|
|
} regex_pcre2_run_result;
|
|
|
|
uint32_t regex_pcre2_bridge_abi_version(void);
|
|
uint32_t regex_pcre2_config_flags(void);
|
|
const uint8_t *regex_pcre2_version(void);
|
|
|
|
int32_t regex_pcre2_error_message(int32_t error_code,
|
|
uint8_t *output,
|
|
uint32_t output_capacity);
|
|
|
|
int32_t regex_pcre2_compile_probe(const uint8_t *pattern,
|
|
uint32_t pattern_length,
|
|
uint32_t application_flags,
|
|
regex_pcre2_compile_result *result);
|
|
|
|
int32_t regex_pcre2_execute(
|
|
const uint8_t *pattern,
|
|
uint32_t pattern_length,
|
|
const uint8_t *subject,
|
|
uint32_t subject_length,
|
|
uint32_t application_flags,
|
|
const regex_pcre2_limits *limits,
|
|
regex_pcre2_match_record *records,
|
|
uint32_t record_capacity,
|
|
regex_pcre2_name_record *name_records,
|
|
uint32_t name_record_capacity,
|
|
uint8_t *name_bytes,
|
|
uint32_t name_bytes_capacity,
|
|
regex_pcre2_run_result *result);
|
|
|
|
int32_t regex_pcre2_substitute(
|
|
const uint8_t *pattern,
|
|
uint32_t pattern_length,
|
|
const uint8_t *subject,
|
|
uint32_t subject_length,
|
|
const uint8_t *replacement,
|
|
uint32_t replacement_length,
|
|
uint32_t application_flags,
|
|
const regex_pcre2_limits *limits,
|
|
regex_pcre2_match_record *records,
|
|
uint32_t record_capacity,
|
|
regex_pcre2_name_record *name_records,
|
|
uint32_t name_record_capacity,
|
|
uint8_t *name_bytes,
|
|
uint32_t name_bytes_capacity,
|
|
/* `output` must have output_capacity + 1 writable bytes for PCRE2's NUL. */
|
|
uint8_t *output,
|
|
uint32_t output_capacity,
|
|
regex_pcre2_run_result *result);
|
|
|
|
int32_t regex_pcre2_trace(
|
|
const uint8_t *pattern,
|
|
uint32_t pattern_length,
|
|
const uint8_t *subject,
|
|
uint32_t subject_length,
|
|
uint32_t application_flags,
|
|
const regex_pcre2_trace_limits *limits,
|
|
regex_pcre2_trace_event *events,
|
|
uint32_t event_capacity,
|
|
uint8_t *mark_bytes,
|
|
uint32_t mark_bytes_capacity,
|
|
regex_pcre2_trace_result *result);
|
|
|
|
int32_t regex_pcre2_self_test(void);
|
|
|
|
#endif
|