From 1ea0254f957734e7629119235e91e03b0c6bd4f2 Mon Sep 17 00:00:00 2001 From: Andrey Kutejko Date: Sat, 13 Jan 2024 17:47:45 +0100 Subject: [PATCH] Ignore case when looking for iTunes extension namespace --- CHANGELOG.md | 1 + src/channel.rs | 9 ++++++--- src/extension/itunes/mod.rs | 8 ++++++++ src/item.rs | 8 ++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d2f635b5..4cfb5d1f06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 2.x.x - Unreleased - Update `chrono` to 0.4.31 [`#160`](https://github.com/rust-syndication/rss/pull/160) +- Change how iTunes extension is detected. Use case insensitive comparison of a namespace [`#159`](https://github.com/rust-syndication/rss/pull/159) ## 2.0.6 - 2023-08-12 diff --git a/src/channel.rs b/src/channel.rs index 684cd43cbe..e6f59d1f12 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -21,7 +21,7 @@ use crate::error::Error; #[cfg(feature = "atom")] use crate::extension::atom; use crate::extension::dublincore; -use crate::extension::itunes; +use crate::extension::itunes::{self, is_itunes_namespace}; use crate::extension::syndication; use crate::extension::util::{ extension_entry, extension_name, parse_extension_element, read_namespace_declarations, @@ -1299,8 +1299,11 @@ impl Channel { Some(ns @ atom::NAMESPACE) => { extension_entry(&mut extensions, ns, name).push(ext); } - Some(ns @ itunes::NAMESPACE) - | Some(ns @ dublincore::NAMESPACE) + Some(ns) if is_itunes_namespace(ns) => { + extension_entry(&mut extensions, itunes::NAMESPACE, name) + .push(ext); + } + Some(ns @ dublincore::NAMESPACE) | Some(ns @ syndication::NAMESPACE) => { extension_entry(&mut extensions, ns, name).push(ext); } diff --git a/src/extension/itunes/mod.rs b/src/extension/itunes/mod.rs index 92ec902b00..4568f056d4 100644 --- a/src/extension/itunes/mod.rs +++ b/src/extension/itunes/mod.rs @@ -22,6 +22,14 @@ pub use self::itunes_owner::*; /// The iTunes XML namespace. pub const NAMESPACE: &str = "http://www.itunes.com/dtds/podcast-1.0.dtd"; +/// Formally XML namespace is case sensitive and this should be just an equality check. +/// But many podcast publishers ignore this and use different case variations of the namespace. +/// Hence this check is relaxed and ignores a case. +#[inline] +pub(crate) fn is_itunes_namespace(ns: &str) -> bool { + ns.eq_ignore_ascii_case(NAMESPACE) +} + fn parse_image(map: &mut BTreeMap>) -> Option { let mut element = match map.remove("image").map(|mut v| v.remove(0)) { Some(element) => element, diff --git a/src/item.rs b/src/item.rs index 173665c0b8..4eb199bc23 100644 --- a/src/item.rs +++ b/src/item.rs @@ -20,7 +20,7 @@ use crate::error::Error; #[cfg(feature = "atom")] use crate::extension::atom; use crate::extension::dublincore; -use crate::extension::itunes; +use crate::extension::itunes::{self, is_itunes_namespace}; use crate::extension::util::{ extension_entry, extension_name, parse_extension_element, read_namespace_declarations, }; @@ -660,7 +660,11 @@ impl Item { Some(ns @ atom::NAMESPACE) => { extension_entry(&mut extensions, ns, name).push(ext); } - Some(ns @ itunes::NAMESPACE) | Some(ns @ dublincore::NAMESPACE) => { + Some(ns) if is_itunes_namespace(ns) => { + extension_entry(&mut extensions, itunes::NAMESPACE, name) + .push(ext); + } + Some(ns @ dublincore::NAMESPACE) => { extension_entry(&mut extensions, ns, name).push(ext); } _ => extension_entry(&mut item.extensions, prefix, name).push(ext),