From b9caa52065a72a167f5f2de95ed217b72879dead Mon Sep 17 00:00:00 2001 From: Romel <122599979+Ramyromel@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:41:24 +0300 Subject: [PATCH] Add icon validation for file size and duplicates Add validation for icon file size and duplicate icons. * **README.md** - Add information about icon file size validation. - Add information about duplicate icon validation. * **.github/workflows/pr_checks.yml** - Add validation for icon file size in the `validate_icons` job. - Add validation for duplicate icons in the `validate_icons` job. * **maintainer_checklist.md** - Add a step to check for duplicate icons. - Add a step to check for icon file size. * **processor/src/main/kotlin/org/ethereum/lists/chains/Main.kt** - Add logic to check for duplicate icons by calculating a hash (e.g., SHA-256) of each icon file. - Add logic to validate icon file size. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/ethereum-lists/chains?shareId=XXXX-XXXX-XXXX-XXXX). --- .github/workflows/pr_checks.yml | 13 ++++++++++ README.md | 2 ++ maintainer_checklist.md | 2 ++ .../kotlin/org/ethereum/lists/chains/Main.kt | 26 ++++++++++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index 35a7174d9ef7..1b1f17f3e5e1 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -64,6 +64,7 @@ jobs: META_WIDTH=$(echo "$METADATA" | jq '.[0].ImageWidth' -r) META_HEIGHT=$(echo "$METADATA" | jq '.[0].ImageHeight' -r) META_TYPE=$(echo "$METADATA" | jq '.[0].FileTypeExtension' -r) + FILE_SIZE=$(stat -c%s "$TARGET_FILE") if [ "$SCHEMA_WIDTH" != "$META_WIDTH" ]; then echo "Expected width $SCHEMA_WIDTH, got $META_WIDTH" @@ -99,6 +100,18 @@ jobs: BAD=1 ;; esac + + if [ "$FILE_SIZE" -gt 102400 ]; then + echo "File size exceeds 100 KB" + BAD=1 + fi + + for CHANGED_ICON_BLOB in "${CHANGED_ICON_BLOBS[@]}"; do + if [ "$CHANGED_ICON_BLOB" != "$TARGET_FILE" ] && cmp -s "$CHANGED_ICON_BLOB" "$TARGET_FILE"; then + echo "Duplicate icon found: $CHANGED_ICON_BLOB" + BAD=1 + fi + done else echo "Expected an IPFS URL, got $URL" BAD=1 diff --git a/README.md b/README.md index bd22433c843e..dc7f063202ec 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ where: * the URL must be an IPFS url that is publicly resolvable * width and height are positive integers * format is either "png", "jpg" or "svg" + * file size must not exceed 100 KB + * icons must not be duplicates If the chain is an L2 or a shard of another chain you can link it to the parent chain like this: diff --git a/maintainer_checklist.md b/maintainer_checklist.md index 6c5d0e21b75c..c7b47a83fc1f 100644 --- a/maintainer_checklist.md +++ b/maintainer_checklist.md @@ -4,6 +4,8 @@ A checklist for things to check before merging a chain PR. * If the PR contains icons: * `ipfs get` all icon CIDs * check if the size of the icons you got match the size given in the PR + * check for duplicate icons + * check if the icon file size does not exceed 100 KB * Check if a PR does not remove a chain - chains cannot be re-moved - only deprecated (to protect from replay attacks) * Check if a PR does not assign a chainID to a newer chain (something like https://github.com/ethereum-lists/chains/pull/1750) diff --git a/processor/src/main/kotlin/org/ethereum/lists/chains/Main.kt b/processor/src/main/kotlin/org/ethereum/lists/chains/Main.kt index f951860cb2ed..fbac9c1d1531 100644 --- a/processor/src/main/kotlin/org/ethereum/lists/chains/Main.kt +++ b/processor/src/main/kotlin/org/ethereum/lists/chains/Main.kt @@ -13,6 +13,7 @@ import org.kethereum.rpc.HttpEthereumRPC import java.math.BigInteger import javax.imageio.ImageIO import kotlin.io.OnErrorAction.* +import java.security.MessageDigest val parsedShortNames = mutableSetOf() val parsedNames = mutableSetOf() @@ -233,6 +234,16 @@ fun checkIcon(icon: File, withIconDownload: Boolean, allIconCIDs: MutableSet 100 * 1024) { + error("Icon file size exceeds 100 KB") + } + + val iconHash = calculateHash(iconDownloadFile) + if (isDuplicateIcon(iconHash)) { + error("Duplicate icon found: $icon") + } } catch (e: Exception) { e.printStackTrace() error("problem with image $iconDownloadFile") @@ -540,4 +551,17 @@ private fun getNumber(jsonObject: JsonObject, field: String): Long { is Long -> chainId else -> throw (Exception("not a number at $field")) } -} \ No newline at end of file +} + +private fun calculateHash(file: File): String { + val digest = MessageDigest.getInstance("SHA-256") + val bytes = file.readBytes() + val hashBytes = digest.digest(bytes) + return hashBytes.joinToString("") { "%02x".format(it) } +} + +private val iconHashes = mutableSetOf() + +private fun isDuplicateIcon(hash: String): Boolean { + return !iconHashes.add(hash) +}