parsers::vcard: allow linebreaks in binval data

[RFC 2426][1] says:

> The binary data MUST be encoded using the "B" encoding format.
> Long lines of encoded binary data SHOULD BE folded to 75 characters
> using the folding method defined in [MIME-DIR].

That implies that whitespace may occur in binval data and we thus must
be able to parse this correctly.

   [1]: https://datatracker.ietf.org/doc/html/rfc2426#section-2.4.1
This commit is contained in:
Jonas Schäfer 2024-04-30 18:16:27 +02:00 committed by Link Mauve
parent 6c3081d656
commit fcadccfbab

View file

@ -14,7 +14,7 @@
//! see [`vcard_update`][crate::vcard_update] module. //! see [`vcard_update`][crate::vcard_update] module.
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
use crate::util::text_node_codecs::{Base64, Codec, Text}; use crate::util::text_node_codecs::{Codec, Text, WhitespaceAwareBase64};
use crate::{ns, Error}; use crate::{ns, Error};
use minidom::Element; use minidom::Element;
@ -44,7 +44,7 @@ generate_element!(
Binval, "BINVAL", VCARD, Binval, "BINVAL", VCARD,
text: ( text: (
/// The actual data. /// The actual data.
data: Base64 data: WhitespaceAwareBase64
) )
); );
@ -131,4 +131,34 @@ mod tests {
assert_eq!(photo.type_.data, "image/jpeg".to_string()); assert_eq!(photo.type_.data, "image/jpeg".to_string());
assert_eq!(photo.binval.data, bytes); assert_eq!(photo.binval.data, bytes);
} }
#[test]
fn test_vcard_with_linebreaks() {
// Test xml stolen from https://xmpp.org/extensions/xep-0153.html#example-5
// extended to use a multi-line base64 string as is allowed as per RFC 2426
let test_vcard = r"<vCard xmlns='vcard-temp'>
<BDAY>1476-06-09</BDAY>
<ADR>
<CTRY>Italy</CTRY>
<LOCALITY>Verona</LOCALITY>
<HOME/>
</ADR>
<NICKNAME/>
<N><GIVEN>Juliet</GIVEN><FAMILY>Capulet</FAMILY></N>
<EMAIL>jcapulet@shakespeare.lit</EMAIL>
<PHOTO>
<TYPE>image/jpeg</TYPE>
<BINVAL>Zm9v
Cg==</BINVAL>
</PHOTO>
</vCard>";
let test_vcard = Element::from_str(&test_vcard).expect("Failed to parse XML");
let test_vcard = VCard::try_from(test_vcard).expect("Failed to parse vCard");
let photo = test_vcard.photo.expect("No photo found");
assert_eq!(photo.type_.data, "image/jpeg".to_string());
assert_eq!(photo.binval.data, b"foo\n");
}
} }