From ae8bfbb76dac1012fe77509dd3c1c670b7a13e7d Mon Sep 17 00:00:00 2001 From: Johannes Krobath Date: Tue, 14 Jul 2026 10:38:01 +0200 Subject: [PATCH] fix: keep parentheses and plus sign in modelIcon URLs (#2896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sanitizeImageParameter replaced every character outside [a-z\d\-_./:] with a dash, so a model like "CK-TLSR8656-SS5-01(7014)" became "CK-TLSR8656-SS5-01-7014-", and the resulting zigbee2mqtt.io/images/devices URL returned 404 — the device showed the default "unavailable" icon and the icon download failed. The z2m image filename is an exact match of the device model (herdsman-converters keeps "(", ")" and "+" verbatim; only "/" and spaces are turned into "-"). Verified against the live image server for herdsman-converters 26.73.0: CK-TLSR8656-SS5-01(7014).png 200 (parens kept) CK-BL702-ROUTER-01(7018).png 200 (parens kept) YMF40-YDM4109+-YDF40.png 200 (slash->dash, plus kept) AV2010-14.png 200 (slash->dash) AE-260.png 200 (space->dash) Adding "()" and "+" to the allowed character class fixes every parens (31) and plus (39) device without touching the slash (117) or space (738) devices, whose dash replacement stays correct. Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils.js b/lib/utils.js index f4b664ea..b7fd35c2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -364,7 +364,7 @@ const ikeaTradfriManufacturerID = [4476]; * @returns {the sanitized image name} */ function sanitizeImageParameter(parameter) { - const replaceByDash = [/\?/g, /&/g, /[^a-z\d\-_./:]/gi, /[/]/gi]; + const replaceByDash = [/\?/g, /&/g, /[^a-z\d\-_./:()+]/gi, /[/]/gi]; let sanitized = parameter || 'illegalParameter'; replaceByDash.forEach(r => sanitized = sanitized.replace(r, '-')); return sanitized;