Skip to content

Commit aef3ee5

Browse files
committed
fix(nft): handle invalid Solana NFT image URLs
1 parent 1ae5ace commit aef3ee5

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

app/api/nft/models.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from enum import Enum
2+
from typing import Any
23

34
from pydantic import BaseModel, ConfigDict, Field, field_validator
45
from pydantic.alias_generators import to_camel
56

67

78
def strip_trailing_slash_validator(v: str | None) -> str | None:
89
if v is not None:
9-
return v.rstrip("/")
10+
return v.strip().rstrip("/")
1011
return v
1112

1213

@@ -171,13 +172,16 @@ def validate_urls(cls, v: str) -> str:
171172

172173

173174
class SolanaAssetContentLink(BaseModel):
174-
image: str | None = None
175+
image: Any = None
175176
external_url: str | None = None
176177

177178
@field_validator("image")
178179
@classmethod
179-
def validate_urls(cls, v: str | None) -> str | None:
180-
return strip_trailing_slash_validator(v)
180+
def validate_image(cls, v: Any) -> str | None:
181+
if isinstance(v, str):
182+
return strip_trailing_slash_validator(v) or None
183+
184+
return None
181185

182186
model_config = ConfigDict(
183187
extra="allow",

app/api/nft/test_routes.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from app.api.nft.models import (
77
SimpleHashNFTResponse,
8+
SolanaAssetContentLink,
89
SolanaAssetMerkleProof,
910
)
1011
from app.main import app
@@ -471,3 +472,25 @@ def capture_post_request(*args, **kwargs):
471472
{"contractAddress": "0x123", "tokenId": "456"},
472473
{"contractAddress": "0x789", "tokenId": "101112"},
473474
]
475+
476+
477+
def test_solana_asset_content_link_image_validation():
478+
# Test with boolean value - should convert to None
479+
# Ref: https://github.com/brave/gate3/issues/72
480+
link_false = SolanaAssetContentLink.model_validate({"image": False})
481+
assert link_false.image is None
482+
483+
# Test with None - should remain None
484+
link_none = SolanaAssetContentLink.model_validate({"image": None})
485+
assert link_none.image is None
486+
487+
# Test with empty string - should convert to None
488+
link_empty = SolanaAssetContentLink.model_validate({"image": ""})
489+
assert link_empty.image is None
490+
491+
# Test with valid string - should apply URL validation
492+
# Trailing slash and whitespaces should be stripped
493+
link_string = SolanaAssetContentLink.model_validate(
494+
{"image": "https://example.com/image.jpg/ "}
495+
)
496+
assert link_string.image == "https://example.com/image.jpg"

0 commit comments

Comments
 (0)