CardDAV: use Apple/Google/CardDAV vCard flavor

In principle, CardDAV servers support arbitrary vCard 3.0
data. Extensions can be different and need to be preserved. However,
when multiple different clients or the server's Web UI interpret the
vCards, they need to agree on the semantic of these vCard extensions.

In practice, CardDAV was pushed by Apple and Apple clients are
probably the most common clients of CardDAV services. When the Google
Contacts Web UI creates or edits a contact, Google CardDAV will
send that data using the vCard flavor used by Apple.

Therefore it makes sense to exchange contacts with *all* CardDAV
servers using that format. This format could be made configurable in
SyncEvolution on a case-by-case basis; at the moment, it is
hard-coded.

During syncing, SyncEvolution takes care to translate between the
vCard flavor used internally (based on Evolution) and the CardDAV
vCard flavor. This mapping includes:

X-AIM/JABBER/... <-> IMPP + X-SERVICE-TYPE

  Any IMPP property declared as X-SERVICE-TYPE=AIM will get
  mapped to X-AIM. Same for others. Some IMPP service types
  have no known X- property extension; they are stored in
  EDS as IMPP. X- property extensions without a known X-SERVICE-TYPE
  (for example, GaduGadu and Groupwise) are stored with
  X-SERVICE-TYPE values chosen by SyncEvolution so that
  Google CardDAV preserves them (GroupWise with mixed case
  got translated by Google into Groupwise, so the latter is used).

  Google always sends an X-ABLabel:Other for IMPP. This is ignored
  because the service type overrides it.

  The value itself also gets transformed during the mapping. IMPP uses
  an URI as value, with a chat protocol (like "aim" or "xmpp") and
  some protocol specific identifier. For each X- extension the
  protocol is determined by the property name and the value is the
  protocol specific identifier without URL encoding.

X-SPOUSE/MANAGER/ASSISTANT <-> X-ABRELATEDNAMES + X-ABLabel

  The mapping is based on the X-ABLabel property attached to
  the X-ABRELATEDNAMES property. This depends on the English
  words "Spouse", "Manager", "Assistant" that Google CardDAV
  and Apple devices seem to use regardless of the configured
  language.

  As with IMPP, only the subset of related names which have
  a corresponding X- property extension get mapped. The rest
  is stored in EDS using the X-ABRELATEDNAMES property.

X-ANNIVERSARY <-> X-ABDATE

  Same here, with X-ABLabel:Anniversary as the special case
  which gets mapped.

X-ABLabel parameter <-> property

  CardDAV vCards have labels attached to arbitrary other properties
  (TEL, ADR, X-ABDATE, X-ABRELATEDNAMES, ...) via vCard group tags:
  item1.X-ABDATE:2010-01-01
  item1.X-ABLabel:Anniversary

  The advantage is that property values can contain arbitrary
  characters, including line breaks and double quotation marks,
  which is not possible in property parameters.

  Neither EDS nor KDE (judging from the lack of responses on the
  KDE-PIM mailing list) support custom labels. SyncEvolution could
  have used grouping as it is done in CardDAV, but grouping is not
  used much (not at all?) by the UIs working with the vCards in EDS
  and KDE. It seemed easier to use a new X-ABLabel parameter.

  Characters which cannot be stored in a parameter get converted
  (double space to single space, line break to space, etc.) during
  syncing. In practice, these characters don't appear in X-ABLabel
  properties anyway because neither Apple nor Google UIs allow entering
  them for custom labels.

  The "Other" label is used by Google even in case where it adds no
  information. For example, all XMPP properties have an associated
  X-ABLabel=Other although the Web UI does not provide a means to edit
  or show such a label. Editing the text before the value in the UI
  changes the X-SERVICE-TYPE parameter value, not the X-ABLabel as for
  other fields.

  Therefore the "Other" label is ignored by removing it during syncing.

X-EVOLUTION-UI-SLOT (the parameter used in Evolution to determine the
order of properties in the UI) gets stored in CardDAV. The only exception
is Google CardDAV which got confused when an IMPP property had both
X-SERVICE-TYPE and X-EVOLUTION-UI-SLOT parameters set. For Google,
X-EVOLUTION-UI-SLOT is only sent on other properties and thus ordering
of chat information can get lost when syncing with Google.

CardDAV needs to use test data with the new CardDAV vCard flavor.
Most CardDAV servers can store EDS vCards and thus
Client::Source::*::testImport passed (with minor tweaks in
synccompare) when using the default eds_contact.vcf, but
Client::Sync::*::testItems fails when comparing synced data with test
cases when the synced data uses the native format and the test cases
are still the ones from EDS.

A libsynthesis with URLENCODE/DECODE() and sharedfield parameter for
<property> is needed.
This commit is contained in:
Patrick Ohly 2014-05-16 11:25:00 +02:00
parent f61e417360
commit 933d10f97c
18 changed files with 1124 additions and 87 deletions

View File

@ -25,7 +25,7 @@ SE_CHECK_FOR_STABLE_RELEASE
# Minimum version of libsynthesis as defined in its
# configure script and thus .pc files:
define([SYNTHESIS_MIN_VERSION], [3.4.0.47.1])
define([SYNTHESIS_MIN_VERSION], [3.4.0.47.2])
# Line above is patched by gen-autotools.sh. Handle
# both "yes" and "no".

View File

