diff --git a/sync-server/server.js b/sync-server/server.js index 7a3dc11..586b5de 100644 --- a/sync-server/server.js +++ b/sync-server/server.js @@ -127,9 +127,20 @@ async function tryDownloadSongs(data) { function processSong(song) { return new Promise((resolve) => { - // Basic sanitization - const safeName = (song.name || 'unknown').replace(/[\\/:*?"<>|]/g, '_'); - const safeArtist = (song.artist || 'unknown').replace(/[\\/:*?"<>|]/g, '_'); + // Sanitize filename with proper encoding handling + const sanitizeFilename = (str) => { + if (!str) return 'unknown'; + // Normalize Unicode (NFC) to ensure consistent encoding + const normalized = str.normalize('NFC'); + // Replace Windows illegal characters and control characters + return normalized + .replace(/[\\/:*?"<>|\x00-\x1f\x7f]/g, '_') + .trim() + .substring(0, 200); // Limit length to avoid path too long errors + }; + + const safeName = sanitizeFilename(song.name); + const safeArtist = sanitizeFilename(song.artist); const source = song.platform || song.source; // Filename: Artist - Name [source_id] const baseName = `${safeArtist} - ${safeName} [${source}_${song.id}]`;