*
* This is the MIME parser for Citadel. Sometimes it actually works.
*
- * Copyright (c) 1998-2001 by Art Cancro
+ * Copyright (c) 1998-2003 by Art Cancro
* This code is distributed under the terms of the GNU General Public License.
*
*/
-#ifdef DLL_EXPORT
-#define IN_LIBCIT
-#endif
#include <stdlib.h>
#include <unistd.h>
size_t content_length;
char *encoding;
char *disposition;
- char *name;
+ char *name = NULL;
+ char *content_type_name;
+ char *content_disposition_name;
char *filename;
int is_multipart;
int part_seq = 0;
encoding = mallok(SIZ);
memset(encoding, 0, SIZ);
- name = mallok(SIZ);
- memset(name, 0, SIZ);
+ content_type_name = mallok(SIZ);
+ memset(content_type_name, 0, SIZ);
+
+ content_disposition_name = mallok(SIZ);
+ memset(content_disposition_name, 0, SIZ);
filename = mallok(SIZ);
memset(filename, 0, SIZ);
if (!isspace(buf[0])) {
if (!strncasecmp(header, "Content-type: ", 14)) {
strcpy(content_type, &header[14]);
- extract_key(name, content_type, "name");
+ extract_key(content_type_name, content_type, "name");
/* Deal with weird headers */
if (strchr(content_type, ' '))
*(strchr(content_type, ' ')) = '\0';
}
if (!strncasecmp(header, "Content-Disposition: ", 21)) {
strcpy(disposition, &header[21]);
+ extract_key(content_disposition_name, disposition, "name");
extract_key(filename, disposition, "filename");
}
if (!strncasecmp(header, "Content-length: ", 16)) {
part_end = ptr;
++ptr;
}
- } while ( (strcasecmp(ptr, endary)) && (ptr <= content_end) );
+ /* If we pass out of scope in the MIME multipart (by
+ * hitting the end boundary), force the pointer out
+ * of scope so this loop ends.
+ */
+ if (ptr < content_end) {
+ if (!strcasecmp(ptr, endary)) {
+ ptr = content_end++;
+ }
+ }
+ } while (ptr <= content_end);
if (PostMultiPartCallBack != NULL) {
PostMultiPartCallBack("", "", partnum, "", NULL,
content_type, 0, encoding, userdata);
++length;
}
part_end = content_end;
+ /* fix an off-by-one error */
+ --part_end;
+ --length;
/* Truncate if the header told us to */
if ( (content_length > 0) && (length > content_length) ) {
length = content_length;
}
+
+ /* Sometimes the "name" field is tacked on to Content-type,
+ * and sometimes it's tacked on to Content-disposition. Use
+ * whichever one we have.
+ */
+ if (strlen(content_disposition_name) > strlen(content_type_name)) {
+ name = content_disposition_name;
+ }
+ else {
+ name = content_type_name;
+ }
mime_decode(partnum,
part_start, length,
phree(header);
phree(content_type);
phree(encoding);
- phree(name);
+ phree(content_type_name);
+ phree(content_disposition_name);
phree(filename);
phree(disposition);
}
PostMultiPartCallBack,
userdata, dont_decode);
}
+