@ -1523,7 +1523,23 @@ void WebDAVSource::getSynthesisInfo(SynthesisInfo &info,
info.m_backendRule = "HAVE-SYNCEVOLUTION-EXDATE-DETACHED";
} else if (content == "VCARD") {
// Assume that a CardDAV server has and preserves UID values.
info.m_backendRule = "LOCALSTORAGE-WITH-UID";
info.m_backendRule = "CARDDAV";
fragments.m_remoterules["CARDDAV"] =
" <remoterule name='CARDDAV'>\n"
" <deviceid>none</deviceid>\n"
" <noemptyproperties>yes</noemptyproperties>\n"
" <include rule='HAVE-EVOLUTION-UI-SLOT'/>\n"
" <include rule='HAVE-EVOLUTION-UI-SLOT-IN-IMPP'/>\n"
" <include rule='HAVE-VCARD-UID'/>\n"
" <include rule='HAVE-ABLABEL-PROPERTY'/>\n"
" </remoterule>";
// Assume that a CardDAV server uses IMPP (RFC 4770) and
// Apple Address book (X-AB) extensions. Convert to the traditional,
// internal fields (ANNIVERSARY, JABBER, etc.) after reading
// from a CardDAV server and from the traditional fields
// before writing.
info.m_beforeWriteScript = "$VCARD_BEFOREWRITE_SCRIPT_WEBDAV;\n";
info.m_afterReadScript = "$VCARD_AFTERREAD_SCRIPT_WEBDAV;\n";
}
// TODO: instead of identifying the peer based on the
@ -1533,12 +1549,17 @@ void WebDAVSource::getSynthesisInfo(SynthesisInfo &info,
string host = m_session->getURI().m_host;
if (host.find("google") != host.npos) {
info.m_backendRule = "GOOGLE";
// Same as CARDDAV above, minus HAVE-EVOLUTION-UI-SLOT-IN-IMPP.
// Sending IMPP;X-SERVICE-TYPE=..;X-EVOLUTION-UI-SLOT=
// causes Google to ignore X-SERVICE-TYPE.
fragments.m_remoterules["GOOGLE"] =
" <remoterule name='GOOGLE'>\n"
" <deviceid>none</deviceid>\n"
// enable extensions, just in case (not relevant yet for calendar)
" <include rule=\"ALL\"/>\n"
" <include rule=\"HAVE-VCARD-UID\">\n"
" <noemptyproperties>yes</noemptyproperties>\n"
" <include rule='HAVE-EVOLUTION-UI-SLOT'/>\n"
// " <include rule='HAVE-EVOLUTION-UI-SLOT-IN-IMPP'/>\n"
" <include rule='HAVE-VCARD-UID'/>\n"
" <include rule='HAVE-ABLABEL-PROPERTY'/>\n"
" </remoterule>";
} else if (host.find("yahoo") != host.npos) {
info.m_backendRule = "YAHOO";
@ -1558,7 +1579,8 @@ void WebDAVSource::getSynthesisInfo(SynthesisInfo &info,
// doesn't seem to store the X-EVOLUTION-UI-SLOT parameter
// extensions.
" <include rule=\"ALL\"/>\n"
" <include rule=\"HAVE-VCARD-UID\">\n"
" <include rule=\"HAVE-VCARD-UID\"/>\n"
" <include rule=\"HAVE-ABLABEL-PROPERTY\"/>\n"
" </remoterule>";
}
}

View File

@ -270,6 +270,10 @@ public:
if (it != m_props.end() ||
(it = m_props.find("testcases")) != m_props.end()) {
config.m_testcases = it->second.c_str();
} else if (m_type == "carddav") {
// CardDAV uses a non-EDS vCard flavor, so we can't use the
// default eds_contact.vcf.
config.m_testcases = "testcases/carddav.vcf";
}
}

View File

@ -7,6 +7,9 @@
it for pairing. But we don't know that and thus cannot rely on it. -->
<field name="UID" type="string" compare="never"/>
<!-- The group tags used to combine instances of different repeating properties. -->
<field name="GROUP_TAG" array="yes" type="string" compare="never"/>
<!-- Name elements -->
<field name="N_LAST" type="string" compare="always"/>
<field name="N_FIRST" type="string" compare="always"/>
@ -31,10 +34,15 @@
<field name="ORG_TEAM" type="string" compare="conflict" merge="fillempty"/>
<field name="ROLE" type="string" compare="conflict" merge="fillempty"/>
<!-- birthday and anniversary (not necessarily the same) -->
<!-- Birthday and anniversary (not necessarily the same). BDAY is always used,
ANNIVERSARY only by some profiles. -->
<field name="BDAY" type="date" compare="conflict" merge="fillempty"/>
<field name="ANNIVERSARY" type="date" compare="conflict" merge="fillempty"/>
<!-- Generic storage for special dates, including anniversary. Mapped to X-ABDATE + X-ABLabel. -->
<!-- Beware, don't use "DATE", it conflicts with builtin function name. -->
<field name="XDATE" array="yes" type="date" compare="conflict"/>
<!-- telephone numbers -->
<field name="TEL" array="yes" type="telephone" compare="conflict"/>
<field name="TEL_FLAGS" array="yes" type="integer" compare="conflict"/>
@ -56,6 +64,9 @@
<field name="BLOGURL" array="yes" type="string" compare="conflict"/>
<field name="VIDEOURL" array="yes" type="string" compare="conflict"/>
<!-- generic replacement for MANAGER/ASSISTANT/SPOUSE -->
<field name="RELATEDNAMES" array="yes" type="string" compare="conflict"/>
<!-- related persons: should be turned into array, like WEB and CALURI/FBURL -->
<field name="MANAGER" type="string" compare="conflict"/>
<field name="ASSISTANT" type="string" compare="conflict"/>
@ -65,7 +76,12 @@
type would be useful, maybe add that later. -->
<field name="WANTS_HTML" type="string" compare="conflict"/>
<!-- chat handles: should be turned into one array, like WEB and CALURI/FBURL -->
<!-- RFC 4770 chat handles, used internally *instead* of the individual handles below. -->
<field name="IMPP" array="yes" type="string" compare="conflict"/> <!-- includes protocol: xmpp:google%20talk -->
<field name="IMPP_SERVICE" array="yes" type="string" compare="conflict"/> <!-- GoogleTalk -->
<field name="IMPP_SLOT" array="yes" type="string" compare="conflict"/> <!-- Evolution UI slot -->
<!-- Individual chat handles: used as temporary storage when exchanging data via legacy profiles. -->
<field name="AIM_HANDLE" array="yes" type="string" compare="conflict"/>
<field name="AIM_SLOT" array="yes" type="string" compare="conflict"/>
<field name="GADUGADU_HANDLE" array="yes" type="string" compare="conflict"/>
@ -117,6 +133,9 @@
<field name="CRYPTOSIGNPREF" type="string" compare="conflict"/>
<field name="OPENPGPFP" type="string" compare="conflict"/>
<!-- Custom labels. Mapped to either X-ABProperty via group tag (WebDAV) or X-ABLabel parameter (internal). -->
<field name="LABEL" array="yes" type="string" compare="conflict"/>
<!-- store extensions that don't match any of the other fields -->
<field name="XPROPS" array="yes" type="string" compare="never"/>
</fieldlist>

View File

