Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
b2c458c
test(core): require bounded BiDi response envelope parsing
seonghobae Aug 18, 2026
89bd3db
style(core): apply canonical BiDi parser test formatting
seonghobae Aug 18, 2026
77eb49b
feat(core): parse bounded BiDi response envelopes
seonghobae Aug 18, 2026
9f924d2
feat(core): expose BiDi response envelope parser
seonghobae Aug 18, 2026
addb63f
style(core): apply canonical response parser formatting
seonghobae Aug 18, 2026
eb086b0
test(core): exercise hostile BiDi response JSON grammar
seonghobae Aug 18, 2026
5c8df76
fix(core): satisfy strict BiDi parser clippy
seonghobae Aug 18, 2026
e455fe8
test(core): cover response parser failure edges
seonghobae Aug 18, 2026
9447879
fix(core): remove unreachable parser error edges
seonghobae Aug 18, 2026
d45118b
test(core): respect bounded response admission boundary
seonghobae Aug 18, 2026
1b157ef
test(core): avoid panic-prone admission assertion
seonghobae Aug 18, 2026
67f5ca3
fix(core): remove unreachable parser coverage branches
seonghobae Aug 18, 2026
e65df25
test(core): require parsed BiDi response correlation
seonghobae Aug 18, 2026
e9d90df
test(core): apply canonical BiDi correlation formatting
seonghobae Aug 18, 2026
5481255
feat(core): correlate bounded BiDi response documents
seonghobae Aug 18, 2026
35a9f42
docs(changelog): record bounded BiDi document correlation
seonghobae Aug 18, 2026
e0b502a
test(core): reject unknown WebDriver BiDi error codes
seonghobae Aug 18, 2026
ebc127c
test(core): format WebDriver BiDi error-code RED
seonghobae Aug 18, 2026
99b4f5d
fix(core): define WebDriver BiDi error-code vocabulary
seonghobae Aug 18, 2026
9b85be5
fix(core): wire WebDriver BiDi error-code validator
seonghobae Aug 18, 2026
e815964
fix(core): reject unknown WebDriver BiDi error codes
seonghobae Aug 18, 2026
5b829fe
style(core): apply canonical rustfmt ordering
seonghobae Aug 18, 2026
f5e087d
test(core): cover current BiDi client-window error
seonghobae Aug 18, 2026
4077a79
fix(core): admit current BiDi client-window error
seonghobae Aug 18, 2026
b7e5ba5
test(core): keep BiDi failure regression panic-free
seonghobae Aug 18, 2026
9d39c59
docs(doctoring): record current BiDi error-code contract
seonghobae Aug 18, 2026
0e8414c
test(core): require wire-derived locateNodes result admission
seonghobae Aug 18, 2026
3ad1c5f
style(core): apply canonical wire-result test formatting
seonghobae Aug 18, 2026
ee545e6
feat(core): admit locateNodes nodes from bounded wire response
seonghobae Aug 18, 2026
2f12879
style(core): apply canonical response document formatting
seonghobae Aug 18, 2026
c8d6d9a
style(core): apply canonical wire node parser formatting
seonghobae Aug 18, 2026
e7b81bc
test(core): cover locateNodes document failure boundaries
seonghobae Aug 18, 2026
16591ab
test(core): keep failure-evidence regressions clippy-clean
seonghobae Aug 18, 2026
858bcf4
test(core): cover locateNodes second-pass parser invariants
seonghobae Aug 18, 2026
da7ffe9
test(core): avoid node debug equality requirement
seonghobae Aug 18, 2026
1b0f6ad
style(core): apply canonical wire-result formatting
seonghobae Aug 18, 2026
cbbc4d6
test(core): cover second-pass parser failure propagation
seonghobae Aug 18, 2026
755ba06
fix(core): keep second-pass string decoding utf8-safe
seonghobae Aug 18, 2026
70d85f9
test(core): cover wire node admission tuple
seonghobae Aug 18, 2026
4089a72
test(core): cover skipped wire result shapes
seonghobae Aug 18, 2026
14a4a39
test(core): cover wire node admission metadata
seonghobae Aug 18, 2026
a2fe264
test(core): prioritize locateNodes result budget
seonghobae Aug 18, 2026
3083e4e
fix(core): enforce locateNodes budget before node decoding
seonghobae Aug 18, 2026
6c3b0bd
fix(core): bind wire parsing to exact result budget
seonghobae Aug 18, 2026
850dbf1
test(core): cover bounded overflow parser invariant
seonghobae Aug 18, 2026
e373a73
test(core): close bounded overflow coverage invariant
seonghobae Aug 18, 2026
dfc522f
test(core): require bounded BiDi byte admission
seonghobae Aug 18, 2026
42c0443
feat(core): admit bounded BiDi response bytes
seonghobae Aug 18, 2026
c80ffdb
test(core): require typed BiDi error-code evidence
seonghobae Aug 18, 2026
f331b32
style(core): canonicalize error-code RED
seonghobae Aug 18, 2026
e9f4dcc
fix(core): retain typed BiDi error-code evidence
seonghobae Aug 18, 2026
358c6e2
test(core): prove every typed BiDi error mapping
seonghobae Aug 18, 2026
6740339
fix(core): restore canonical Rust formatting
seonghobae Aug 18, 2026
a451054
test(core): require wire-to-authority node binding
seonghobae Aug 18, 2026
bcc719f
test(core): format wire authority regression
seonghobae Aug 18, 2026
fda7ea8
feat(core): bind wire locateNodes results to current authority
seonghobae Aug 18, 2026
b0c29ac
test(core): cover BiDi bind admission failure
seonghobae Aug 19, 2026
257d9a2
test(core): require typed BiDi protocol errors
seonghobae Aug 19, 2026
ef4f554
style(core): apply canonical rustfmt to BiDi RED
seonghobae Aug 19, 2026
5441594
fix(core): preserve correlated BiDi protocol errors
seonghobae Aug 19, 2026
cdf0d8f
style(core): apply canonical rustfmt to BiDi error preservation
seonghobae Aug 19, 2026
d883f9a
test(core): align BiDi wire error regression with typed protocol pres…
seonghobae Aug 19, 2026
910c519
style(core): apply canonical rustfmt to BiDi wire regression
seonghobae Aug 19, 2026
291bbac
fix(core): remove unreachable BiDi success-conversion edge
seonghobae Aug 19, 2026
a11b838
test(core): cover nullable BiDi error admission
seonghobae Aug 19, 2026
2687529
test(core): require bounded BiDi WebSocket endpoint admission
seonghobae Aug 19, 2026
a1c4cb5
style(core): canonicalize BiDi WebSocket endpoint RED
seonghobae Aug 19, 2026
dbdff70
style(core): apply canonical rustfmt to endpoint RED
seonghobae Aug 19, 2026
3d2c408
feat(core): admit bounded BiDi WebSocket endpoints
seonghobae Aug 19, 2026
e0ec37e
style(core): apply canonical endpoint rustfmt
seonghobae Aug 19, 2026
bebb1e1
test(core): cover malformed BiDi endpoint authorities
seonghobae Aug 19, 2026
8054128
fix(core): remove unreachable IPv4 endpoint branch
seonghobae Aug 19, 2026
42bfbed
test(core): cover empty BiDi endpoint authority
seonghobae Aug 19, 2026
bc042ee
test(core): format BiDi WebSocket endpoint regressions
seonghobae Aug 19, 2026
5d7906a
test(core): require exact BiDi endpoint session correlation
seonghobae Aug 19, 2026
96fdd9d
style(core): apply canonical BiDi session-correlation formatting
seonghobae Aug 19, 2026
c4d2e4d
feat(core): correlate BiDi endpoint with exact session
seonghobae Aug 19, 2026
45935f5
feat(core): export correlated BiDi endpoint contract
seonghobae Aug 19, 2026
70461f1
style(core): apply canonical session-correlation formatting
seonghobae Aug 19, 2026
4047cef
docs(changelog): record BiDi session correlation
seonghobae Aug 19, 2026
48ad304
test(core): require explicit BiDi connect target
seonghobae Aug 19, 2026
3cc6711
test(core): format explicit BiDi connect target regressions
seonghobae Aug 19, 2026
2e9898d
feat(core): derive explicit BiDi loopback connect targets
seonghobae Aug 19, 2026
aace3a8
feat(core): export explicit BiDi connect target contract
seonghobae Aug 19, 2026
2e43ad6
style(core): format explicit BiDi connect target
seonghobae Aug 19, 2026
6a21bed
test(core): require BiDi connect target changelog evidence
seonghobae Aug 19, 2026
7e30360
docs(core): record explicit BiDi connect target boundary
seonghobae Aug 19, 2026
dc5cfd8
test(core): preserve BiDi endpoint across resolver handoff
seonghobae Aug 19, 2026
3a9506c
fix(core): retain correlated BiDi endpoint on resolver handoff
seonghobae Aug 19, 2026
d34c528
test(core): require exact BiDi socket peer verification
seonghobae Aug 19, 2026
d7cf226
feat(core): verify exact BiDi socket peer
seonghobae Aug 19, 2026
89fc9c3
feat(core): export verified BiDi peer contract
seonghobae Aug 19, 2026
f62d204
test(core): require BiDi socket-peer release evidence
seonghobae Aug 19, 2026
d52cdfe
docs(changelog): record BiDi socket-peer verification
seonghobae Aug 19, 2026
fa510a0
fix(changelog): preserve direct TCP release wording
seonghobae Aug 19, 2026
fcde975
test(network): require bounded BiDi loopback TCP connection
seonghobae Aug 19, 2026
aef0ac7
test(network): format BiDi TCP RED contract
seonghobae Aug 19, 2026
1de304b
feat(network): connect exact BiDi loopback transport
seonghobae Aug 19, 2026
ccb7d31
feat(network): export bounded BiDi TCP transport
seonghobae Aug 19, 2026
b4ce10d
refactor(network): isolate BiDi transport errors
seonghobae Aug 19, 2026
8ed075c
test(network): isolate BiDi transport resilience coverage
seonghobae Aug 19, 2026
ec66b21
refactor(network): keep BiDi transport boundary focused
seonghobae Aug 19, 2026
755d626
test(network): apply canonical BiDi resilience formatting
seonghobae Aug 19, 2026
fd91248
fix(network): remove unused BiDi error imports
seonghobae Aug 19, 2026
975e2e2
docs(changelog): record bounded BiDi TCP transport
seonghobae Aug 19, 2026
c491464
test(network): require consumable BiDi TCP evidence
seonghobae Aug 19, 2026
6aab73c
feat(network): hand off verified BiDi TCP evidence
seonghobae Aug 19, 2026
18703be
docs(changelog): record BiDi TCP evidence handoff
seonghobae Aug 19, 2026
11a533d
test(network): require bounded BiDi WebSocket opening request
seonghobae Aug 19, 2026
9803303
feat(network): bind BiDi WebSocket opening request
seonghobae Aug 19, 2026
8b8f664
test(network): cover BiDi handshake diagnostics
seonghobae Aug 19, 2026
73f2fbd
test(network): close BiDi handshake branch coverage
seonghobae Aug 19, 2026
d39d0d3
test(network): retain BiDi WebSocket client key
seonghobae Aug 19, 2026
ccfc641
fix(network): retain BiDi WebSocket client key
seonghobae Aug 19, 2026
2495b5a
test(core): cover ChromeDriver session id compatibility
seonghobae Aug 19, 2026
baf917c
fix(core): accept canonical ChromeDriver session ids
seonghobae Aug 19, 2026
ba38e2c
merge: carry ChromeDriver session compatibility into correlation
seonghobae Aug 19, 2026
d8f45f8
merge: carry ChromeDriver session compatibility into connect targets
seonghobae Aug 21, 2026
036412a
merge: carry ChromeDriver session compatibility into socket peer veri…
seonghobae Aug 21, 2026
e441948
merge: carry ChromeDriver session compatibility into BiDi TCP transport
seonghobae Aug 21, 2026
b036e47
merge: carry ChromeDriver session compatibility into BiDi handshake r…
seonghobae Aug 21, 2026
30da73a
test(network): redact WebSocket client nonce debug
seonghobae Aug 22, 2026
6922dd9
fix(network): redact WebSocket client nonce debug
seonghobae Aug 22, 2026
e1ad7f4
Merge pull request #193 from ContextualWisdomLab/feat/webdriver-bidi-…
seonghobae Aug 26, 2026
1db9faa
Merge pull request #191 from ContextualWisdomLab/feat/webdriver-bidi-…
seonghobae Aug 26, 2026
37e5688
Merge pull request #189 from ContextualWisdomLab/feat/webdriver-bidi-…
seonghobae Aug 26, 2026
09736e2
Merge pull request #190 from ContextualWisdomLab/feat/webdriver-bidi-…
seonghobae Aug 26, 2026
0b0a9e0
Merge pull request #188 from ContextualWisdomLab/feat/webdriver-bidi-…
seonghobae Aug 26, 2026
225eb45
Merge pull request #192 from ContextualWisdomLab/feat/webdriver-bidi-…
seonghobae Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ All notable changes to OriginWeave are documented in this file. The format follo

