solana/nft_bridge: allow invalid utf-8 metadata

Change-Id: If2fba5d394b8afab34ed0f12714851d0121a2924
This commit is contained in:
Reisen 2021-09-13 10:26:59 +00:00 committed by Hendrik Hofstadt
parent 47c5834e6f
commit 3a9264f6e4
4 changed files with 41 additions and 11 deletions

View File

@ -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"

View File

@ -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" }

View File

@ -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(),

View File

@ -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)?;