From 7bd70a345decd78662d45a448db114c9b2e5698d Mon Sep 17 00:00:00 2001 From: METO Date: Sun, 12 Oct 2025 17:07:58 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF?= =?UTF-8?q?=E9=9F=B3=E4=B9=90=E6=AD=8C=E8=AF=8DHTML=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E8=A7=A3=E7=A0=81=E5=8A=9F=E8=83=BD=20(#119)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/providers/tencent.js | 43 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/providers/tencent.js b/src/providers/tencent.js index ef46b8a..f255c2a 100644 --- a/src/providers/tencent.js +++ b/src/providers/tencent.js @@ -276,18 +276,53 @@ export default class TencentProvider extends BaseProvider { return JSON.stringify(url); } + /** + * 解码HTML实体编码 + */ + decodeHtmlEntities(text) { + if (!text) return text; + + // 常见HTML实体编码映射 + const entityMap = { + ''': "'", + '"': '"', + '&': '&', + '<': '<', + '>': '>', + ' ': ' ' + }; + + // 替换命名实体 + let decoded = text; + for (const [entity, char] of Object.entries(entityMap)) { + decoded = decoded.replace(new RegExp(entity, 'g'), char); + } + + // 替换数字实体(如 ' " 等) + decoded = decoded.replace(/&#(\d+);/g, (match, dec) => { + return String.fromCharCode(parseInt(dec, 10)); + }); + + // 替换十六进制实体(如 ' 等) + decoded = decoded.replace(/&#x([0-9a-fA-F]+);/g, (match, hex) => { + return String.fromCharCode(parseInt(hex, 16)); + }); + + return decoded; + } + /** * 腾讯音乐歌词解码 */ lyricDecode(result) { const jsonStr = result.substring(18, result.length - 1); const data = JSON.parse(jsonStr); - + const lyricData = { - lyric: data.lyric ? Buffer.from(data.lyric, 'base64').toString() : '', - tlyric: data.trans ? Buffer.from(data.trans, 'base64').toString() : '' + lyric: data.lyric ? this.decodeHtmlEntities(Buffer.from(data.lyric, 'base64').toString()) : '', + tlyric: data.trans ? this.decodeHtmlEntities(Buffer.from(data.trans, 'base64').toString()) : '' }; - + return JSON.stringify(lyricData); } } \ No newline at end of file