From 2d56a9ee09d92ae5b4506c8ffba70305fbf9a7ca Mon Sep 17 00:00:00 2001 From: "jgmyers%netscape.com" Date: Tue, 27 Feb 2001 23:23:17 +0000 Subject: [PATCH] fix mime_decode_filename() and callers, make override_charset a PRBool: bug 65277 r=nhotta r=ducarroz sr=sspitzer --- mailnews/mime/src/mimedrft.cpp | 4 +-- mailnews/mime/src/mimeeobj.cpp | 1 - mailnews/mime/src/mimehdrs.cpp | 31 +++++++---------- mailnews/mime/src/mimehdrs.h | 6 ++-- mailnews/mime/src/mimei.cpp | 12 +++---- mailnews/mime/src/mimemoz2.cpp | 24 ++++++++----- mailnews/mime/src/mimemsg.cpp | 4 +-- mailnews/mime/src/mimesun.cpp | 2 +- mailnews/mime/src/mimetext.cpp | 6 ++-- mailnews/mime/src/modlmime.h | 13 ++++--- mailnews/mime/src/nsStreamConverter.cpp | 46 +++++++++++++------------ 11 files changed, 77 insertions(+), 72 deletions(-) diff --git a/mailnews/mime/src/mimedrft.cpp b/mailnews/mime/src/mimedrft.cpp index 25c6206d632..0768ae9a4b0 100644 --- a/mailnews/mime/src/mimedrft.cpp +++ b/mailnews/mime/src/mimedrft.cpp @@ -1574,7 +1574,7 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers ) // if we've been told to use an override charset then do so....otherwise use the charset // inside the message header... if (mdd->options && mdd->options->override_charset) - mdd->mailcharset = nsCRT::strdup(mdd->options->override_charset); + mdd->mailcharset = nsCRT::strdup(mdd->options->default_charset); else { char *contentType = NULL; @@ -1627,7 +1627,7 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers ) char *workURLSpec = nsnull; char *contLoc = nsnull; - newAttachment->real_name = MimeHeaders_get_name ( headers ); + newAttachment->real_name = MimeHeaders_get_name ( headers, mdd->options ); contLoc = MimeHeaders_get( headers, HEADER_CONTENT_LOCATION, PR_FALSE, PR_FALSE ); if (!contLoc) contLoc = MimeHeaders_get( headers, HEADER_CONTENT_BASE, PR_FALSE, PR_FALSE ); diff --git a/mailnews/mime/src/mimeeobj.cpp b/mailnews/mime/src/mimeeobj.cpp index 9efeae50048..f18d31fc5c3 100644 --- a/mailnews/mime/src/mimeeobj.cpp +++ b/mailnews/mime/src/mimeeobj.cpp @@ -186,7 +186,6 @@ GOTTA STILL DO THIS FOR QUOTING! // obj->options really owns the storage for this. newopt.part_to_load = nsnull; newopt.default_charset = nsnull; - newopt.override_charset = nsnull; PR_FREEIF(id); PR_FREEIF(id_url); PR_FREEIF(id_name); diff --git a/mailnews/mime/src/mimehdrs.cpp b/mailnews/mime/src/mimehdrs.cpp index adc4b5cf16b..dc1236b4b13 100644 --- a/mailnews/mime/src/mimehdrs.cpp +++ b/mailnews/mime/src/mimehdrs.cpp @@ -677,15 +677,6 @@ MimeHeaders_convert_rfc1522(MimeDisplayOptions *opt, if (opt->format_out != nsMimeOutput::nsMimeMessageSaveAs) output_charset = "UTF-8"; - // if we have an override charset, use it first...otherwise fall back to the - // default charset. Note: these charsets will only be used if the header isn't - // mime encoded. - const char * inputCharset = nsnull; - if (opt->override_charset) - inputCharset = opt->override_charset; - else if (opt->default_charset) - inputCharset = opt->default_charset; - // check if we're converting from input charset to utf-8, and if so, cache converters. if (!opt->m_unicodeToUTF8Encoder) { @@ -698,9 +689,9 @@ MimeHeaders_convert_rfc1522(MimeDisplayOptions *opt, nsCOMPtr sourceCharsetAtom; nsCOMPtr destCharsetAtom; - opt->charsetForCachedInputDecoder = inputCharset; + opt->charsetForCachedInputDecoder = opt->default_charset; nsAutoString sourceCharset, destCharset; - sourceCharset.AssignWithConversion(inputCharset); + sourceCharset.AssignWithConversion(opt->default_charset); destCharset.AssignWithConversion(output_charset); rv = ccm2->GetCharsetAtom(sourceCharset.GetUnicode(), getter_AddRefs(sourceCharsetAtom)); rv = ccm2->GetCharsetAtom(destCharset.GetUnicode(), getter_AddRefs(destCharsetAtom)); @@ -710,16 +701,16 @@ MimeHeaders_convert_rfc1522(MimeDisplayOptions *opt, } } - PRBool useInputCharsetConverter = opt->m_inputCharsetToUnicodeDecoder && !nsCRT::strcasecmp(inputCharset, opt->charsetForCachedInputDecoder); + PRBool useInputCharsetConverter = opt->m_inputCharsetToUnicodeDecoder && !nsCRT::strcasecmp(opt->default_charset, opt->charsetForCachedInputDecoder); int status; if (useInputCharsetConverter) status = opt->rfc1522_conversion_fn(input, input_length, - inputCharset, output_charset, /* no input charset? */ + opt->default_charset, output_charset, /* no input charset? */ &converted, &converted_len, opt->stream_closure, opt->m_inputCharsetToUnicodeDecoder , opt->m_unicodeToUTF8Encoder); else status = opt->rfc1522_conversion_fn(input, input_length, - inputCharset, output_charset, /* no input charset? */ + opt->default_charset, output_charset, /* no input charset? */ &converted, &converted_len, opt->stream_closure, nsnull , opt->m_unicodeToUTF8Encoder); @@ -882,7 +873,8 @@ extern PRInt16 INTL_DefaultMailToWinCharSetID(PRInt16 csid); /* Given text purporting to be a qtext header value, strip backslashes that may be escaping other chars in the string. */ char * -mime_decode_filename(char *name, const char *charset) +mime_decode_filename(char *name, const char *charset, + const char *default_charset, PRBool override_charset) { char *s = name, *d = name; char *cvt, *returnVal = NULL; @@ -906,7 +898,8 @@ mime_decode_filename(char *name, const char *charset) *d = 0; returnVal = name; - cvt = MIME_DecodeMimePartIIStr(returnVal, 0, PR_TRUE); + cvt = MIME_DecodeMimeHeader(returnVal, default_charset, override_charset, + PR_TRUE); if (cvt && cvt != returnVal) { returnVal = cvt; @@ -922,7 +915,7 @@ mime_decode_filename(char *name, const char *charset) X-Sun-Data-Name: NAME (no RFC, but used by MailTool) */ char * -MimeHeaders_get_name(MimeHeaders *hdrs) +MimeHeaders_get_name(MimeHeaders *hdrs, MimeDisplayOptions *opts) { char *s = 0, *name = 0, *cvt = 0; char *charset = nsnull; // for RFC2231 support @@ -964,7 +957,9 @@ MimeHeaders_get_name(MimeHeaders *hdrs) /* Argh. What we should do if we want to be robust is to decode qtext in all appropriate headers. Unfortunately, that would be too scary at this juncture. So just decode qtext/mime2 here. */ - cvt = mime_decode_filename(name, charset); + cvt = mime_decode_filename(name, charset, + opts->default_charset, + opts->override_charset); PR_FREEIF(charset); if (cvt && cvt != name) diff --git a/mailnews/mime/src/mimehdrs.h b/mailnews/mime/src/mimehdrs.h index c6f9cad377c..76e526f6f3d 100644 --- a/mailnews/mime/src/mimehdrs.h +++ b/mailnews/mime/src/mimehdrs.h @@ -75,8 +75,10 @@ HG77761 /* Does all the heuristic silliness to find the filename in the given headers. */ -extern char *MimeHeaders_get_name(MimeHeaders *hdrs); +extern char *MimeHeaders_get_name(MimeHeaders *hdrs, MimeDisplayOptions *opts); -extern char *mime_decode_filename(char *name, const char* charset); +extern char *mime_decode_filename(char *name, const char* charset, + const char* default_charset, + PRBool override_charset); #endif /* _MIMEHDRS_H_ */ diff --git a/mailnews/mime/src/mimei.cpp b/mailnews/mime/src/mimei.cpp index 2d1aded84e8..3a5029862f6 100644 --- a/mailnews/mime/src/mimei.cpp +++ b/mailnews/mime/src/mimei.cpp @@ -534,7 +534,7 @@ mime_create (const char *content_type, MimeHeaders *hdrs, ))) #endif { - char *name = MimeHeaders_get_name(hdrs); + char *name = MimeHeaders_get_name(hdrs, opts); if (name) { override_content_type = opts->file_type_fn (name, opts->stream_closure); @@ -970,7 +970,7 @@ mime_find_suggested_name_of_part(const char *part, MimeObject *obj) obj = mime_address_to_part(part, obj); if (!obj) return 0; - result = (obj->headers ? MimeHeaders_get_name(obj->headers) : 0); + result = (obj->headers ? MimeHeaders_get_name(obj->headers, obj->options) : 0); /* If this part doesn't have a name, but this part is one fork of an AppleDouble, and the AppleDouble itself has a name, then use that. */ @@ -979,7 +979,7 @@ mime_find_suggested_name_of_part(const char *part, MimeObject *obj) obj->parent->headers && mime_typep(obj->parent, (MimeObjectClass *) &mimeMultipartAppleDoubleClass)) - result = MimeHeaders_get_name(obj->parent->headers); + result = MimeHeaders_get_name(obj->parent->headers, obj->options); /* Else, if this part is itself an AppleDouble, and one of its children has a name, then use that (check data fork first, then resource.) */ @@ -990,13 +990,13 @@ mime_find_suggested_name_of_part(const char *part, MimeObject *obj) if (cont->nchildren > 1 && cont->children[1] && cont->children[1]->headers) - result = MimeHeaders_get_name(cont->children[1]->headers); + result = MimeHeaders_get_name(cont->children[1]->headers, obj->options); if (!result && cont->nchildren > 0 && cont->children[0] && cont->children[0]->headers) - result = MimeHeaders_get_name(cont->children[0]->headers); + result = MimeHeaders_get_name(cont->children[0]->headers, obj->options); } /* Ok, now we have the suggested name, if any. @@ -1302,7 +1302,7 @@ MimeObject_output_init(MimeObject *obj, const char *content_type) if (obj->headers) { char *ct; - name = MimeHeaders_get_name(obj->headers); + name = MimeHeaders_get_name(obj->headers, obj->options); ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, PR_FALSE, PR_FALSE); diff --git a/mailnews/mime/src/mimemoz2.cpp b/mailnews/mime/src/mimemoz2.cpp index f5bda080f36..844fcb88adb 100644 --- a/mailnews/mime/src/mimemoz2.cpp +++ b/mailnews/mime/src/mimemoz2.cpp @@ -120,7 +120,9 @@ ProcessBodyAsAttachment(MimeObject *obj, nsMsgAttachmentData **data) if (tmp->real_name) { char *fname = NULL; - fname = mime_decode_filename(tmp->real_name, charset); + fname = mime_decode_filename(tmp->real_name, charset, + obj->options->default_charset, + obj->options->override_charset); PR_FREEIF(charset); if (fname && fname != tmp->real_name) { @@ -130,7 +132,7 @@ ProcessBodyAsAttachment(MimeObject *obj, nsMsgAttachmentData **data) } else { - tmp->real_name = MimeHeaders_get_name(child->headers); + tmp->real_name = MimeHeaders_get_name(child->headers, obj->options); } if ( (!tmp->real_name) && (tmp->real_type) && (nsCRT::strncasecmp(tmp->real_type, "text", 4)) ) @@ -360,7 +362,9 @@ BuildAttachmentList(MimeObject *aChild, nsMsgAttachmentData *aAttachData, // So we should parse both types. char *fname = NULL; - fname = mime_decode_filename(tmp->real_name, charset); + fname = mime_decode_filename(tmp->real_name, charset, + aChild->options->default_charset, + aChild->options->override_charset); PR_FREEIF(charset); if (fname && fname != tmp->real_name) @@ -401,7 +405,9 @@ BuildAttachmentList(MimeObject *aChild, nsMsgAttachmentData *aAttachData, // So we should parse both types. char *fname = NULL; - fname = mime_decode_filename(tmp->real_name, charset); + fname = mime_decode_filename(tmp->real_name, charset, + aChild->options->default_charset, + aChild->options->override_charset); PR_FREEIF(charset); if (fname && fname != tmp->real_name) @@ -1326,7 +1332,7 @@ MimeDisplayOptions::MimeDisplayOptions() whattodo = 0 ; default_charset = nsnull; - override_charset = nsnull; + override_charset = PR_FALSE; force_user_charset = PR_FALSE; stream_closure = nsnull; @@ -1383,7 +1389,6 @@ MimeDisplayOptions::~MimeDisplayOptions() { PR_FREEIF(part_to_load); PR_FREEIF(default_charset); - PR_FREEIF(override_charset); } //////////////////////////////////////////////////////////////// // Bridge routines for new stream converter XP-COM interface @@ -1960,8 +1965,11 @@ ResetChannelCharset(MimeObject *obj) (*cSet != CR) && (*cSet != LF) && (*cSet != '"') ) ptr2++; - if (*cSet) - obj->options->override_charset = nsCRT::strdup(cSet); + if (*cSet) { + PR_FREEIF(obj->options->default_charset); + obj->options->default_charset = nsCRT::strdup(cSet); + obj->options->override_charset = PR_TRUE; + } PR_FREEIF(cSet); } diff --git a/mailnews/mime/src/mimemsg.cpp b/mailnews/mime/src/mimemsg.cpp index 9064dd63abe..92d005ad3d7 100644 --- a/mailnews/mime/src/mimemsg.cpp +++ b/mailnews/mime/src/mimemsg.cpp @@ -437,8 +437,8 @@ HG09091 const char *input_charset = NULL; MimeInlineText *text = (MimeInlineText *) body; - if (obj->options->override_charset && (*obj->options->override_charset)) - input_charset = obj->options->override_charset; + if (obj->options->override_charset && (*obj->options->default_charset)) + input_charset = obj->options->default_charset; else if ( (text) && (text->charset) && (*(text->charset)) ) input_charset = text->charset; else diff --git a/mailnews/mime/src/mimesun.cpp b/mailnews/mime/src/mimesun.cpp index 0556233d6ea..0152cea14a3 100644 --- a/mailnews/mime/src/mimesun.cpp +++ b/mailnews/mime/src/mimesun.cpp @@ -190,7 +190,7 @@ MimeSunAttachment_create_child(MimeObject *obj) obj->options && obj->options->file_type_fn) { - char *name = MimeHeaders_get_name(mult->hdrs); + char *name = MimeHeaders_get_name(mult->hdrs, obj->options); if (name) { mime_ct2 = obj->options->file_type_fn(name, diff --git a/mailnews/mime/src/mimetext.cpp b/mailnews/mime/src/mimetext.cpp index ea56a448119..2047afb43c4 100644 --- a/mailnews/mime/src/mimetext.cpp +++ b/mailnews/mime/src/mimetext.cpp @@ -81,7 +81,7 @@ MimeInlineText_initialize (MimeObject *obj) { if (obj->options && obj->options->override_charset) { - text->charset = nsCRT::strdup(obj->options->override_charset); + text->charset = nsCRT::strdup(obj->options->default_charset); } else { @@ -329,8 +329,8 @@ MimeInlineText_rotate_convert_and_parse_line(char *line, PRInt32 length, if (!input_charset) { - if (obj->options->override_charset && (*obj->options->override_charset)) - input_charset = obj->options->override_charset; + if (obj->options->override_charset && (*obj->options->default_charset)) + input_charset = obj->options->default_charset; else if ( (text) && (text->charset) && (*(text->charset)) ) input_charset = text->charset; else diff --git a/mailnews/mime/src/modlmime.h b/mailnews/mime/src/modlmime.h index 1815d44dfcd..397bd132577 100644 --- a/mailnews/mime/src/modlmime.h +++ b/mailnews/mime/src/modlmime.h @@ -202,13 +202,12 @@ public: assume when no other one is specified via a `charset' parameter. */ - char *override_charset; /* If this is non-NULL, then we will assume that - all data is in this charset, regardless of what - the `charset' parameter of that part says. - This overrides `default_charset' as well. - (This is to cope with the fact that, in the - real world, many messages are mislabelled with - the wrong charset.) + PRBool override_charset; /* If this is PR_TRUE, then we will assume that + all data is in the default_charset, regardless + of what the `charset' parameter of that part + says. (This is to cope with the fact that, in + the real world, many messages are mislabelled + with the wrong charset.) */ PRBool force_user_charset; /* this is the new strategy to deal with incorrectly labeled attachments */ diff --git a/mailnews/mime/src/nsStreamConverter.cpp b/mailnews/mime/src/nsStreamConverter.cpp index 334df5c7020..c82ade51227 100644 --- a/mailnews/mime/src/nsStreamConverter.cpp +++ b/mailnews/mime/src/nsStreamConverter.cpp @@ -118,7 +118,7 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType) { if (session->data_object) { - char **override_charset = nsnull; + PRBool *override_charset = nsnull; char **default_charset = nsnull; char **url_name = nsnull; @@ -155,16 +155,22 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType) if (i18nUrl) { nsXPIDLString uniCharset; - i18nUrl->GetFolderCharset(getter_Copies(uniCharset)); - nsAutoString charset(uniCharset); - if (!charset.IsEmpty()) - *default_charset = charset.ToNewCString(); + nsAutoString charset; // check to see if we have a charset override...and if we do, set that field appropriately too... nsresult rv = i18nUrl->GetCharsetOverRide(getter_Copies(uniCharset)); charset = uniCharset; - if (NS_SUCCEEDED(rv) && !charset.IsEmpty() ) - *override_charset = charset.ToNewCString(); + if (NS_SUCCEEDED(rv) && !charset.IsEmpty() ) { + *override_charset = PR_TRUE; + *default_charset = charset.ToNewCString(); + } + else + { + i18nUrl->GetFolderCharset(getter_Copies(uniCharset)); + charset = uniCharset; + if (!charset.IsEmpty()) + *default_charset = charset.ToNewCString(); + } // if there is no manual override and a folder charset exists // then check if we have a folder level override @@ -173,7 +179,7 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType) PRBool folderCharsetOverride; rv = i18nUrl->GetFolderCharsetOverride(&folderCharsetOverride); if (NS_SUCCEEDED(rv) && folderCharsetOverride) - *override_charset = nsCRT::strdup(*default_charset); + *override_charset = PR_TRUE; // notify the default to msgWindow (for the menu check mark) nsCOMPtr msgurl (do_QueryInterface(aURI)); @@ -184,22 +190,18 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType) if (msgWindow) msgWindow->SetMailCharacterSet(NS_ConvertASCIItoUCS2(*default_charset)); } - } - // if the pref says always override and no manual override then set the folder charset to override - // in future, the override flag to be per folder instead of a global pref - if (charset.IsEmpty()) { - nsCOMPtr prefs = do_GetService(kPrefCID, &rv); - if (NS_SUCCEEDED(rv) && prefs) - { - PRBool force_override; - rv = prefs->GetBoolPref("mailnews.force_charset_override", &force_override); - if (NS_SUCCEEDED(rv) && force_override) + // if the pref says always override and no manual override then set the folder charset to override + if (!*override_charset) { + nsCOMPtr prefs = do_GetService(kPrefCID, &rv); + if (NS_SUCCEEDED(rv) && prefs) { - i18nUrl->GetFolderCharset(getter_Copies(uniCharset)); - charset.Assign(uniCharset); - if (!charset.IsEmpty()) - *override_charset = charset.ToNewCString(); + PRBool force_override; + rv = prefs->GetBoolPref("mailnews.force_charset_override", &force_override); + if (NS_SUCCEEDED(rv) && force_override) + { + *override_charset = PR_TRUE; + } } } }