### Added

- Bounded WebDriver BiDi loopback TCP transport that consumes one exact no-DNS connect target, retries only explicitly recoverable local transport failures within repository timeout and attempt ceilings, exposes the stream only after operating-system peer inspection and exact peer verification, supports a consuming handoff of the original stream with typed credential-free peer/session/TLS and bounded-attempt evidence, preserves typed causal errors, and performs no DNS, proxy/PAC, process authentication, TLS, WebSocket, BiDi message, browser-action, or Agent-authority step.
- Exact WebDriver BiDi socket-peer verification that consumes an approved no-DNS connect target, requires the observed IP address and port to match exactly, preserves the TLS requirement and exact correlated session id, and remains inert metadata that does not authenticate an OS process, does not negotiate TLS, perform a WebSocket handshake, or grant Agent authority.
- Explicit no-DNS WebDriver BiDi loopback connection targets that derive exact IPv4/IPv6 loopback `SocketAddr` metadata from a session-correlated endpoint, reject `localhost` as requiring separately trusted name resolution, preserve the TLS requirement and exact session id, perform no socket I/O, and grant no Agent authority.
- Rust workspace for independently reusable core, policy, destination, network, TLS, resource, and evidence modules.
- Versioned browser-protocol adapter metadata that distinguishes WebDriver BiDi from pinned CDP, binds bounded adapter/browser revision tokens to an explicit duplicate-free capability set, normalizes capability-set identity independently of caller ordering, and exposes typed fail-closed capability requirements without granting browser, action, network, or secret authority by protocol kind alone.
- Canonical OriginWeave protocol-version parsing for exact `originweave/<major>.<minor>` syntax, with typed fail-closed rejection of malformed, ambiguous, overflowed, or noncanonical serialized generations; parsing does not negotiate compatibility or grant adapter authority.
Expand All @@ -19,6 +22,8 @@ All notable changes to OriginWeave are documented in this file. The format follo
- Fail-closed WebDriver BiDi `locateNodes` response correlation that consumes the exact serialized command, rejects out-of-range or mismatched response `id` values, and returns non-cloneable correlation evidence carrying only the matched command identifier and browsing context without parsing the response or granting browser/Agent authority.
- Typed WebDriver BiDi response-envelope correlation that preserves success/error classification, rejects success responses with absent ids, treats nullable error ids as explicitly uncorrelatable, and prevents correlated error envelopes from becoming success correlation evidence without raw JSON parsing or browser/Agent authority grants.
- Bounded raw WebDriver BiDi response-document admission before JSON parsing, with a 65,536-byte product safety budget, exact wire-text retention, JSON-whitespace-aware top-level object-boundary checks, and typed fail-closed errors; this coarse boundary deliberately does not claim JSON validity, response correlation, browser authenticity, or Agent authority.
- One consuming bounded WebDriver BiDi response-document correlation boundary that parses the exact admitted JSON document and feeds only its typed response kind and protocol-range id into the existing exact command-correlation gate, preserving nested parser/correlation error sources without authenticating transport or granting browser/Agent authority.
- Consuming WebDriver BiDi WebSocket endpoint/session correlation that validates one caller-supplied canonical session UUID and rejects exact session mismatches before later transport use; the correlated type preserves only bounded endpoint metadata and does not authenticate Chromium, ChromeDriver, the caller, or the socket peer.
- Fail-closed WebDriver BiDi `script.NodeRemoteValue` admission that requires the exact remote type `node` and a non-empty `sharedId` within the same UTF-8 identifier budget as browser session and context identifiers, rejecting control and whitespace so an untrusted `locateNodes` item cannot be retained as a later typed-input handle without a usable shared node identity.
- Same-call `locateNodes` result admission that revalidates the exact current session, browsing context, canonical origin, and document epoch, rejects an over-budget or non-node result, and translates each admitted `sharedId` through the authority registry into an `ObservedNodeHandle` without performing browser I/O.
- Same-call QueryNodes admission that transfers a non-cloneable SemanticObservation protocol-use proof by ownership into `bind_current_nodes` before an untrusted `locateNodes` result can become current `ObservedNodeHandle` values, so Navigation-only or TypedInput-only proofs cannot mint observation handles.
Expand Down
20 changes: 20 additions & 0 deletions crates/originweave-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ mod browser_registry;
mod browser_registry_coverage;
mod contracts;
mod webdriver_bidi_command;
mod webdriver_bidi_error_code;
mod webdriver_bidi_response_document;
mod webdriver_bidi_response_document_correlation;
mod webdriver_bidi_response_envelope;
mod webdriver_bidi_result;
mod webdriver_bidi_websocket_connect_target;
mod webdriver_bidi_websocket_endpoint;

