comparison src/readpst.c @ 407:24871e6cdd69

Stuart C. Naifeh - fix rfc2231 encoding when saving messages to both .eml and msg formats
author Carl Byington <carl@five-ten-sg.com>
date Sat, 27 Mar 2021 14:53:01 -0700
parents c1b1bbd42696
children
comparison
equal deleted inserted replaced
406:7200790e46ac 407:24871e6cdd69
1177 } 1177 }
1178 *curr_out = '\0'; 1178 *curr_out = '\0';
1179 return res; 1179 return res;
1180 } 1180 }
1181 1181
1182 /** Convert inp to rfc2231 encoding of string
1183 *
1184 * @param inp pointer to the string of interest
1185 * @return pointer to converted string -- caller must free
1186 */
1187 char *rfc2231_string(char *inp) {
1188 int needs = 0;
1189 const int8_t *x = (int8_t *)inp;
1190 while (*x) {
1191 if (*x <= 32) needs++;
1192 x++;
1193 }
1194 int n = strlen(inp) + 2*needs + 15;
1195 char *buffer = pst_malloc(n);
1196 strcpy(buffer, "utf-8''");
1197 x = (int8_t *)inp;
1198 const uint8_t *y = (uint8_t *)inp;
1199 uint8_t *z = (uint8_t *)buffer;
1200 z += strlen(buffer); // skip the utf8 prefix
1201 while (*y) {
1202 if (*x <= 32) {
1203 *(z++) = (uint8_t)'%';
1204 snprintf(z, 3, "%2x", *y);
1205 z += 2;
1206 }
1207 else {
1208 *(z++) = *y;
1209 }
1210 x++;
1211 y++;
1212 }
1213 *z = '\0';
1214 return buffer;
1215 }
1216
1182 void write_inline_attachment(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pst) 1217 void write_inline_attachment(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pst)
1183 { 1218 {
1184 DEBUG_ENT("write_inline_attachment"); 1219 DEBUG_ENT("write_inline_attachment");
1185 DEBUG_INFO(("Attachment Size is %#"PRIx64", data = %#"PRIxPTR", id %#"PRIx64"\n", (uint64_t)attach->data.size, attach->data.data, attach->i_id)); 1220 DEBUG_INFO(("Attachment Size is %#"PRIx64", data = %#"PRIxPTR", id %#"PRIx64"\n", (uint64_t)attach->data.size, attach->data.data, attach->i_id));
1186 1221
1208 1243
1209 if (attach->filename2.str) { 1244 if (attach->filename2.str) {
1210 // use the long filename, converted to proper encoding if needed. 1245 // use the long filename, converted to proper encoding if needed.
1211 // it is already utf8 1246 // it is already utf8
1212 char *escaped = quote_string(attach->filename2.str); 1247 char *escaped = quote_string(attach->filename2.str);
1213 pst_rfc2231(&attach->filename2); 1248 // encode long filename as rfc2231 without modifying original -- we may still need the original long filename
1214 fprintf(f_output, "Content-Disposition: attachment; \n filename*=%s;\n", attach->filename2.str); 1249 char *rfc2231 = rfc2231_string(attach->filename2.str);
1250 fprintf(f_output, "Content-Disposition: attachment; \n filename*=%s;\n", rfc2231);
1251 free (rfc2231);
1215 // Also include the (escaped) utf8 filename in the 'filename' header directly - this is not strictly valid 1252 // Also include the (escaped) utf8 filename in the 'filename' header directly - this is not strictly valid
1216 // (since this header should be ASCII) but is almost always handled correctly (and in fact this is the only 1253 // (since this header should be ASCII) but is almost always handled correctly (and in fact this is the only
1217 // way to get MS Outlook to correctly read a UTF8 filename, AFAICT, which is why we're doing it). 1254 // way to get MS Outlook to correctly read a UTF8 filename, AFAICT, which is why we're doing it).
1218 fprintf(f_output, " filename=\"%s\"\n\n", escaped); 1255 fprintf(f_output, " filename=\"%s\"\n\n", escaped);
1219 free(escaped); 1256 free(escaped);