@ -1,4 +1,4 @@
<!-- vCard profile -->
<!-- vCard profile for Evolution, KDE, SyncML -->
<mimeprofile name="vCard" fieldlist="contacts">
<profile name="VCARD" nummandatory="0"> <!-- we allow records without "N" as Address book can store them -->
@ -78,7 +78,7 @@
<value field="ROLE"/>
</property>
<property name="TEL">
<property name="TEL" groupfield="GROUP_TAG">
<value field="TEL"/>
<position field="TEL" repeat="array" increment="1" minshow="1"/>
<parameter name="TYPE" default="yes" positional="no" show="yes">
@ -101,9 +101,12 @@
<parameter name="X-EVOLUTION-UI-SLOT" positional="no" show="no" rule="HAVE-EVOLUTION-UI-SLOT">
<value field="TEL_SLOT"/>
</parameter>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="EMAIL">
<property name="EMAIL" groupfield="GROUP_TAG">
<value field="EMAIL"/>
<position field="EMAIL" repeat="array" increment="1" minshow="1"/>
<parameter name="TYPE" default="yes" positional="no" show="yes">
@ -117,9 +120,12 @@
<parameter name="X-EVOLUTION-UI-SLOT" positional="no" show="no" rule="HAVE-EVOLUTION-UI-SLOT">
<value field="EMAIL_SLOT"/>
</parameter>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="URL">
<property name="URL" groupfield="GROUP_TAG">
<value field="WEB"/>
<position field="WEB" repeat="array" increment="1" minshow="1"/>
<parameter name="TYPE" default="yes" positional="no" show="yes">
@ -130,6 +136,9 @@
<enum name="PREF" value="B3"/>
</value>
</parameter>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="CALURI" suppressempty="yes">
@ -197,6 +206,14 @@
<value field="ASSISTANT"/>
</property>
<property name="X-ABRELATEDNAMES" suppressempty="yes" groupfield="GROUP_TAG">
<value field="RELATEDNAMES"/>
<position field="RELATEDNAMES" repeat="array" increment="1" minshow="0"/>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="X-EVOLUTION-SPOUSE" suppressempty="yes" delayedparsing="1" rule ="KDE"/>
<property name="X-EVOLUTION-SPOUSE" suppressempty="yes" delayedparsing="1" rule ="other">
<value field="SPOUSE" show="yes"/>
@ -223,6 +240,27 @@
<value field="ANNIVERSARY"/>
</property>
<property name="X-ABDATE" suppressempty="yes" groupfield="GROUP_TAG">
<value field="XDATE" conversion="DATE+EXTFMT"/>
<position field="XDATE" repeat="array" increment="1" minshow="0"/>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="IMPP" suppressempty="yes" groupfield="GROUP_TAG">
<value field="IMPP"/>
<position field="IMPP" repeat="array" increment="1" minshow="0"/>
<parameter name="X-EVOLUTION-UI-SLOT" positional="no" show="no" rule="HAVE-EVOLUTION-UI-SLOT-IN-IMPP">
<value field="IMPP_SLOT"/>
</parameter>
<parameter name="X-SERVICE-TYPE" positional="no" show="no">
<value field="IMPP_SERVICE"/>
</parameter>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="X-AIM" suppressempty="yes" rule="KDE"/>
<property name="X-AIM" suppressempty="yes" rule="other">
@ -375,7 +413,7 @@
<value field="WANTS_HTML"/>
</property>
<property name="ADR" values="7">
<property name="ADR" values="7" groupfield="GROUP_TAG">
<value index="0" field="ADR_POBOX"/>
<value index="1" field="ADR_ADDTL"/>
<value index="2" field="ADR_STREET"/>
@ -391,8 +429,11 @@
<enum mode="ignore" value="B2"/> <!-- OTHER -->
</value>
</parameter>
<parameter name="X-ABLabel" rule="HAVE-ABLABEL-PARAMETER" sharedfield="yes">
<value field="LABEL"/>
</parameter>
</property>
<property name="BDAY" rule="EXTENDED-DATE-FORMAT">
<value field="BDAY" conversion="DATE+EXTFMT"/>
</property>
@ -419,6 +460,12 @@
<value index="1" field="GEO_LONG"/>
</property>
<!-- Label assigned to any of the repeating properties. -->
<property name="X-ABLabel" suppressempty="yes" groupfield="GROUP_TAG" rule="HAVE-ABLABEL-PROPERTY">
<value field="LABEL" repeat="array" increment="1" minshow="0"/>
<position field="LABEL" repeat="array" increment="1" minshow="1"/>
</property>
<property name="X-*" suppressempty="yes" show="false">
<value field="XPROPS"/>
<position field="XPROPS" repeat="array" increment="1" minshow="0"/>

View File

@ -0,0 +1,9 @@
<subrule name="HAVE-ABLABEL-PROPERTY">
<!-- property X-ABLabel is not generated by default,
must be enabled for peers which support it -->
</subrule>
<subrule name="HAVE-ABLABEL-PARAMETER">
<!-- parameter X-ABLabel is not generated by default,
must be enabled for peers which support it -->
</subrule>

View File

@ -1,5 +1,8 @@
<!-- parameter X-EVOLUTION-UI-SLOT is not generated by default,
must be enabled for peers which support it -->
<subrule name="HAVE-EVOLUTION-UI-SLOT">
<!-- parameter X-EVOLUTION-UI-SLOT is not generated by default,
must be enabled for peers which support it -->
</subrule>
<subrule name="HAVE-EVOLUTION-UI-SLOT-IN-IMPP">
</subrule>

View File

@ -6,8 +6,9 @@
<strictexecordering>no</strictexecordering>
<include rule="HAVE-SYNCEVOLUTION-EXDATE-DETACHED"/>
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
<include rule="HAVE-ABLABEL-PARAMETER"/>
<!-- Merging between SyncEvolution instances is expected to work
well, so allow the engine to update items on both
sides also in the "non-first" slow sync case.

View File

@ -1,5 +1,7 @@
<!-- rule which enables all optional properties and parameters -->
<!-- rule which enables all optional properties and parameters in the legacy format vCard -->
<remoterule name="ALL">
<deviceid>none - this rule is activated via its name in MAKE/PARSETEXTWITHPROFILE() macro calls</deviceid>
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
<include rule="HAVE-EVOLUTION-UI-SLOT-IN-IMPP"/>
<include rule="HAVE-ABLABEL-PARAMETER"/>
</remoterule>

View File

@ -1,6 +1,7 @@
<remoterule name="EVOLUTION">
<deviceid>none - this rule is activated via its name in MAKE/PARSETEXTWITHPROFILE() macro calls</deviceid>
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
<include rule="HAVE-ABLABEL-PARAMETER"/>
<!-- storing empty properties only wastes space and causes overhead, suppress them -->
<noemptyproperties>yes</noemptyproperties>
</remoterule>

View File

@ -4,6 +4,7 @@
<noemptyproperties>yes</noemptyproperties>
<!-- enable storing of X-EVOLUTION-UI-SLOT -->
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
<include rule="HAVE-ABLABEL-PARAMETER"/>
</remoterule>
<subrule name="HAVE-VCARD-UID">
@ -18,4 +19,5 @@
<!-- enable storing of X-EVOLUTION-UI-SLOT -->
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
<include rule="HAVE-VCARD-UID"/>
<include rule="HAVE-ABLABEL-PARAMETER"/>
</remoterule>

View File

