Skip to content

Large branch bodies panic at runtime because jump displacements overflow i16 #158

Description

@ajbufort

A forward jump over a large branch body panics at runtime because the jump displacement is written with a u16 bound check but decoded as an i16.

Minimal reproduction (no and/or needed - plain if):

>> if (false()) then (count([ ...13000 members... ]) = 999) else false()
thread 'main' panicked: index out of bounds

The then branch here compiles to more than 32KB of bytecode. FunctionBuilder::patch_jump checks the offset against u16::MAX and writes two little-endian bytes, but Instruction::Jump/JumpIfTrue/JumpIfFalse hold an i16 and the VM decodes with i16::from_le_bytes, so an offset in 32768..=65535 wraps to a negative displacement and the VM jumps backward past the start of the chunk. An offset above 65535 hits the panic!("jump too far") in patch_jump instead of returning an error.

This affects every construct that emits a forward jump over a branch: if/then/else, quantified expressions, xsl:iterate, and so on. It is reachable from any sufficiently large (but not deeply nested) branch body.

I have a fix that widens the jump displacement to i32.

-Tony Bufort

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions