Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

str: Ensure the input data is correct #54

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion scale-decode/src/visitor/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl<'temp, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver>
// and let the visitor decide whether to use them or not.
let mut s = Str::new(data)?;
// Since we aren't decoding here, shift our bytes along to after the str:
*data = s.bytes_after();
*data = s.bytes_after()?;
visitor.visit_str(&mut s, type_id)
}
Primitive::U8 => {
Expand Down
14 changes: 8 additions & 6 deletions scale-decode/src/visitor/types/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// limitations under the License.

use crate::visitor::DecodeError;
use codec::{Compact, Decode};
use codec::{Compact, CompactLen, Decode};

/// This represents a string, but defers proper decoding of it until it's asked for,
/// and avoids allocating.
Expand All @@ -31,8 +31,9 @@ impl<'scale> Str<'scale> {
// encoded string (and the rest of the input) around so that we can provide a
// consistent interface with Array/Sequence etc.
let remaining_bytes = &mut &*bytes;
let len = <Compact<u64>>::decode(remaining_bytes)?.0 as usize;
let compact_len = bytes.len() - remaining_bytes.len();
let compact_len = Compact::<u32>::decode(remaining_bytes)?;
let len = compact_len.0 as usize;
let compact_len = Compact::<u32>::compact_len(&compact_len.0);

Ok(Str { len, bytes, compact_len })
}
Expand All @@ -45,8 +46,8 @@ impl<'scale> Str<'scale> {
self.bytes
}
/// The bytes remaining in the input after this string.
pub fn bytes_after(&self) -> &'scale [u8] {
&self.bytes[self.compact_len + self.len..]
pub fn bytes_after(&self) -> Result<&'scale [u8], DecodeError> {
self.bytes.get(self.compact_len + self.len..).ok_or(DecodeError::NotEnoughInput)
}
/// Is the string zero bytes long?
pub fn is_empty(&self) -> bool {
Expand All @@ -56,6 +57,7 @@ impl<'scale> Str<'scale> {
pub fn as_str(&self) -> Result<&'scale str, DecodeError> {
let start = self.compact_len;
let end = start + self.len;
alloc::str::from_utf8(&self.bytes[start..end]).map_err(DecodeError::InvalidStr)
alloc::str::from_utf8(self.bytes.get(start..end).ok_or(DecodeError::NotEnoughInput)?)
.map_err(DecodeError::InvalidStr)
}
}
Loading