pub use browser_authority_registry::BrowserAuthorityRegistry;
pub use browser_protocol::{
Expand Down Expand Up @@ -71,10 +76,25 @@ pub use webdriver_bidi_command::{
WebDriverBiDiLocateNodesResponseCorrelationError,
WebDriverBiDiLocateNodesResponseEnvelopeError,
};
pub use webdriver_bidi_error_code::WebDriverBiDiErrorCode;
pub use webdriver_bidi_response_document::{
BoundedWebDriverBiDiResponseDocument, MAX_WEBDRIVER_BIDI_RESPONSE_DOCUMENT_BYTES,
WebDriverBiDiResponseDocumentAdmissionError,
};
pub use webdriver_bidi_response_document_correlation::WebDriverBiDiLocateNodesResponseDocumentError;
pub use webdriver_bidi_response_envelope::{
MAX_WEBDRIVER_BIDI_RESPONSE_JSON_DEPTH, MAX_WEBDRIVER_BIDI_RESPONSE_TOP_LEVEL_FIELDS,
ParsedWebDriverBiDiCommandResponseEnvelope, WebDriverBiDiResponseEnvelopeParseError,
};
pub use webdriver_bidi_result::{
ValidatedWebDriverBiDiLocateNodesResult, WebDriverBiDiLocateNodesResultAdmissionError,
};
pub use webdriver_bidi_websocket_connect_target::{
VerifiedWebDriverBiDiSocketPeer, WebDriverBiDiSocketPeerVerificationError,
WebDriverBiDiWebSocketConnectTarget, WebDriverBiDiWebSocketConnectTargetError,
};
pub use webdriver_bidi_websocket_endpoint::{
CorrelatedWebDriverBiDiWebSocketEndpoint, MAX_WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_BYTES,
WebDriverBiDiWebSocketEndpoint, WebDriverBiDiWebSocketEndpointAdmissionError,
WebDriverBiDiWebSocketEndpointCorrelationError,
};
170 changes: 170 additions & 0 deletions crates/originweave-core/src/webdriver_bidi_error_code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/// Typed current WebDriver BiDi protocol error code retained from one validated error response.
///
/// This vocabulary is deliberately closed over the protocol error codes reviewed by OriginWeave.
/// Unknown wire text remains fail-closed and cannot become typed protocol evidence.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WebDriverBiDiErrorCode {
/// The command or one of its arguments is invalid.
InvalidArgument,
/// A selector argument is invalid.
InvalidSelector,
/// The referenced browser session does not exist.
InvalidSessionId,
/// The referenced web extension is invalid.
InvalidWebExtension,
/// A requested pointer move target is outside the allowed bounds.
MoveTargetOutOfBounds,
/// The referenced user prompt does not exist.
NoSuchAlert,
/// The referenced client window does not exist.
NoSuchClientWindow,
/// The referenced network collector does not exist.
NoSuchNetworkCollector,
/// The referenced element does not exist.
NoSuchElement,
/// The referenced frame does not exist.
NoSuchFrame,
/// The referenced handle does not exist.
NoSuchHandle,
/// The referenced history entry does not exist.
NoSuchHistoryEntry,
/// The referenced network intercept does not exist.
NoSuchIntercept,
/// The requested network data does not exist.
NoSuchNetworkData,
/// The referenced node does not exist.
NoSuchNode,
/// The referenced network request does not exist.
NoSuchRequest,
/// The referenced screencast does not exist.
NoSuchScreencast,
/// The referenced script does not exist.
NoSuchScript,
/// The referenced storage partition does not exist.
NoSuchStoragePartition,
/// The referenced user context does not exist.
NoSuchUserContext,
/// The referenced web extension does not exist.
NoSuchWebExtension,
/// A browser session could not be created.
SessionNotCreated,
/// The browser could not capture the requested screen image.
UnableToCaptureScreen,
/// The browser could not close as requested.
UnableToCloseBrowser,
/// The browser could not set the requested cookie.
UnableToSetCookie,
/// The browser could not set the requested file input.
UnableToSetFileInput,
/// Requested network data is temporarily unavailable.
UnavailableNetworkData,
/// The supplied storage-partition descriptor is underspecified.
UnderspecifiedStoragePartition,
/// The command is unknown to the remote end.
UnknownCommand,
/// The remote end reported an otherwise unclassified protocol error.
UnknownError,
/// The requested operation is unsupported by the remote end.
UnsupportedOperation,
}