@ -3,6 +3,237 @@
$VCARD_OUTGOING_PHOTO_VALUE_SCRIPT;
]]></macro>
<macro name="NEWTAG"><![CDATA[
INTEGER newtag;
newtag = 1;
while (TRUE) {
$1 = "item" + newtag;
if (!CONTAINS($2, $1)) {
break;
}
newtag = newtag + 1;
}
]]></macro>
<macro name="VCARD_AFTERREAD_SCRIPT"><![CDATA[
$VCARD_INCOMING_PHOTO_VALUE_SCRIPT;
]]></macro>
<!-- moves an IMPP value to a specific legacy field -->
<macro name="VCARD_MODERN_TO_LEGACY_IMPP"><![CDATA[
INTEGER impp_index;
impp_index = SIZE($2);
SWAP($1, $2[impp_index]);
SWAP(IMPP_SLOT[$4], $3[impp_index]);
IMPP[$4] = UNASSIGNED;
]]></macro>
<!-- convert from IMPP to X- fields, XDATE to ANNIVERSARY, etc. -->
<macro name="VCARD_MODERN_TO_LEGACY"><![CDATA[
INTEGER i;
STRING s;
// Special X-ABDATE -> X-ANNIVERSARY.
i = SIZE(XDATE) - 1;
while (i >= 0) {
if (GROUP_TAG[i] != EMPTY &&
XDATE[i] != UNASSIGNED &&
LABEL[i] == "Anniversary") {
SWAP(ANNIVERSARY, XDATE[i]);
// XDATE[i] = UNASSIGNED;
break;
}
i = i - 1;
}
// Special X-ABRELATEDNAMES -> X-SPOUSE/MANAGER/ASSISTANT
i = SIZE(RELATEDNAMES) - 1;
while (i >= 0) {
if (GROUP_TAG[i] != EMPTY &&
RELATEDNAMES[i] != UNASSIGNED) {
s = LABEL[i];
if (s == "Spouse") {
if (SPOUSE == EMPTY) {
SWAP(SPOUSE, RELATEDNAMES[i]);
// RELATEDNAMES[i] = UNASSIGNED;
}
} else if (s == "Manager") {
if (MANAGER == EMPTY) {
SWAP(MANAGER, RELATEDNAMES[i]);
// RELATEDNAMES[i] = UNASSIGNED;
}
} else if (s == "Assistant") {
if (ASSISTANT == EMPTY) {
SWAP(ASSISTANT, RELATEDNAMES[i]);
// RELATEDNAMES[i] = UNASSIGNED;
}
}
}
i = i - 1;
}
// IMPP -> X-JABBER/AIM/... depending on service type. Protocol must match.
i = SIZE(IMPP) - 1;
INTEGER offset;
STRING service;
STRING protocol;
STRING value;
while (i >= 0) {
service = IMPP_SERVICE[i];
if (service != UNASSIGNED) {
offset = FIND(IMPP[i], ":");
if (offset != UNASSIGNED) {
protocol = SUBSTR(IMPP[i], 0, offset);
value = URLDECODE(SUBSTR(IMPP[i], offset + 1));
if (service == "AIM" && protocol == "aim") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, AIM_HANDLE, AIM_SLOT, i);
} else if (service == "Gadugadu") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, GADUGADU_HANDLE, GADUGADU_SLOT, i);
} else if (service == "Groupwise") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, GROUPWISE_HANDLE, GROUPWISE_SLOT, i);
} else if (service == "ICQ" && protocol == "aim") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, ICQ_HANDLE, ICQ_SLOT, i);
} else if (service == "Jabber" && protocol == "xmpp") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, JABBER_HANDLE, JABBER_SLOT, i);
} else if (service == "MSN" && protocol == "msnim") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, MSN_HANDLE, MSN_SLOT, i);
} else if (service == "Yahoo" && protocol == "ymsgr") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, YAHOO_HANDLE, YAHOO_SLOT, i);
} else if (service == "Skype" && protocol == "skype") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, SKYPE_HANDLE, SKYPE_SLOT, i);
} else if (service == "Sip") {
$VCARD_MODERN_TO_LEGACY_IMPP(value, SIP_HANDLE, SIP_SLOT, i);
}
}
}
i = i - 1;
}
// Remove labels which are no longer needed (valued moved above,
// stored for a group which has no other properties (Google
// CardDAV server sometimes sends that, editing in Evolution
// might cause it, etc.) or provide no information ("Other").
i = SIZE(LABEL) - 1;
while (i >= 0) {
if (LABEL[i] == "Other" ||
LABEL[i] != UNASSIGNED &&
(GROUP_TAG[i] == EMPTY ||
RELATEDNAMES[i] == UNASSIGNED &&
XDATE[i] == UNASSIGNED &&
TEL[i] == UNASSIGNED &&
EMAIL[i] == UNASSIGNED &&
WEB[i] == UNASSIGNED &&
XDATE[i] == UNASSIGNED &&
IMPP[i] == UNASSIGNED &&
ADR_POBOX[i] == UNASSIGNED &&
ADR_ADDTL[i] == UNASSIGNED &&
ADR_STREET[i] == UNASSIGNED &&
ADR_CITY[i] == UNASSIGNED &&
ADR_REG[i] == UNASSIGNED &&
ADR_ZIP[i] == UNASSIGNED &&
ADR_COUNTRY[i] == UNASSIGNED &&
ADR_STREET_FLAGS[i] == UNASSIGNED)) {
LABEL[i] = UNASSIGNED;
}
i = i - 1;
}
// Remove all group tags. Not used for legacy formats.
GROUP_TAG = UNASSIGNED;
]]></macro>
<!-- X-SPOUSE/MANAGER/ASSISTANT -> special X-ABRELATEDNAMES -->
<macro name="VCARD_LEGACY_TO_MODERN_RELATEDNAMES"><![CDATA[
if ($1 != UNASSIGNED) {
// STRING tag;
INTEGER num;
num = SIZE(LABEL);
// $NEWTAG(tag, GROUP_TAG);
SWAP(RELATEDNAMES[num], $1);
LABEL[num] = $2;
// GROUP_TAG[num] = tag;
// $1 = UNASSIGNED;
}
]]></macro>
<!-- X-JABBER/AIM/... -> IMPP -->
<macro name="VCARD_LEGACY_TO_MODERN_IMPP"><![CDATA[
INTEGER impp_index;
impp_index = SIZE($3) - 1;
while (impp_index >= 0) {
if ($3[impp_index] != UNASSIGNED) {
INTEGER num;
num = SIZE(LABEL);
IMPP[num] = $2 + ":" + URLENCODE($3[impp_index]);
$3[impp_index] = UNASSIGNED;
SWAP($4[impp_index], IMPP_SLOT[num]);
IMPP_SERVICE[num] = $1;
LABEL[num] = "Other";
}
impp_index = impp_index - 1;
}
]]></macro>
<!-- convert from X- fields to IMPP, ANNIVERSARY to DATE, etc. -->
<macro name="VCARD_LEGACY_TO_MODERN"><![CDATA[
if (ANNIVERSARY != UNASSIGNED) {
INTEGER i;
i = SIZE(LABEL);
// STRING tag;
// $NEWTAG(tag, GROUP_TAG);
SWAP(XDATE[i], ANNIVERSARY);
LABEL[i] = "Anniversary";
// GROUP_TAG[i] = tag;
// ANNIVERSARY = UNASSIGNED;
}
$VCARD_LEGACY_TO_MODERN_RELATEDNAMES(SPOUSE, "Spouse");
$VCARD_LEGACY_TO_MODERN_RELATEDNAMES(MANAGER, "Manager");
$VCARD_LEGACY_TO_MODERN_RELATEDNAMES(ASSISTANT, "Assistant");
$VCARD_LEGACY_TO_MODERN_IMPP("AIM", "aim", AIM_HANDLE, AIM_SLOT);
$VCARD_LEGACY_TO_MODERN_IMPP("Gadugadu", "x-apple", GADUGADU_HANDLE, GADUGADU_SLOT); // ???
$VCARD_LEGACY_TO_MODERN_IMPP("Groupwise", "x-apple", GROUPWISE_HANDLE, GROUPWISE_SLOT); // ???
$VCARD_LEGACY_TO_MODERN_IMPP("ICQ", "aim", ICQ_HANDLE, ICQ_SLOT);
$VCARD_LEGACY_TO_MODERN_IMPP("Jabber", "xmpp", JABBER_HANDLE, JABBER_SLOT);
$VCARD_LEGACY_TO_MODERN_IMPP("MSN", "msnim", MSN_HANDLE, MSN_SLOT);
$VCARD_LEGACY_TO_MODERN_IMPP("Yahoo", "ymsgr", YAHOO_HANDLE, YAHOO_SLOT);
$VCARD_LEGACY_TO_MODERN_IMPP("Skype", "skype", SKYPE_HANDLE, SKYPE_SLOT);
$VCARD_LEGACY_TO_MODERN_IMPP("Sip", "x-apple", SIP_HANDLE, SIP_SLOT); // ???
// $VCARD_LEGACY_TO_MODERN_IMPP("???", "???", IM_ADDRESS);
// $VCARD_LEGACY_TO_MODERN_IMPP("???", "???", MEANWHILE_HANDLE, MEANWHILE_SLOT);
// $VCARD_LEGACY_TO_MODERN_IMPP("??", "???", SMS_HANDLE, SMS_SLOT);
// Create group tags for all labels. Without them the label won't be
// associated with the corresponding property in the modern vCard.
INTEGER i;
i = SIZE(LABEL) - 1;
// Reset GROUP_TAG. It might contain obsolete tags after
// a read/modify cycle.
GROUP_TAG = EMPTY;
// We don't use group tags internally, so we can simply enumerate them
// here.
INTEGER tagnum;
tagnum = 1;
while (i >= 0) {
if (LABEL[i] != UNASSIGNED) {
GROUP_TAG[i] = "item" + tagnum;
tagnum = tagnum + 1;
}
i = i - 1;
}
]]></macro>
<macro name="VCARD_BEFOREWRITE_SCRIPT_WEBDAV"><![CDATA[
$VCARD_BEFOREWRITE_SCRIPT;
$VCARD_LEGACY_TO_MODERN;
]]></macro>
<macro name="VCARD_AFTERREAD_SCRIPT_WEBDAV"><![CDATA[
$VCARD_MODERN_TO_LEGACY;
$VCARD_AFTERREAD_SCRIPT;
]]></macro>

