* SDK: Sanitize base58 pubkey input (cherry picked from commit250b3969d4
) * SDK: Sanitize base58 signature input (cherry picked from commit2783aee483
) Co-authored-by: Trent Nelson <trent@solana.com>
This commit is contained in:
@ -9,6 +9,8 @@ pub const PUBKEY_BYTES: usize = 32;
|
|||||||
pub const MAX_SEED_LEN: usize = 32;
|
pub const MAX_SEED_LEN: usize = 32;
|
||||||
/// Maximum number of seeds
|
/// Maximum number of seeds
|
||||||
pub const MAX_SEEDS: usize = 16;
|
pub const MAX_SEEDS: usize = 16;
|
||||||
|
/// Maximum string length of a base58 encoded pubkey
|
||||||
|
const MAX_BASE58_LEN: usize = 44;
|
||||||
|
|
||||||
#[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
|
#[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
|
||||||
pub enum PubkeyError {
|
pub enum PubkeyError {
|
||||||
@ -58,6 +60,9 @@ impl FromStr for Pubkey {
|
|||||||
type Err = ParsePubkeyError;
|
type Err = ParsePubkeyError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s.len() > MAX_BASE58_LEN {
|
||||||
|
return Err(ParsePubkeyError::WrongSize);
|
||||||
|
}
|
||||||
let pubkey_vec = bs58::decode(s)
|
let pubkey_vec = bs58::decode(s)
|
||||||
.into_vec()
|
.into_vec()
|
||||||
.map_err(|_| ParsePubkeyError::Invalid)?;
|
.map_err(|_| ParsePubkeyError::Invalid)?;
|
||||||
@ -336,6 +341,13 @@ mod tests {
|
|||||||
pubkey_base58_str.parse::<Pubkey>(),
|
pubkey_base58_str.parse::<Pubkey>(),
|
||||||
Err(ParsePubkeyError::Invalid)
|
Err(ParsePubkeyError::Invalid)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// too long input string
|
||||||
|
// longest valid encoding
|
||||||
|
let mut too_long = bs58::encode(&[255u8; PUBKEY_BYTES]).into_string();
|
||||||
|
// and one to grow on
|
||||||
|
too_long.push('1');
|
||||||
|
assert_eq!(too_long.parse::<Pubkey>(), Err(ParsePubkeyError::WrongSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -58,6 +58,11 @@ impl Keypair {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Number of bytes in a signature
|
||||||
|
pub const SIGNATURE_BYTES: usize = 64;
|
||||||
|
/// Maximum string length of a base58 encoded signature
|
||||||
|
const MAX_BASE58_SIGNATURE_LEN: usize = 88;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(
|
#[derive(
|
||||||
Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, AbiExample,
|
Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, AbiExample,
|
||||||
@ -138,6 +143,9 @@ impl FromStr for Signature {
|
|||||||
type Err = ParseSignatureError;
|
type Err = ParseSignatureError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s.len() > MAX_BASE58_SIGNATURE_LEN {
|
||||||
|
return Err(ParseSignatureError::WrongSize);
|
||||||
|
}
|
||||||
let bytes = bs58::decode(s)
|
let bytes = bs58::decode(s)
|
||||||
.into_vec()
|
.into_vec()
|
||||||
.map_err(|_| ParseSignatureError::Invalid)?;
|
.map_err(|_| ParseSignatureError::Invalid)?;
|
||||||
@ -521,6 +529,21 @@ mod tests {
|
|||||||
signature_base58_str.parse::<Signature>(),
|
signature_base58_str.parse::<Signature>(),
|
||||||
Err(ParseSignatureError::Invalid)
|
Err(ParseSignatureError::Invalid)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// too long input string
|
||||||
|
// longest valid encoding
|
||||||
|
let mut too_long: GenericArray<u8, U64> = GenericArray::default();
|
||||||
|
// *sigh*
|
||||||
|
for i in &mut too_long {
|
||||||
|
*i = 255u8;
|
||||||
|
}
|
||||||
|
let mut too_long = bs58::encode(too_long).into_string();
|
||||||
|
// and one to grow on
|
||||||
|
too_long.push('1');
|
||||||
|
assert_eq!(
|
||||||
|
too_long.parse::<Signature>(),
|
||||||
|
Err(ParseSignatureError::WrongSize)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Reference in New Issue
Block a user