Skip to content

Commit

Permalink
Update parsing of integrity metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Oct 27, 2023
1 parent 5995973 commit b0f0f0e
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 13 deletions.
45 changes: 43 additions & 2 deletions crates/wasmparser/src/validator/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,34 @@ impl<'a> ComponentNameParser<'a> {
}

fn parse_hash(&mut self) -> Result<&'a str> {
let hash = self.take_up_to('>')?;
Ok(hash)
let integrity = self.take_up_to('>')?;
let mut any = false;
for hash in integrity.split_whitespace() {
any = true;
let rest = hash
.strip_prefix("sha256")
.or_else(|| hash.strip_prefix("sha384"))
.or_else(|| hash.strip_prefix("sha512"));
let rest = match rest {
Some(s) => s,
None => bail!(self.offset, "unrecognized hash algorithm: `{hash}`"),
};
let rest = match rest.strip_prefix('-') {
Some(s) => s,
None => bail!(self.offset, "expected `-` after hash algorithm: {hash}"),
};
let (base64, _options) = match rest.find('?') {
Some(i) => (&rest[..i], Some(&rest[i + 1..])),
None => (rest, None),
};
if !is_base64(base64) {
bail!(self.offset, "not valid base64: `{base64}`");
}
}
if !any {
bail!(self.offset, "integrity hash cannot be empty");
}
Ok(integrity)
}

fn eat_optional_hash(&mut self) -> Result<Option<&'a str>> {
Expand Down Expand Up @@ -730,6 +756,21 @@ impl<'a> ComponentNameParser<'a> {
}
}

fn is_base64(s: &str) -> bool {
if s.is_empty() {
return false;
}
let mut equals = 0;
for (i, byte) in s.as_bytes().iter().enumerate() {
match byte {
b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'+' | b'/' if equals == 0 => {}
b'=' if i > 0 && equals < 2 => equals += 1,
_ => return false,
}
}
true
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion tests/local/component-model/export.wast
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

;; cannot export some types of strings
(assert_invalid
(component (type (component (export "integrity=<x>" (func)))))
(component (type (component (export "integrity=<sha256-a>" (func)))))
"not of an allowed kind to use in an export")
(assert_invalid
(component (type (component (export "url=<x>" (func)))))
Expand Down
42 changes: 37 additions & 5 deletions tests/local/component-model/import.wast
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@
(component
(import "locked-dep=<a:b>" (func))
(import "locked-dep=<a:[email protected]>" (func))
(import "locked-dep=<a:b>,integrity=<a>" (func))
(import "locked-dep=<a:[email protected]>,integrity=<a>" (func))
(import "locked-dep=<a:b>,integrity=<sha256-a>" (func))
(import "locked-dep=<a:[email protected]>,integrity=<sha256-a>" (func))
)

(assert_invalid
Expand Down Expand Up @@ -269,7 +269,7 @@
(component
(import "url=<>" (func))
(import "url=<a>" (func))
(import "url=<a>,integrity=<a>" (func))
(import "url=<a>,integrity=<sha256-a>" (func))
)

(assert_invalid
Expand All @@ -280,6 +280,38 @@
"failed to find `>`")

(component
(import "integrity=<>" (func))
(import "integrity=<a>" (func))
(import "integrity=<sha256-a>" (func))
(import "integrity=<sha384-a>" (func))
(import "integrity=<sha512-a>" (func))
(import "integrity=<sha512-a sha256-b>" (func))
(import "integrity=< sha512-a sha256-b >" (func))
(import "integrity=< sha512-a?abcd >" (func))
(import "integrity=<sha256-abcdefghijklmnopqrstuvwxyz>" (func))
(import "integrity=<sha256-ABCDEFGHIJKLMNOPQRSTUVWXYZ>" (func))
(import "integrity=<sha256-++++++++++++++++++++==>" (func))
(import "integrity=<sha256-////////////////////==>" (func))
)
(assert_invalid
(component (import "integrity=<>" (func)))
"integrity hash cannot be empty")
(assert_invalid
(component (import "integrity=<sha256>" (func)))
"expected `-` after hash algorithm")
(assert_invalid
(component (import "integrity=<sha256->" (func)))
"not valid base64")
(assert_invalid
(component (import "integrity=<sha256-^^^^>" (func)))
"not valid base64")
(assert_invalid
(component (import "integrity=<sha256-=========>" (func)))
"not valid base64")
(assert_invalid
(component (import "integrity=<sha256-=>" (func)))
"not valid base64")
(assert_invalid
(component (import "integrity=<sha256-==>" (func)))
"not valid base64")
(assert_invalid
(component (import "integrity=<md5-ABC>" (func)))
"unrecognized hash algorithm")
4 changes: 2 additions & 2 deletions tests/snapshots/local/component-model/import.wast/44.print
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
(type (;1;) (func))
(import "locked-dep=<a:[email protected]>" (func (;1;) (type 1)))
(type (;2;) (func))
(import "locked-dep=<a:b>,integrity=<a>" (func (;2;) (type 2)))
(import "locked-dep=<a:b>,integrity=<sha256-a>" (func (;2;) (type 2)))
(type (;3;) (func))
(import "locked-dep=<a:[email protected]>,integrity=<a>" (func (;3;) (type 3)))
(import "locked-dep=<a:[email protected]>,integrity=<sha256-a>" (func (;3;) (type 3)))
)
2 changes: 1 addition & 1 deletion tests/snapshots/local/component-model/import.wast/56.print
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
(type (;1;) (func))
(import "url=<a>" (func (;1;) (type 1)))
(type (;2;) (func))
(import "url=<a>,integrity=<a>" (func (;2;) (type 2)))
(import "url=<a>,integrity=<sha256-a>" (func (;2;) (type 2)))
)
20 changes: 18 additions & 2 deletions tests/snapshots/local/component-model/import.wast/59.print
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
(component
(type (;0;) (func))
(import "integrity=<>" (func (;0;) (type 0)))
(import "integrity=<sha256-a>" (func (;0;) (type 0)))
(type (;1;) (func))
(import "integrity=<a>" (func (;1;) (type 1)))
(import "integrity=<sha384-a>" (func (;1;) (type 1)))
(type (;2;) (func))
(import "integrity=<sha512-a>" (func (;2;) (type 2)))
(type (;3;) (func))
(import "integrity=<sha512-a sha256-b>" (func (;3;) (type 3)))
(type (;4;) (func))
(import "integrity=< sha512-a sha256-b >" (func (;4;) (type 4)))
(type (;5;) (func))
(import "integrity=< sha512-a?abcd >" (func (;5;) (type 5)))
(type (;6;) (func))
(import "integrity=<sha256-abcdefghijklmnopqrstuvwxyz>" (func (;6;) (type 6)))
(type (;7;) (func))
(import "integrity=<sha256-ABCDEFGHIJKLMNOPQRSTUVWXYZ>" (func (;7;) (type 7)))
(type (;8;) (func))
(import "integrity=<sha256-++++++++++++++++++++==>" (func (;8;) (type 8)))
(type (;9;) (func))
(import "integrity=<sha256-////////////////////==>" (func (;9;) (type 9)))
)

0 comments on commit b0f0f0e

Please sign in to comment.