diff --git a/server/providers/Audible.js b/server/providers/Audible.js index 133d3c0d8..88587eddb 100644 --- a/server/providers/Audible.js +++ b/server/providers/Audible.js @@ -1,6 +1,7 @@ const axios = require('axios').default const Logger = require('../Logger') const { isValidASIN } = require('../utils/index') +const htmlSanitizer = require('../utils/htmlSanitizer') class Audible { #responseTimeout = 10000 @@ -66,8 +67,10 @@ class Audible { } return { - title, - subtitle: subtitle || null, + // Audible metadata can contain HTML entities (e.g. `"`, `&`) that are otherwise + // shown literally in titles/subtitles. Decode them at the ingestion boundary. See #5340 + title: title ? htmlSanitizer.stripAllTags(title) : title, + subtitle: subtitle ? htmlSanitizer.stripAllTags(subtitle) : null, author: authors ? authors.map(({ name }) => name).join(', ') : null, narrator: narrators ? narrators.map(({ name }) => name).join(', ') : null, publisher: publisherName, diff --git a/test/server/providers/Audible.test.js b/test/server/providers/Audible.test.js index 67e85111b..282905802 100644 --- a/test/server/providers/Audible.test.js +++ b/test/server/providers/Audible.test.js @@ -45,4 +45,22 @@ describe('Audible', () => { expect(result).to.equal('.5') }) }) + + describe('cleanResult', () => { + it('should decode HTML entities in the title and subtitle (#5340)', () => { + const result = audible.cleanResult({ + title: 'The "Hitler" Myth', + subtitle: 'Image & Reality in the Third Reich', + asin: 'B0TESTASIN' + }) + expect(result.title).to.equal('The "Hitler" Myth') + expect(result.subtitle).to.equal('Image & Reality in the Third Reich') + }) + + it('should keep a null subtitle when none is provided', () => { + const result = audible.cleanResult({ title: 'A Plain Title', asin: 'B0TESTASIN' }) + expect(result.title).to.equal('A Plain Title') + expect(result.subtitle).to.equal(null) + }) + }) }) \ No newline at end of file