From 44de2c49f4ffb08393960b38ad7d1a8d96ed9339 Mon Sep 17 00:00:00 2001 From: Aptivi CEO Date: Sun, 29 Sep 2024 19:47:39 +0300 Subject: [PATCH] add - doc - Added indirect version specifying for ... ...vCard --- We've added indirect version specification for vCard 2.1 and 3.0, but this is forbidden for vCard 4.0 and 5.0. --- Type: add Breaking: False Doc Required: True Backport Required: False Part: 1/1 --- VisualCard.Tests/ContactDataBogus.cs | 28 ++++++++++++++++++++++++++++ VisualCard/CardTools.cs | 17 ++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/VisualCard.Tests/ContactDataBogus.cs b/VisualCard.Tests/ContactDataBogus.cs index a94fd939..1ef142c1 100644 --- a/VisualCard.Tests/ContactDataBogus.cs +++ b/VisualCard.Tests/ContactDataBogus.cs @@ -44,6 +44,17 @@ public static class ContactDataBogus """ ; + private static readonly string vcardTwoWithIndirectVersionSpecify = + """ + BEGIN:VCARD + N:Hood;Rick;;; + CALURI:https://www.rickhood.com/events/calendar?type=MusicHoodFestival2024 + NICKNAME:R.H. + VERSION:2.1 + END:VCARD + """ + ; + private static readonly string vcardThreeNoFullName = """ BEGIN:VCARD @@ -124,6 +135,17 @@ public static class ContactDataBogus """ ; + private static readonly string vcardInvalidVersion = + """ + BEGIN:VCARD + N:Hood;Rick;;; + FN:Rick Hood + ADR;TYPE=warehouse:;;Los Angeles, USA;;;; + VERSION:5.0 + END:VCARD + """ + ; + /// /// All of the contacts in this field should fail immediately upon processing the test contacts in the /// function. This throws VCardParseException. @@ -150,6 +172,9 @@ public static class ContactDataBogus [ vcardTwoWithUnsupportedParts, ], + [ + vcardTwoWithIndirectVersionSpecify, + ], ]; /// @@ -179,6 +204,9 @@ public static class ContactDataBogus [ vcardZeroByte, ], + [ + vcardInvalidVersion, + ], ]; } } diff --git a/VisualCard/CardTools.cs b/VisualCard/CardTools.cs index 5a3e770d..32ec8aad 100644 --- a/VisualCard/CardTools.cs +++ b/VisualCard/CardTools.cs @@ -83,6 +83,7 @@ public static Card[] GetCards(StreamReader stream) Version CardVersion = new(); List nestedCards = []; bool nested = false; + bool versionDirect = false; while (!stream.EndOfStream) { bool append = false; @@ -135,23 +136,32 @@ public static Card[] GetCards(StreamReader stream) VersionSpotted = false; EndSpotted = false; nested = true; + versionDirect = true; continue; } // Now that the beginning of the card tag is spotted, parse the version as we need to know how to select the appropriate parser. - // All VCards are required to have their own version directly after the BEGIN:VCARD tag - if (CardLine != $"{VcardConstants._versionSpecifier}:2.1" && + // vCard 4.0 and 5.0 cards are required to have their own version directly after the BEGIN:VCARD tag, but vCard 3.0 and 2.1 may + // or may not place VERSION directly after the BEGIN:VCARD tag. + if (CardLine.StartsWith(VcardConstants._versionSpecifier) && + CardLine != $"{VcardConstants._versionSpecifier}:2.1" && CardLine != $"{VcardConstants._versionSpecifier}:3.0" && CardLine != $"{VcardConstants._versionSpecifier}:4.0" && CardLine != $"{VcardConstants._versionSpecifier}:5.0" && !VersionSpotted) throw new InvalidDataException($"This has an invalid VCard version {CardLine}."); - else if (!VersionSpotted) + else if (!VersionSpotted && CardLine.StartsWith(VcardConstants._versionSpecifier)) { VersionSpotted = true; CardVersion = new(CardLine.Substring(8)); + + // Check to see if the vCard has VERSION directly after BEGIN:VCARD for 4.0 and 5.0 + if (!versionDirect && (CardVersion.Major == 4 || CardVersion.Major == 5)) + throw new InvalidDataException($"vCard {CardVersion.Major}.0 requires that VERSION comes directly after {VcardConstants._beginText}."); continue; } + if (!VersionSpotted) + versionDirect = false; // If the ending tag is spotted, reset everything. if (CardLine == VcardConstants._endText && !EndSpotted) @@ -172,6 +182,7 @@ public static Card[] GetCards(StreamReader stream) CardContent.Clear(); nestedCards.Clear(); BeginSpotted = false; + versionDirect = false; } else if (append) CardContent.AppendLine();