Skip to content

Commit 324b33d

Browse files
committed
feat: check max script sig push
1 parent b11cdc2 commit 324b33d

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

src/descriptor/bare.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
120120
S: Satisfier<Pk>,
121121
{
122122
let ms = self.ms.satisfy(satisfier)?;
123-
let script_sig = witness_to_scriptsig(&ms);
123+
let script_sig = witness_to_scriptsig(&ms)?;
124124
let witness = vec![];
125125
Ok((witness, script_sig))
126126
}
@@ -133,7 +133,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
133133
S: Satisfier<Pk>,
134134
{
135135
let ms = self.ms.satisfy_malleable(satisfier)?;
136-
let script_sig = witness_to_scriptsig(&ms);
136+
let script_sig = witness_to_scriptsig(&ms)?;
137137
let witness = vec![];
138138
Ok((witness, script_sig))
139139
}

src/descriptor/sh.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,14 @@ impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> {
376376
ShInner::SortedMulti(ref smv) => {
377377
let mut script_witness = smv.satisfy(satisfier)?;
378378
script_witness.push(smv.encode().into_bytes());
379-
let script_sig = witness_to_scriptsig(&script_witness);
379+
let script_sig = witness_to_scriptsig(&script_witness)?;
380380
let witness = vec![];
381381
Ok((witness, script_sig))
382382
}
383383
ShInner::Ms(ref ms) => {
384384
let mut script_witness = ms.satisfy(satisfier)?;
385385
script_witness.push(ms.encode().into_bytes());
386-
let script_sig = witness_to_scriptsig(&script_witness);
386+
let script_sig = witness_to_scriptsig(&script_witness)?;
387387
let witness = vec![];
388388
Ok((witness, script_sig))
389389
}
@@ -406,7 +406,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> {
406406
ShInner::Ms(ref ms) => {
407407
let mut script_witness = ms.satisfy_malleable(satisfier)?;
408408
script_witness.push(ms.encode().into_bytes());
409-
let script_sig = witness_to_scriptsig(&script_witness);
409+
let script_sig = witness_to_scriptsig(&script_witness)?;
410410
let witness = vec![];
411411
Ok((witness, script_sig))
412412
}

src/miniscript/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ impl ScriptContext for Legacy {
385385
fn check_witness(witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
386386
// In future, we could avoid by having a function to count only
387387
// len of script instead of converting it.
388-
if witness_to_scriptsig(witness).len() > MAX_SCRIPTSIG_SIZE {
388+
if witness_to_scriptsig(witness).unwrap().len() > MAX_SCRIPTSIG_SIZE {
389389
return Err(ScriptContextError::MaxScriptSigSizeExceeded);
390390
}
391391
Ok(())

src/util.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use core::convert::TryFrom;
44

5+
use bitcoin::constants::MAX_SCRIPT_ELEMENT_SIZE;
56
use bitcoin::hashes::Hash;
67
use bitcoin::script::{self, PushBytes, ScriptBuf};
78
use bitcoin::PubkeyHash;
@@ -47,18 +48,22 @@ pub(crate) fn witness_size<T: ItemSize>(wit: &[T]) -> usize {
4748
wit.iter().map(T::size).sum::<usize>() + varint_len(wit.len())
4849
}
4950

50-
pub(crate) fn witness_to_scriptsig(witness: &[Vec<u8>]) -> ScriptBuf {
51+
pub(crate) fn witness_to_scriptsig(witness: &[Vec<u8>]) -> Result<ScriptBuf, super::Error> {
5152
let mut b = script::Builder::new();
52-
for wit in witness {
53+
for (i, wit) in witness.iter().enumerate() {
5354
if let Ok(n) = script::read_scriptint(wit) {
5455
b = b.push_int(n);
5556
} else {
56-
let push = <&PushBytes>::try_from(wit.as_slice())
57-
.expect("All pushes in miniscript are <73 bytes");
57+
if i != witness.len() - 1 {
58+
assert!(wit.len() < 73, "All pushes in miniscript are < 73 bytes");
59+
} else {
60+
assert!(wit.len() <= MAX_SCRIPT_ELEMENT_SIZE, "P2SH redeem script is <= 520 bytes");
61+
}
62+
let push = <&PushBytes>::try_from(wit.as_slice()).expect("checked above");
5863
b = b.push_slice(push)
5964
}
6065
}
61-
b.into_script()
66+
Ok(b.into_script())
6267
}
6368

6469
// trait for pushing key that depend on context

0 commit comments

Comments
 (0)