From 4bfab503c758f8112e679997f1b517929acd4678 Mon Sep 17 00:00:00 2001 From: Kayokoi <113896798+wozhenbang2004@users.noreply.github.com> Date: Sat, 7 Nov 2026 12:04:30 -0800 Subject: [PATCH 1/2] fix(isMagnetURI): require hexadecimal BitTorrent v2 hashes Restrict only the btmh digest to hexadecimal characters while retaining case-insensitive matching. --- src/lib/isMagnetURI.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/isMagnetURI.js b/src/lib/isMagnetURI.js index e00ee3c32..017fa0087 100644 --- a/src/lib/isMagnetURI.js +++ b/src/lib/isMagnetURI.js @@ -1,6 +1,6 @@ import assertString from './util/assertString'; -const magnetURIComponent = /(?:^magnet:\?|[^?&]&)xt(?:\.1)?=urn:(?:(?:aich|bitprint|btih|ed2k|ed2khash|kzhash|md5|sha1|tree:tiger):[a-z0-9]{32}(?:[a-z0-9]{8})?|btmh:1220[a-z0-9]{64})(?:$|&)/i; +const magnetURIComponent = /(?:^magnet:\?|[^?&]&)xt(?:\.1)?=urn:(?:(?:aich|bitprint|btih|ed2k|ed2khash|kzhash|md5|sha1|tree:tiger):[a-z0-9]{32}(?:[a-z0-9]{8})?|btmh:1220[a-f0-9]{64})(?:$|&)/i; export default function isMagnetURI(url) { assertString(url); From 1f1daf60aeb33e89250589c97eb9aa712bb6fe7e Mon Sep 17 00:00:00 2001 From: Kayokoi <113896798+wozhenbang2004@users.noreply.github.com> Date: Sat, 7 Nov 2026 12:10:32 -0800 Subject: [PATCH 2/2] test(isMagnetURI): cover non-hexadecimal v2 hashes Cover invalid characters at the start, middle and end, alongside valid lowercase and uppercase hexadecimal digests and query parameters. --- test/validators.test.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/validators.test.js b/test/validators.test.js index 98d2a12ff..d2cd64740 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -12771,6 +12771,23 @@ describe('Validators', () => { }); + it('should require hexadecimal BitTorrent v2 magnet hashes', () => { + const hash = '0123456789abcdef'.repeat(4); + test({ + validator: 'isMagnetURI', + valid: [ + `magnet:?xt=urn:btmh:1220${hash}`, + `magnet:?xt=urn:btmh:1220${hash.toUpperCase()}`, + `magnet:?dn=example&xt.1=urn:btmh:1220${hash}&tr=udp://example.com`, + ], + invalid: [ + `magnet:?xt=urn:btmh:1220g${hash.slice(1)}`, + `magnet:?xt=urn:btmh:1220${hash.slice(0, -1)}Z`, + `magnet:?dn=example&xt.1=urn:btmh:1220${hash.slice(0, 32)}g${hash.slice(33)}&dn=test`, + ], + }); + }); + it('should validate LatLong', () => { test({ validator: 'isLatLong',