From 50f26a2e62d885f2c94c561b076316009836a946 Mon Sep 17 00:00:00 2001 From: Warren He Date: Fri, 17 Nov 2023 10:42:27 -0800 Subject: [PATCH] runtime/evm: add tests for JSON round trip --- analyzer/evmnfts/evm_nfts.go | 6 ++++- analyzer/runtime/evm/erc721_test.go | 42 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 analyzer/runtime/evm/erc721_test.go diff --git a/analyzer/evmnfts/evm_nfts.go b/analyzer/evmnfts/evm_nfts.go index 1de78d4c9..8c629025c 100644 --- a/analyzer/evmnfts/evm_nfts.go +++ b/analyzer/evmnfts/evm_nfts.go @@ -118,7 +118,11 @@ func (p *processor) ProcessItem(ctx context.Context, batch *storage.QueryBatch, staleNFT.DownloadRound, storage.SanitizeStringP(nftData.MetadataURI), nftData.MetadataAccessed, - // If SanitizeString can affect JSON validity, we're doomed. + // Metadata has already gone through a round trip of JSON Unmarshal + // and Marshal, which should already make it safe for PostgreSQL. But + // for consistency, pass it through SanitizeString as well. This + // shouldn't have any effect, and if it does, it shouldn't affect the + // JSON syntax. storage.SanitizeStringP(nftData.Metadata), storage.SanitizeStringP(nftData.Name), storage.SanitizeStringP(nftData.Description), diff --git a/analyzer/runtime/evm/erc721_test.go b/analyzer/runtime/evm/erc721_test.go new file mode 100644 index 000000000..e8974300f --- /dev/null +++ b/analyzer/runtime/evm/erc721_test.go @@ -0,0 +1,42 @@ +package evm + +import ( + "encoding/json" + "testing" + "unicode/utf8" + + "github.com/stretchr/testify/require" +) + +func TestJSONRoundTrip(t *testing.T) { + for _, s := range []string{ + // Invalid UTF-8. + "{\"a\": \"\xff\"}", + "{\"\xff\": \"a\"}", + // NUL bytes. + "{\"a\": \"\x00\"}", + "{\"\x00\": \"a\"}", + // Codepoint zero. + "{\"a\": \"\\u0000\"}", + "{\"\\u0000\": \"a\"}", + } { + var parsed any + err := json.Unmarshal([]byte(s), &parsed) + if err != nil { + // Erroring out while unmarshalling is fine. + t.Logf("%#v -> parsing: %v\n", s, err) + continue + } + roundTripBuf, err := json.Marshal(parsed) + if err != nil { + // Erroring out while marshalling is uncool, but not a showstopper. + t.Logf("%#v -> stringifying: %v\n", s, err) + continue + } + roundTrip := string(roundTripBuf) + // If it gets through the round trip, it'd better be clean. + require.True(t, utf8.ValidString(roundTrip), "%#v -> invalid UTF-8 %#v", s, roundTrip) + require.NotContains(t, roundTrip, 0x0, "%#v -> contains NUL byte %#v", s, roundTrip) + t.Logf("%#v -> %#v\n", s, roundTrip) + } +}