solana/nft_bridge: allow invalid utf-8 metadata
Change-Id: If2fba5d394b8afab34ed0f12714851d0121a2924
This commit is contained in:
parent
47c5834e6f
commit
3a9264f6e4
|
@ -264,6 +264,17 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.0"
|
||||
|
@ -1645,6 +1656,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"borsh",
|
||||
"bridge",
|
||||
"bstr",
|
||||
"byteorder",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
|
@ -2199,6 +2211,12 @@ dependencies = [
|
|||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
|
|
|
@ -19,6 +19,7 @@ default = []
|
|||
[dependencies]
|
||||
bridge = { path = "../../../bridge/program", features = ["no-entrypoint", "cpi"] }
|
||||
borsh = "0.8.1"
|
||||
bstr = "0.2.16"
|
||||
byteorder = "1.4.3"
|
||||
rocksalt = { path = "../../../solitaire/rocksalt" }
|
||||
solitaire = { path = "../../../solitaire/program" }
|
||||
|
|
|
@ -215,6 +215,8 @@ pub fn complete_wrapped(
|
|||
accs: &mut CompleteWrapped,
|
||||
data: CompleteWrappedData,
|
||||
) -> Result<()> {
|
||||
use bstr::ByteSlice;
|
||||
|
||||
// Verify the chain registration
|
||||
let derivation_data: EndpointDerivationData = (&*accs).into();
|
||||
accs.chain_registration
|
||||
|
@ -261,10 +263,12 @@ pub fn complete_wrapped(
|
|||
},
|
||||
)?;
|
||||
|
||||
let mut name = accs.vaa.name.clone();
|
||||
name.truncate(32);
|
||||
let mut symbol = accs.vaa.symbol.clone();
|
||||
let name = accs.vaa.name.clone();
|
||||
let mut symbol: Vec<u8> = accs.vaa.symbol.clone().as_bytes().to_vec();
|
||||
symbol.truncate(10);
|
||||
let mut symbol: Vec<char> = symbol.chars().collect();
|
||||
symbol.retain(|&c| c != '\u{FFFD}');
|
||||
let symbol: String = symbol.iter().collect();
|
||||
|
||||
let spl_token_metadata_ix = spl_token_metadata::instruction::create_metadata_accounts(
|
||||
spl_token_metadata::id(),
|
||||
|
|
|
@ -67,6 +67,7 @@ pub struct PayloadTransfer {
|
|||
|
||||
impl DeserializePayload for PayloadTransfer {
|
||||
fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
|
||||
use bstr::ByteSlice;
|
||||
let mut v = Cursor::new(buf);
|
||||
|
||||
if v.read_u8()? != 1 {
|
||||
|
@ -78,17 +79,23 @@ impl DeserializePayload for PayloadTransfer {
|
|||
|
||||
let token_chain = v.read_u16::<BigEndian>()?;
|
||||
|
||||
let mut symbol_data: [u8; 32] = [0; 32];
|
||||
// We may receive invalid UTF-8 over the bridge, especially if truncated. To compensate for
|
||||
// this we rely on the bstr libraries ability to parse invalid UTF-8, and strip out the
|
||||
// "Invalid Unicode Codepoint" (FFFD) characters. This becomes the canonical representation
|
||||
// on Solana.
|
||||
let mut symbol_data = vec![0u8; 32];
|
||||
v.read_exact(&mut symbol_data)?;
|
||||
let mut symbol = String::from_utf8(symbol_data.to_vec())
|
||||
.map_err::<SolitaireError, _>(|_| TokenBridgeError::InvalidUTF8String.into())?;
|
||||
symbol = symbol.chars().filter(|c| c != &'\0').collect();
|
||||
symbol_data.retain(|&c| c != 0);
|
||||
let mut symbol: Vec<char> = symbol_data.chars().collect();
|
||||
symbol.retain(|&c| c != '\u{FFFD}');
|
||||
let symbol: String = symbol.iter().collect();
|
||||
|
||||
let mut name_data: [u8; 32] = [0; 32];
|
||||
let mut name_data = vec![0u8; 32];
|
||||
v.read_exact(&mut name_data)?;
|
||||
let mut name = String::from_utf8(name_data.to_vec())
|
||||
.map_err::<SolitaireError, _>(|_| TokenBridgeError::InvalidUTF8String.into())?;
|
||||
name = name.chars().filter(|c| c != &'\0').collect();
|
||||
name_data.retain(|&c| c != 0);
|
||||
let mut name: Vec<char> = name_data.chars().collect();
|
||||
name.retain(|&c| c != '\u{FFFD}');
|
||||
let name: String = name.iter().collect();
|
||||
|
||||
let mut id_data: [u8; 32] = [0; 32];
|
||||
v.read_exact(&mut id_data)?;
|
||||
|
|
Loading…
Reference in New Issue