Limit getProgramAccounts memcpy filter string to 128 bytes

This commit is contained in:
Michael Vines 2021-02-22 22:31:20 -08:00 committed by mergify[bot]
parent 41bfbea63d
commit 65f1afe5e1
2 changed files with 46 additions and 7 deletions

View File

@ -16,10 +16,15 @@ impl RpcFilterType {
match encoding {
MemcmpEncoding::Binary => {
let MemcmpEncodedBytes::Binary(bytes) = &compare.bytes;
bs58::decode(&bytes)
.into_vec()
.map(|_| ())
.map_err(|e| e.into())
if bytes.len() > 128 {
Err(RpcFilterError::Base58DataTooLarge)
} else {
bs58::decode(&bytes)
.into_vec()
.map(|_| ())
.map_err(|e| e.into())
}
}
}
}
@ -27,10 +32,12 @@ impl RpcFilterType {
}
}
#[derive(Error, Debug)]
#[derive(Error, PartialEq, Debug)]
pub enum RpcFilterError {
#[error("bs58 decode error")]
DecodeError(#[from] bs58::decode::Error),
#[error("encoded binary (base 58) data should be less than 129 bytes")]
Base58DataTooLarge,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -140,4 +147,36 @@ mod tests {
}
.bytes_match(&data));
}
#[test]
fn test_verify_memcmp() {
let base58_bytes = "\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111";
assert_eq!(base58_bytes.len(), 128);
assert_eq!(
RpcFilterType::Memcmp(Memcmp {
offset: 0,
bytes: MemcmpEncodedBytes::Binary(base58_bytes.to_string()),
encoding: None,
})
.verify(),
Ok(())
);
let base58_bytes = "\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
1";
assert_eq!(base58_bytes.len(), 129);
assert_eq!(
RpcFilterType::Memcmp(Memcmp {
offset: 0,
bytes: MemcmpEncodedBytes::Binary(base58_bytes.to_string()),
encoding: None,
})
.verify(),
Err(RpcFilterError::Base58DataTooLarge)
);
}
}

View File

@ -207,7 +207,7 @@ Returns all information associated with the account of provided Pubkey
fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
"base58" is limited to Account data of less than 128 bytes.
"base58" is limited to Account data of less than 129 bytes.
"base64" will return base64 encoded data for Account data of any size.
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
@ -1806,7 +1806,7 @@ Returns all accounts owned by the provided program Pubkey
##### Filters:
- `memcmp: <object>` - compares a provided series of bytes with program account data at a particular offset. Fields:
- `offset: <usize>` - offset into program account data to start comparison
- `bytes: <string>` - data to match, as base-58 encoded string
- `bytes: <string>` - data to match, as base-58 encoded string and limited to less than 129 bytes
- `dataSize: <u64>` - compares the program account data length with the provided data size