View File

@ -1676,7 +1676,7 @@ test = SyncEvolutionTest("googlecontacts", compile,
"", options.shell,
"Client::Sync::eds_contact::testItems Client::Source::google_carddav",
[ "google_carddav", "eds_contact" ],
"CLIENT_TEST_WEBDAV='google carddav testcases=testcases/eds_contact.vcf' "
"CLIENT_TEST_WEBDAV='google carddav' "
"CLIENT_TEST_NUM_ITEMS=10 " # don't stress server
"CLIENT_TEST_MODE=server " # for Client::Sync
"CLIENT_TEST_FAILURES="

View File

@ -467,14 +467,9 @@ sub NormalizeItem {
s/^FN:.*\n/FN$1: [...]\n/mg;
}
if ($googlecarddav) {
# Adds .X-ABLabel to URL, TEL, etc. to represent custom
# labels. TODO: support that in SyncEvolution
s/^.*\.X-ABLabel(;[^:;\n]*)*:.*\r?\n?//mg;
# Ignore groups. TODO: support that in SyncEvolution.
s/^[a-zA-Z0-9]+\.//mg;
}
# Properties and parameters are case-insensitive. ownCloud uses
# X-ABLABEL while everyone else uses X-ABLabel.
s/X-ABLABEL/X-ABLabel/g;
if ($googlesyncml) {
# Not support car type in telephone

View File

@ -4635,80 +4635,72 @@ FN:John Doe
N:Doe;John
ORG:Test Inc.
END:VCARD'''
johnComplexVCard = '''BEGIN:VCARD
# The data must be stored exactly as generated by the Synthesis engine.
# Otherwise we risk that parsing it directly and comparing against
# an item data that first went through a parsing/generating step
# will find irrelevant differences, which breaks the tests which assume
# that client and server already have the same data.
#
# Perhaps a better solution would be to not create the data on the client
# directly and instead create it via syncing.
johnComplexVCard = r'''BEGIN:VCARD
VERSION:3.0
URL:http://john.doe.com
TITLE:Senior Tester
ORG:Test Inc.;Testing;test#1
ROLE:professional test case
X-EVOLUTION-MANAGER:John Doe Senior
X-EVOLUTION-ASSISTANT:John Doe Junior
NICKNAME:user1
BDAY:2006-01-08
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test\; never sent to a peer
X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Content with\nMultiple\nText lines\nand national chars: äöü
X-EVOLUTION-ANNIVERSARY:2006-01-09
X-EVOLUTION-SPOUSE:Joan Doe
NOTE:This is a test case which uses almost all Evolution fields.
FN:John Doe
PRODID:-//Synthesis AG//NONSGML SyncML Engine V3.4.0.47//EN
REV:20100328T103410Z
N:Doe;John;;;
FN:John Doe
X-EVOLUTION-FILE-AS:Doe\, John
X-GENDER:
NICKNAME:user1
TITLE:Senior Tester
CATEGORIES:TEST
X-EVOLUTION-BLOG-URL:web log
CALURI:calender
FBURL:free/busy
X-EVOLUTION-VIDEO-URL:chat
X-MOZILLA-HTML:TRUE
ADR;TYPE=WORK:Test Box #2;;Test Drive 2;Test Town;Upper Test County;12346;O
ld Testovia
LABEL;TYPE=WORK:Test Drive 2\nTest Town\, Upper Test County\n12346\nTest Bo
x #2\nOld Testovia
ADR;TYPE=HOME:Test Box #1;;Test Drive 1;Test Village;Lower Test County;1234
5;Testovia
LABEL;TYPE=HOME:Test Drive 1\nTest Village\, Lower Test County\n12345\nTest
Box #1\nTestovia
ADR:Test Box #3;;Test Drive 3;Test Megacity;Test County;12347;New Testonia
LABEL;TYPE=OTHER:Test Drive 3\nTest Megacity\, Test County\n12347\nTest Box
#3\nNew Testonia
UID:pas-id-43C0ED3900000001
EMAIL;TYPE=WORK;X-EVOLUTION-UI-SLOT=1:john.doe@work.com
EMAIL;TYPE=HOME;X-EVOLUTION-UI-SLOT=2:john.doe@home.priv
EMAIL;TYPE=OTHER;X-EVOLUTION-UI-SLOT=3:john.doe@other.world
EMAIL;TYPE=OTHER;X-EVOLUTION-UI-SLOT=4:john.doe@yet.another.world
TEL;TYPE=work;TYPE=Voice;X-EVOLUTION-UI-SLOT=1:business 1
TEL;TYPE=homE;TYPE=VOICE;X-EVOLUTION-UI-SLOT=2:home 2
ORG:Test Inc.;Testing;test#1;
ROLE:professional test case
TEL;TYPE=WORK,VOICE;X-EVOLUTION-UI-SLOT=1:business 1
TEL;TYPE=HOME,VOICE;X-EVOLUTION-UI-SLOT=2:home 2
TEL;TYPE=CELL;X-EVOLUTION-UI-SLOT=3:mobile 3
TEL;TYPE=WORK;TYPE=FAX;X-EVOLUTION-UI-SLOT=4:businessfax 4
TEL;TYPE=HOME;TYPE=FAX;X-EVOLUTION-UI-SLOT=5:homefax 5
TEL;TYPE=WORK,FAX;X-EVOLUTION-UI-SLOT=4:businessfax 4
TEL;TYPE=HOME,FAX;X-EVOLUTION-UI-SLOT=5:homefax 5
TEL;TYPE=PAGER;X-EVOLUTION-UI-SLOT=6:pager 6
TEL;TYPE=CAR;X-EVOLUTION-UI-SLOT=7:car 7
TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 8
EMAIL;TYPE=WORK;X-EVOLUTION-UI-SLOT=1:john.doe@work.com
EMAIL;TYPE=HOME;X-EVOLUTION-UI-SLOT=2:john.doe@home.priv
EMAIL;X-EVOLUTION-UI-SLOT=3:john.doe@other.world
EMAIL;X-EVOLUTION-UI-SLOT=4:john.doe@yet.another.world
URL:http://john.doe.com
CALURI:calender
FBURL:free/busy
X-EVOLUTION-BLOG-URL:web log
X-EVOLUTION-VIDEO-URL:chat
X-EVOLUTION-MANAGER:John Doe Senior
X-MANAGER:John Doe Senior
X-EVOLUTION-ASSISTANT:John Doe Junior
X-ASSISTANT:John Doe Junior
X-EVOLUTION-SPOUSE:Joan Doe
X-SPOUSE:Joan Doe
X-EVOLUTION-ANNIVERSARY:20060109
X-ANNIVERSARY:20060109
X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
X-GROUPWISE;X-EVOLUTION-UI-SLOT=4:GROUPWISE DOE
X-GADUGADU:GADUGADU DOE
X-GROUPWISE;X-EVOLUTION-UI-SLOT=4:GROUPWISE DOE
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
X-JABBER:JABBER DOE
X-MSN:MSN DOE
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
X-SKYPE:SKYPE DOE
X-SIP:SIP DOE
PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAA
AAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcM
CAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEF
BQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
Hh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgE
Bf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/
xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR
AD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2V
fmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2um
hWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJ
YV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUk
GZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2
JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0Dth
VFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z
/VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==
END:VCARD
'''
X-MOZILLA-HTML:TRUE
ADR;TYPE=WORK:Test Box #2;;Test Drive 2;Test Town;Upper Test County;12346;Old Testovia
ADR;TYPE=HOME:Test Box #1;;Test Drive 1;Test Village;Lower Test County;12345;Testovia
ADR:Test Box #3;;Test Drive 3;Test Megacity;Test County;12347;New Testonia
BDAY:20060108
NOTE:This is a test case which uses almost all Evolution fields.
PHOTO;TYPE=JPEG;ENCODING=B:/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcMCAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEFBQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgEBf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2VfmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2umhWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJYV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUkGZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0DthVFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z/VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==
GEO:;
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test\; never sent to a peer
X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Content with\nMultiple\nText lines\nand national chars: äöü
END:VCARD'''
joanVCard = '''BEGIN:VCARD
VERSION:3.0
FN:Joan Doe

View File

@ -24,6 +24,7 @@ dist_noinst_DATA += \
test/testcases/eds_event.ics.local \
test/testcases/eds_task.ics \
test/testcases/vcal10.ics \
test/testcases/carddav.vcf \
test/testcases/eds_contact.vcf \
test/testcases/eds_memo.ics \
test/testcases/google_event.ics \

483
test/testcases/carddav.vcf Normal file
View File

@ -0,0 +1,483 @@
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user17
NICKNAME:user17
NOTE:triggers parser bug in Funambol 3.0: trailing = is mistaken for soft line break=
FN:parserbug=
N:parserbug=;;;;
X-EVOLUTION-FILE-AS:parserbug=
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user16
NICKNAME:user16
NOTE:test case with empty email
FN:incomplete
N:incomplete;;;;
EMAIL:
X-EVOLUTION-FILE-AS:incomplete
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user11
NICKNAME:user11
NOTE:This is a long line without any special characters. This is a simpler
example that should require folding in vcards. Does folding insert a crlf
before a space or does it insert crlf _plus_ a space? vCard 2.1 inserts
before a space\, 3.0 inserts line break plus space.
FN:long line
N:line;long;;;
X-EVOLUTION-FILE-AS:line\, long
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user12
NICKNAME:user12
NOTE:ampersand entity &amp\; less-than entity &lt\;
FN:xml entities
N:xml;entities;;;
X-EVOLUTION-FILE-AS:xml\, entities
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user13
NICKNAME:user13
NOTE:a colon is not a special character so here it comes : and not quoting necessary
FN:colon
N:colon;unquoted;;;
X-EVOLUTION-FILE-AS:colon\, unquoted
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user14
NICKNAME:user14
NOTE:here are some quotation marks: single ' double " back ` - none of them is special
FN:quotation marks
N:marks;quotation;;;
X-EVOLUTION-FILE-AS:marks\, quotation
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user15
NICKNAME:user15
NOTE:Spouse's Name: foobar
FN:spouse name
N:name;spouse;;;
X-EVOLUTION-FILE-AS:spouse\, name
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user9
NICKNAME:user9
NOTE;CHARSET="UTF-8":Tests charset specification with quotation marks.
FN:charset
N:set;char;;;
X-EVOLUTION-FILE-AS:set\, char
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user2
NICKNAME:user2
X-EVOLUTION-SPOUSE:
NOTE:This user tests some of the advanced aspects of vcards:\n- non-ASCII c
haracters (with umlauts in the name)\n- line break (in this note and the
mailing address)\n- long lines (in this note)\n- special characters (in
this note)\n- tabs (in this note)\n\nVery long line\, very very long th
is time... still not finished... blah blah blah blah blah 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15 16\n\ncomma \,\ncolon :\nsemicolon \;\nbackslash
\\\n\nThe same\, in the middle of a line:\ncomma \, comma\ncolon : col
on\nsemicolon \; semicolon\nbackslash \\ backslash\n\nA tab tab done\n
line starts with tab
FN:Umlaut Ä Ö Ü ß
N:Ü;Ä;Ö;Umlaut;ß
X-EVOLUTION-FILE-AS:Ü\, Ä
CATEGORIES:Business
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
ADR;TYPE=HOME:test 5;Line 2;Umlaut Ä in Line 1;test 1;test 3;test 2;test 4
LABEL;TYPE=HOME:Umlaut Ä in Line 1\nLine 2\n\ntest 1\, test 3\ntest 2\ntest 5\ntest 4
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user8
NICKNAME:user8
X-EVOLUTION-SPOUSE:
NOTE:Here are some special characters: comma \, colon : semicolon \;
FN:special characters
N:characters;special;;;
X-EVOLUTION-FILE-AS:characters\, special
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user7
NICKNAME:user7
X-EVOLUTION-SPOUSE:
NOTE:This test case uses line breaks. This is line 1.\nLine 2.\n\nLine brea
ks in vcard 2.1 are encoded as =0D=0A.\nThat means the = has to be encod
ed itself...
FN:line breaks
N:breaks;line;;;
X-EVOLUTION-FILE-AS:breaks\, line
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
ADR;TYPE=HOME:;Address Line 2\nAddress Line 3;Address Line 1;;;;
LABEL;TYPE=HOME:Address Line 1\nAddress Line 2\nAddress Line 3
END:VCARD
BEGIN:VCARD
VERSION:3.0
N:Doe;John;1;Mr.;Sr.
FN:Mr. John 1 Doe Sr.
NICKNAME:user1
TITLE:tester
ORG:at company
REV:2014-04-11T08:43:42Z
UID:6f354d698b7ccd22
BDAY;VALUE=DATE:1970-12-30
ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country
ADR;TYPE=WORK:;;work address;;;;
ADR:;;custom address;;;;
TEL;TYPE=WORK:business 1
TEL;TYPE=CELL:mobile
TEL;TYPE=HOME:home
TEL:main
TEL;TYPE=FAX,WORK:work fax
TEL;TYPE=FAX,HOME:home fax
item14.TEL:google voice
TEL;TYPE=PAGER:pager
item15.TEL:custom
EMAIL;TYPE=HOME,PREF:john.doe@home.com
EMAIL;TYPE=WORK:doe@work.com
item2.EMAIL:john@custom.com
NOTE:A test contact.
PHOTO;ENCODING=b;TYPE=PNG:iVBORw0KGgoAAAANSUhEUgAAACQAAAAXCAYAAABj7u2bAAAAB
mJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gEICjgdiWkBO
QAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu
0tcURAG8F98gRKTYGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWP
sAU6wPxHW6aWbgsu+ve3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6TH
lejbWSt0Bv8QBXX2MF7jKU4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkF
jQX9g5e4ykGUcBm+FaDexx2MUQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOc
BHcEv7FvyN8xxqmeynovA1Baf4UVvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdN
owXWEQlOBXMYyI4j3EavqFUzpOYl4OTqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV
8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6Bb/Ae0cnahfg6KuAAAAAElFTkSuQmCC
IMPP;X-SERVICE-TYPE=GoogleTalk:xmpp:google%20talk
IMPP;X-SERVICE-TYPE=AIM:aim:aim
IMPP;X-SERVICE-TYPE=Yahoo:ymsgr:yahoo
IMPP;X-SERVICE-TYPE=Skype:skype:skype
IMPP;X-SERVICE-TYPE=QQ:x-apple:QQ
IMPP;X-SERVICE-TYPE=MSN:msnim:MSN
IMPP;X-SERVICE-TYPE=ICQ:aim:ICQ
IMPP;X-SERVICE-TYPE=Jabber:xmpp:Jabber
IMPP;X-SERVICE-TYPE=chat-label:x-apple:custom%20chat
X-EVOLUTION-FILE-AS:Doe\, John
X-MOZILLA-HTML:FALSE
X-PHONETIC-FIRST-NAME:John
X-PHONETIC-LAST-NAME:Doe
item2.X-ABLabel:custom-label2
item3.X-ABDATE:1971-01-01
item3.X-ABLabel:Anniversary
item4.X-ABDATE:2000-02-01
item4.X-ABLabel:custom-label3
item14.X-ABLabel:Google Voice
item15.X-ABLabel:custom-label4
item16.X-ABRELATEDNAMES:spouse
item16.X-ABLabel:Spouse
item17.X-ABRELATEDNAMES:child
item17.X-ABLabel:Child
item18.X-ABRELATEDNAMES:mother
item18.X-ABLabel:Mother
item19.X-ABRELATEDNAMES:father
item19.X-ABLabel:Father
item20.X-ABRELATEDNAMES:parent
item20.X-ABLabel:Parent
item21.X-ABRELATEDNAMES:brother
item21.X-ABLabel:Brother
item22.X-ABRELATEDNAMES:sister
item22.X-ABLabel:Sister
item23.X-ABRELATEDNAMES:friend
item23.X-ABLabel:Friend
item24.X-ABRELATEDNAMES:relative
item24.X-ABLabel:relative
item25.X-ABRELATEDNAMES:manager
item25.X-ABLabel:Manager
item26.X-ABRELATEDNAMES:assistant
item26.X-ABLabel:Assistant
item27.X-ABRELATEDNAMES:referred-by
item27.X-ABLabel:referred-by-label
item28.X-ABRELATEDNAMES:partner
item28.X-ABLabel:Partner
item29.X-ABRELATEDNAMES:domestic partner
item29.X-ABLabel:domestic-partner-label
item30.X-ABRELATEDNAMES:custom relationship
item30.X-ABLabel:custom-label5
item31.URL:http://profile.com
item31.X-ABLabel:Profile
item32.URL:http://blog.com
item32.X-ABLabel:Blog
item33.URL:http://homepage.com
item33.X-ABLabel:HomePage
item34.URL:http://company.com
item34.X-ABLabel:Work
item35.URL:http://custom.com
item35.X-ABLabel:Custom-label6
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user5
NICKNAME:user5
X-EVOLUTION-SPOUSE:
NOTE:image in JPG format
FN:Ms. JPG
N:;JPG;;Ms.;
X-EVOLUTION-FILE-AS:JPG
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAA
AAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcM
CAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEF
BQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
Hh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgE
Bf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/
xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR
AD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2V
fmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2um
hWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJ
YV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUk
GZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2
JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0Dth
VFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z
/VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user4
NICKNAME:user4
X-EVOLUTION-SPOUSE:
NOTE:image in PNG format
FN:Mrs. PNG
N:;PNG;;Mrs.;
X-EVOLUTION-FILE-AS:PNG
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
PHOTO;ENCODING=b;TYPE=PNG:iVBORw0KGgoAAAANSUhEUgAAACQAAAAXCAYAAABj7u2bAAAAB
mJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gEICjgdiWkBO
QAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu
0tcURAG8F98gRKTYGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWP
sAU6wPxHW6aWbgsu+ve3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6TH
lejbWSt0Bv8QBXX2MF7jKU4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkF
jQX9g5e4ykGUcBm+FaDexx2MUQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOc
BHcEv7FvyN8xxqmeynovA1Baf4UVvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdN
owXWEQlOBXMYyI4j3EavqFUzpOYl4OTqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV
8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6Bb/Ae0cnahfg6KuAAAAAElFTkSuQmCC
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user6
NICKNAME:user6
X-EVOLUTION-SPOUSE:
NOTE:The first name is "First \; special \;".
FN:Mr. First \; special \; middle Last
N:Last;First \; special \;;middle;Mr.;
X-EVOLUTION-FILE-AS:Last\, First \; special \;
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
END:VCARD
BEGIN:VCARD
VERSION:3.0
URL:
TITLE:
ROLE:
X-EVOLUTION-MANAGER:
X-EVOLUTION-ASSISTANT:
UID:unique-id-user3
NICKNAME:user3
X-EVOLUTION-SPOUSE:
NOTE:image in GIF format
FN:Mr. GIF
N:;GIF;;Mr.;
X-EVOLUTION-FILE-AS:GIF
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
X-EVOLUTION-VIDEO-URL:
X-MOZILLA-HTML:FALSE
PHOTO;ENCODING=b;TYPE=GIF:R0lGODlhJAAXAIABAAAAAP///yH+FUNyZWF0ZWQgd2l0aCBUa
GUgR0lNUAAh+QQBCgABACwAAAAAJAAXAAACVYyPqcvtD6OctNqLFdi8b/sd3giAJRNmqXaKH
TIaZJKSpx3McLtyeSuTAWm34e+4WBGFuJ/P1QjZek9ksjiRGqFCTW5pZblmzdiO+GJWncqM+
w2PwwsAOw==
END:VCARD
BEGIN:VCARD
VERSION:3.0
UID:unique-id-user10
NICKNAME:user10
X-EVOLUTION-SPOUSE:
NOTE:large vcard with plenty of special chars < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
& < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
FN:large vcard
N:;vcard;;large;
X-EVOLUTION-FILE-AS:large
END:VCARD

View File

@ -0,0 +1,225 @@
@@ -2,7 +2,7 @@
VERSION:3.0
UID:unique-id-user17
NICKNAME:user17
-NOTE:triggers parser bug in Funambol 3.0: trailing = is mistaken for soft line break=
+NOTE:triggers parser bug in Funambol 3.0\: trailing= is mistaken for soft line break=
FN:parserbug=
N:parserbug=;;;;
X-EVOLUTION-FILE-AS:parserbug=
@@ -24,9 +24,7 @@
UID:unique-id-user11
NICKNAME:user11
NOTE:This is a long line without any special characters. This is a simpler
- example that should require folding in vcards. Does folding insert a crlf
- before a space or does it insert crlf _plus_ a space? vCard 2.1 inserts
- before a space\, 3.0 inserts line break plus space.
+ example that should require folding in vcards. ...
FN:long line
N:line;long;;;
X-EVOLUTION-FILE-AS:line\, long
@@ -46,7 +44,7 @@
VERSION:3.0
UID:unique-id-user13
NICKNAME:user13
-NOTE:a colon is not a special character so here it comes : and not quoting necessary
+NOTE:a colon is not a special character so here it comes \: and not quotingnecessary
FN:colon
N:colon;unquoted;;;
X-EVOLUTION-FILE-AS:colon\, unquoted
@@ -56,7 +54,7 @@
VERSION:3.0
UID:unique-id-user14
NICKNAME:user14
-NOTE:here are some quotation marks: single ' double " back ` - none of them is special
+NOTE:here are some quotation marks\: single ' double " back ` - none of them is special
FN:quotation marks
N:marks;quotation;;;
X-EVOLUTION-FILE-AS:marks\, quotation
@@ -66,7 +64,7 @@
VERSION:3.0
UID:unique-id-user15
NICKNAME:user15
-NOTE:Spouse's Name: foobar
+NOTE:Spouse's Name\: foobar
FN:spouse name
N:name;spouse;;;
X-EVOLUTION-FILE-AS:spouse\, name
@@ -92,19 +90,10 @@
UID:unique-id-user2
NICKNAME:user2
X-EVOLUTION-SPOUSE:
-NOTE:This user tests some of the advanced aspects of vcards:\n- non-ASCII c
- haracters (with umlauts in the name)\n- line break (in this note and the
- mailing address)\n- long lines (in this note)\n- special characters (in
- this note)\n- tabs (in this note)\n\nVery long line\, very very long th
- is time... still not finished... blah blah blah blah blah 1 2 3 4 5 6 7
- 8 9 10 11 12 13 14 15 16\n\ncomma \,\ncolon :\nsemicolon \;\nbackslash
- \\\n\nThe same\, in the middle of a line:\ncomma \, comma\ncolon : col
- on\nsemicolon \; semicolon\nbackslash \\ backslash\n\nA tab tab done\n
- line starts with tab
+NOTE:This user tests some of the advanced aspects of vcards...
FN:Umlaut Ä Ö Ü ß
N:Ü;Ä;Ö;Umlaut;ß
X-EVOLUTION-FILE-AS:Ü\, Ä
-CATEGORIES:Business
X-EVOLUTION-BLOG-URL:
CALURI:
FBURL:
@@ -124,7 +113,7 @@
UID:unique-id-user8
NICKNAME:user8
X-EVOLUTION-SPOUSE:
-NOTE:Here are some special characters: comma \, colon : semicolon \;
+NOTE:Here are some special characters\: comma \, colon \: semicolon \;
FN:special characters
N:characters;special;;;
X-EVOLUTION-FILE-AS:characters\, special
@@ -146,7 +135,7 @@
NICKNAME:user7
X-EVOLUTION-SPOUSE:
NOTE:This test case uses line breaks. This is line 1.\nLine 2.\n\nLine brea
- ks in vcard 2.1 are encoded as =0D=0A.\nThat means the = has to be encod
+ ks in vcard 2.1 are encoded as=0D=0A.\nThat means the= has to be encod
ed itself...
FN:line breaks
N:breaks;line;;;
@@ -204,7 +193,7 @@
IMPP;X-SERVICE-TYPE=MSN:msnim:MSN
IMPP;X-SERVICE-TYPE=ICQ:aim:ICQ
IMPP;X-SERVICE-TYPE=Jabber:xmpp:Jabber
-IMPP;X-SERVICE-TYPE=chat-label:x-apple:custom%20chat
+IMPP;X-SERVICE-TYPE=Chat-label:x-apple:custom%20chat
X-EVOLUTION-FILE-AS:Doe\, John
X-MOZILLA-HTML:FALSE
X-PHONETIC-FIRST-NAME:John
@@ -246,15 +235,15 @@
item29.X-ABLabel:domestic-partner-label
item30.X-ABRELATEDNAMES:custom relationship
item30.X-ABLabel:custom-label5
-item31.URL:http://profile.com
+item31.URL:http\://profile.com
item31.X-ABLabel:Profile
-item32.URL:http://blog.com
+item32.URL:http\://blog.com
item32.X-ABLabel:Blog
-item33.URL:http://homepage.com
+item33.URL:http\://homepage.com
item33.X-ABLabel:HomePage
-item34.URL:http://company.com
+item34.URL:http\://company.com
item34.X-ABLabel:Work
-item35.URL:http://custom.com
+item35.URL:http\://custom.com
item35.X-ABLabel:Custom-label6
END:VCARD
@@ -376,107 +365,7 @@
UID:unique-id-user10
NICKNAME:user10
X-EVOLUTION-SPOUSE:
-NOTE:large vcard with plenty of special chars < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
- & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <
+NOTE:large vcard with plenty of special chars < &...
FN:large vcard
N:;vcard;;large;
X-EVOLUTION-FILE-AS:large