plutus
plutus copied to clipboard
`indexByteString` performs range check twice
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.