summaryrefslogtreecommitdiff
path: root/library/backend/vobject.cpp
Unidiff
Diffstat (limited to 'library/backend/vobject.cpp') (more/less context) (show whitespace changes)
-rw-r--r--library/backend/vobject.cpp104
1 files changed, 100 insertions, 4 deletions
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 9c2ba3b..e6f6b78 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -1005,19 +1005,94 @@ static int writeBase64(OFile *fp, unsigned char *s, long len)
1005 return 1; 1005 return 1;
1006} 1006}
1007 1007
1008static const char *replaceChar(unsigned char c)
1009{
1010 if (c == '\n') {
1011 return "=0A=\n";
1012 } else if (
1013 (c >= 'A' && c <= 'Z')
1014 ||
1015 (c >= 'a' && c <= 'z')
1016 ||
1017 (c >= '0' && c <= '9')
1018 ||
1019 (c >= '\'' && c <= ')')
1020 ||
1021 (c >= '+' && c <= '-')
1022 ||
1023 (c == '/')
1024 ||
1025 (c == '?')
1026 ||
1027 (c == ' '))
1028 {
1029 return 0;
1030 }
1031
1032 static char trans[4];
1033 trans[0] = '=';
1034 trans[3] = '\0';
1035 int rem = c % 16;
1036 int div = c / 16;
1037
1038 if (div < 10)
1039 trans[1] = '0' + div;
1040 else
1041 trans[1] = 'A' + (div - 10);
1042
1043 if (rem < 10)
1044 trans[2] = '0' + rem;
1045 else
1046 trans[2] = 'A' + (rem - 10);
1047
1048 return trans;
1049}
1050
1008static void writeQPString(OFile *fp, const char *s) 1051static void writeQPString(OFile *fp, const char *s)
1009{ 1052{
1053 /*
1054 only A-Z, 0-9 and
1055 "'" (ASCII code 39)
1056 "(" (ASCII code 40)
1057 ")" (ASCII code 41)
1058 "+" (ASCII code 43)
1059 "," (ASCII code 44)
1060 "-" (ASCII code 45)
1061 "/" (ASCII code 47)
1062 "?" (ASCII code 63)
1063
1064 should remain un-encoded.
1065 '=' needs to be encoded as it is the escape character.
1066 ';' needs to be as it is a field separator.
1067
1068 */
1010 const char *p = s; 1069 const char *p = s;
1011 while (*p) { 1070 while (*p) {
1012 if (*p == '\n') { 1071 const char *rep = replaceChar(*p);
1013 if (p[1]) appendsOFile(fp,"=0A="); 1072 if (rep)
1014 } 1073 appendsOFile(fp, rep);
1074 else
1015 appendcOFile(fp,*p); 1075 appendcOFile(fp,*p);
1016 p++; 1076 p++;
1017 } 1077 }
1018} 1078}
1019 1079
1020 1080static bool includesUnprintable(VObject *o)
1081{
1082 if (o) {
1083 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
1084 const char *p = STRINGZ_VALUE_OF(o);
1085 if (p) {
1086 while (*p) {
1087 if (replaceChar(*p))
1088 return TRUE;
1089 p++;
1090 }
1091 }
1092 }
1093 }
1094 return FALSE;
1095}
1021 1096
1022static void writeVObject_(OFile *fp, VObject *o); 1097static void writeVObject_(OFile *fp, VObject *o);
1023 1098
@@ -1059,6 +1134,10 @@ static void writeAttrValue(OFile *fp, VObject *o)
1059 struct PreDefProp *pi; 1134 struct PreDefProp *pi;
1060 pi = lookupPropInfo(NAME_OF(o)); 1135 pi = lookupPropInfo(NAME_OF(o));
1061 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1136 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1137 if ( includesUnprintable(o) ) {
1138 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
1139 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1140 }
1062 appendcOFile(fp,';'); 1141 appendcOFile(fp,';');
1063 appendsOFile(fp,NAME_OF(o)); 1142 appendsOFile(fp,NAME_OF(o));
1064 } 1143 }
@@ -1122,6 +1201,18 @@ static void writeProp(OFile *fp, VObject *o)
1122 int i = 0, n = 0; 1201 int i = 0, n = 0;
1123 const char** fields = fields_; 1202 const char** fields = fields_;
1124 /* output prop as fields */ 1203 /* output prop as fields */
1204 bool printable = TRUE;
1205 while (*fields && printable) {
1206 VObject *t = isAPropertyOf(o,*fields);
1207 if (includesUnprintable(t))
1208 printable = FALSE;
1209 fields++;
1210 }
1211 fields = fields_;
1212 if (!printable) {
1213 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
1214 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1215 }
1125 appendcOFile(fp,':'); 1216 appendcOFile(fp,':');
1126 while (*fields) { 1217 while (*fields) {
1127 VObject *t = isAPropertyOf(o,*fields); 1218 VObject *t = isAPropertyOf(o,*fields);
@@ -1138,7 +1229,12 @@ static void writeProp(OFile *fp, VObject *o)
1138 } 1229 }
1139 } 1230 }
1140 1231
1232
1141 if (VALUE_TYPE(o)) { 1233 if (VALUE_TYPE(o)) {
1234 if ( includesUnprintable(o) ) {
1235 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
1236 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1237 }
1142 unsigned long size = 0; 1238 unsigned long size = 0;
1143 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1239 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1144 if (p) size = LONG_VALUE_OF(p); 1240 if (p) size = LONG_VALUE_OF(p);