/// Parse one exact decoded WebDriver BiDi `ErrorCode` value into typed protocol evidence.
pub(crate) fn parse_webdriver_bidi_error_code(value: &[u8]) -> Option<WebDriverBiDiErrorCode> {
const ERROR_CODES: &[(&[u8], WebDriverBiDiErrorCode)] = &[
(b"invalid argument", WebDriverBiDiErrorCode::InvalidArgument),
(b"invalid selector", WebDriverBiDiErrorCode::InvalidSelector),
(
b"invalid session id",
WebDriverBiDiErrorCode::InvalidSessionId,
),
(
b"invalid web extension",
WebDriverBiDiErrorCode::InvalidWebExtension,
),
(
b"move target out of bounds",
WebDriverBiDiErrorCode::MoveTargetOutOfBounds,
),
(b"no such alert", WebDriverBiDiErrorCode::NoSuchAlert),
(
b"no such client window",
WebDriverBiDiErrorCode::NoSuchClientWindow,
),
(
b"no such network collector",
WebDriverBiDiErrorCode::NoSuchNetworkCollector,
),
(b"no such element", WebDriverBiDiErrorCode::NoSuchElement),
(b"no such frame", WebDriverBiDiErrorCode::NoSuchFrame),
(b"no such handle", WebDriverBiDiErrorCode::NoSuchHandle),
(
b"no such history entry",
WebDriverBiDiErrorCode::NoSuchHistoryEntry,
),
(
b"no such intercept",
WebDriverBiDiErrorCode::NoSuchIntercept,
),
(
b"no such network data",
WebDriverBiDiErrorCode::NoSuchNetworkData,
),
(b"no such node", WebDriverBiDiErrorCode::NoSuchNode),
(b"no such request", WebDriverBiDiErrorCode::NoSuchRequest),
(
b"no such screencast",
WebDriverBiDiErrorCode::NoSuchScreencast,
),
(b"no such script", WebDriverBiDiErrorCode::NoSuchScript),
(
b"no such storage partition",
WebDriverBiDiErrorCode::NoSuchStoragePartition,
),
(
b"no such user context",
WebDriverBiDiErrorCode::NoSuchUserContext,
),
(
b"no such web extension",
WebDriverBiDiErrorCode::NoSuchWebExtension,
),
(
b"session not created",
WebDriverBiDiErrorCode::SessionNotCreated,
),
(
b"unable to capture screen",
WebDriverBiDiErrorCode::UnableToCaptureScreen,
),
(
b"unable to close browser",
WebDriverBiDiErrorCode::UnableToCloseBrowser,
),
(
b"unable to set cookie",
WebDriverBiDiErrorCode::UnableToSetCookie,
),
(
b"unable to set file input",
WebDriverBiDiErrorCode::UnableToSetFileInput,
),
(
b"unavailable network data",
WebDriverBiDiErrorCode::UnavailableNetworkData,
),
(
b"underspecified storage partition",
WebDriverBiDiErrorCode::UnderspecifiedStoragePartition,
),
(b"unknown command", WebDriverBiDiErrorCode::UnknownCommand),
(b"unknown error", WebDriverBiDiErrorCode::UnknownError),
(
b"unsupported operation",
WebDriverBiDiErrorCode::UnsupportedOperation,
),
];

ERROR_CODES
.iter()
.find_map(|(raw, code)| (*raw == value).then_some(*code))
}
22 changes: 22 additions & 0 deletions crates/originweave-core/src/webdriver_bidi_response_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub enum WebDriverBiDiResponseDocumentAdmissionError {
EmptyDocument,
/// The raw response exceeds the OriginWeave pre-parser byte budget.
DocumentTooLarge,
/// The raw response is not valid UTF-8.
InvalidUtf8,
/// The first and last non-whitespace bytes do not delimit a JSON object.
InvalidObjectBoundary,
}
Expand All @@ -27,6 +29,9 @@ impl fmt::Display for WebDriverBiDiResponseDocumentAdmissionError {
formatter,
"WebDriver BiDi response document exceeds {MAX_WEBDRIVER_BIDI_RESPONSE_DOCUMENT_BYTES} bytes"
),
Self::InvalidUtf8 => {
formatter.write_str("WebDriver BiDi response document is not valid UTF-8")
}
Self::InvalidObjectBoundary => formatter.write_str(
"WebDriver BiDi response document must have a top-level JSON object boundary",
),
Expand Down Expand Up @@ -68,6 +73,23 @@ impl BoundedWebDriverBiDiResponseDocument {
})
}

/// Admits raw transport bytes after bounding them and validating UTF-8.
///
/// The byte budget is checked before UTF-8 validation or owned-text
/// allocation. This keeps hostile transport payloads outside the parser
/// boundary until both the resource and text-encoding contracts hold.
pub fn from_utf8_bytes(
raw: &[u8],
) -> Result<Self, WebDriverBiDiResponseDocumentAdmissionError> {
if raw.len() > MAX_WEBDRIVER_BIDI_RESPONSE_DOCUMENT_BYTES {
return Err(WebDriverBiDiResponseDocumentAdmissionError::DocumentTooLarge);
}

let raw = std::str::from_utf8(raw)
.map_err(|_| WebDriverBiDiResponseDocumentAdmissionError::InvalidUtf8)?;
Self::new(raw)
}

/// Returns the exact admitted response text, including surrounding JSON whitespace.
#[must_use]
pub fn as_str(&self) -> &str {
Expand Down
Loading
Loading