Skip to content

indexByteString performs range check twice #7469

@effectfully

Description

@effectfully

This is how the denotation of indexByteString is defined:

        indexByteStringDenotation :: BS.ByteString -> Int -> BuiltinResult Word8
        indexByteStringDenotation xs n = do
            unless (n >= 0 && n < BS.length xs) $
                fail "Index out of bounds"
            pure $ BS.index xs n

There's an explicit range check, but BS.index performs one already:

index :: HasCallStack => ByteString -> Int -> Word8
index ps n
    | n < 0          = moduleError "index" ("negative index: " ++ show n)
    | n >= length ps = moduleError "index" ("index too large: " ++ show n
                                         ++ ", length = " ++ show (length ps))
    | otherwise      = ps `unsafeIndex` n

Obviously failing with an exception isn't an option for UPLC, but there's indexMaybe and unsafeIndex. I'd recommend using the former and not performing the check manually, that Maybe in there should compile away. Verify by dumping the Core of PlutusCore.Evaluation.Machine.MachineParameters.Default.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions