fix mime_decode_filename() and callers, make override_charset a PRBool: bug 65277 r=nhotta r=ducarroz sr=sspitzer

This commit is contained in:
jgmyers%netscape.com 2001-02-27 23:23:17 +00:00
Родитель b2625edc98
Коммит 2d56a9ee09
11 изменённых файлов: 77 добавлений и 72 удалений

Просмотреть файл

@ -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 // if we've been told to use an override charset then do so....otherwise use the charset
// inside the message header... // inside the message header...
if (mdd->options && mdd->options->override_charset) if (mdd->options && mdd->options->override_charset)
mdd->mailcharset = nsCRT::strdup(mdd->options->override_charset); mdd->mailcharset = nsCRT::strdup(mdd->options->default_charset);
else else
{ {
char *contentType = NULL; char *contentType = NULL;
@ -1627,7 +1627,7 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
char *workURLSpec = nsnull; char *workURLSpec = nsnull;
char *contLoc = 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 ); contLoc = MimeHeaders_get( headers, HEADER_CONTENT_LOCATION, PR_FALSE, PR_FALSE );
if (!contLoc) if (!contLoc)
contLoc = MimeHeaders_get( headers, HEADER_CONTENT_BASE, PR_FALSE, PR_FALSE ); contLoc = MimeHeaders_get( headers, HEADER_CONTENT_BASE, PR_FALSE, PR_FALSE );

Просмотреть файл

@ -186,7 +186,6 @@ GOTTA STILL DO THIS FOR QUOTING!
// obj->options really owns the storage for this. // obj->options really owns the storage for this.
newopt.part_to_load = nsnull; newopt.part_to_load = nsnull;
newopt.default_charset = nsnull; newopt.default_charset = nsnull;
newopt.override_charset = nsnull;
PR_FREEIF(id); PR_FREEIF(id);
PR_FREEIF(id_url); PR_FREEIF(id_url);
PR_FREEIF(id_name); PR_FREEIF(id_name);

Просмотреть файл

@ -677,15 +677,6 @@ MimeHeaders_convert_rfc1522(MimeDisplayOptions *opt,
if (opt->format_out != nsMimeOutput::nsMimeMessageSaveAs) if (opt->format_out != nsMimeOutput::nsMimeMessageSaveAs)
output_charset = "UTF-8"; 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. // check if we're converting from input charset to utf-8, and if so, cache converters.
if (!opt->m_unicodeToUTF8Encoder) if (!opt->m_unicodeToUTF8Encoder)
{ {
@ -698,9 +689,9 @@ MimeHeaders_convert_rfc1522(MimeDisplayOptions *opt,
nsCOMPtr <nsIAtom> sourceCharsetAtom; nsCOMPtr <nsIAtom> sourceCharsetAtom;
nsCOMPtr <nsIAtom> destCharsetAtom; nsCOMPtr <nsIAtom> destCharsetAtom;
opt->charsetForCachedInputDecoder = inputCharset; opt->charsetForCachedInputDecoder = opt->default_charset;
nsAutoString sourceCharset, destCharset; nsAutoString sourceCharset, destCharset;
sourceCharset.AssignWithConversion(inputCharset); sourceCharset.AssignWithConversion(opt->default_charset);
destCharset.AssignWithConversion(output_charset); destCharset.AssignWithConversion(output_charset);
rv = ccm2->GetCharsetAtom(sourceCharset.GetUnicode(), getter_AddRefs(sourceCharsetAtom)); rv = ccm2->GetCharsetAtom(sourceCharset.GetUnicode(), getter_AddRefs(sourceCharsetAtom));
rv = ccm2->GetCharsetAtom(destCharset.GetUnicode(), getter_AddRefs(destCharsetAtom)); 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; int status;
if (useInputCharsetConverter) if (useInputCharsetConverter)
status = opt->rfc1522_conversion_fn(input, input_length, 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, &converted, &converted_len,
opt->stream_closure, opt->m_inputCharsetToUnicodeDecoder , opt->m_unicodeToUTF8Encoder); opt->stream_closure, opt->m_inputCharsetToUnicodeDecoder , opt->m_unicodeToUTF8Encoder);
else else
status = opt->rfc1522_conversion_fn(input, input_length, 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, &converted, &converted_len,
opt->stream_closure, nsnull , opt->m_unicodeToUTF8Encoder); 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 /* Given text purporting to be a qtext header value, strip backslashes that
may be escaping other chars in the string. */ may be escaping other chars in the string. */
char * 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 *s = name, *d = name;
char *cvt, *returnVal = NULL; char *cvt, *returnVal = NULL;
@ -906,7 +898,8 @@ mime_decode_filename(char *name, const char *charset)
*d = 0; *d = 0;
returnVal = name; returnVal = name;
cvt = MIME_DecodeMimePartIIStr(returnVal, 0, PR_TRUE); cvt = MIME_DecodeMimeHeader(returnVal, default_charset, override_charset,
PR_TRUE);
if (cvt && cvt != returnVal) { if (cvt && cvt != returnVal) {
returnVal = cvt; 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) X-Sun-Data-Name: NAME (no RFC, but used by MailTool)
*/ */
char * char *
MimeHeaders_get_name(MimeHeaders *hdrs) MimeHeaders_get_name(MimeHeaders *hdrs, MimeDisplayOptions *opts)
{ {
char *s = 0, *name = 0, *cvt = 0; char *s = 0, *name = 0, *cvt = 0;
char *charset = nsnull; // for RFC2231 support 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 /* 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 in all appropriate headers. Unfortunately, that would be too scary
at this juncture. So just decode qtext/mime2 here. */ 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); PR_FREEIF(charset);
if (cvt && cvt != name) if (cvt && cvt != name)

Просмотреть файл

@ -75,8 +75,10 @@ HG77761
/* Does all the heuristic silliness to find the filename in the given headers. /* 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_ */ #endif /* _MIMEHDRS_H_ */

Просмотреть файл

@ -534,7 +534,7 @@ mime_create (const char *content_type, MimeHeaders *hdrs,
))) )))
#endif #endif
{ {
char *name = MimeHeaders_get_name(hdrs); char *name = MimeHeaders_get_name(hdrs, opts);
if (name) if (name)
{ {
override_content_type = opts->file_type_fn (name, opts->stream_closure); 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); obj = mime_address_to_part(part, obj);
if (!obj) return 0; 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 /* 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. */ 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 && obj->parent->headers &&
mime_typep(obj->parent, mime_typep(obj->parent,
(MimeObjectClass *) &mimeMultipartAppleDoubleClass)) (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 /* 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.) */ 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 && if (cont->nchildren > 1 &&
cont->children[1] && cont->children[1] &&
cont->children[1]->headers) cont->children[1]->headers)
result = MimeHeaders_get_name(cont->children[1]->headers); result = MimeHeaders_get_name(cont->children[1]->headers, obj->options);
if (!result && if (!result &&
cont->nchildren > 0 && cont->nchildren > 0 &&
cont->children[0] && cont->children[0] &&
cont->children[0]->headers) 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. /* 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) if (obj->headers)
{ {
char *ct; char *ct;
name = MimeHeaders_get_name(obj->headers); name = MimeHeaders_get_name(obj->headers, obj->options);
ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE,
PR_FALSE, PR_FALSE); PR_FALSE, PR_FALSE);

Просмотреть файл

@ -120,7 +120,9 @@ ProcessBodyAsAttachment(MimeObject *obj, nsMsgAttachmentData **data)
if (tmp->real_name) if (tmp->real_name)
{ {
char *fname = NULL; 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); PR_FREEIF(charset);
if (fname && fname != tmp->real_name) if (fname && fname != tmp->real_name)
{ {
@ -130,7 +132,7 @@ ProcessBodyAsAttachment(MimeObject *obj, nsMsgAttachmentData **data)
} }
else 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)) ) 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. // So we should parse both types.
char *fname = NULL; 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); PR_FREEIF(charset);
if (fname && fname != tmp->real_name) if (fname && fname != tmp->real_name)
@ -401,7 +405,9 @@ BuildAttachmentList(MimeObject *aChild, nsMsgAttachmentData *aAttachData,
// So we should parse both types. // So we should parse both types.
char *fname = NULL; 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); PR_FREEIF(charset);
if (fname && fname != tmp->real_name) if (fname && fname != tmp->real_name)
@ -1326,7 +1332,7 @@ MimeDisplayOptions::MimeDisplayOptions()
whattodo = 0 ; whattodo = 0 ;
default_charset = nsnull; default_charset = nsnull;
override_charset = nsnull; override_charset = PR_FALSE;
force_user_charset = PR_FALSE; force_user_charset = PR_FALSE;
stream_closure = nsnull; stream_closure = nsnull;
@ -1383,7 +1389,6 @@ MimeDisplayOptions::~MimeDisplayOptions()
{ {
PR_FREEIF(part_to_load); PR_FREEIF(part_to_load);
PR_FREEIF(default_charset); PR_FREEIF(default_charset);
PR_FREEIF(override_charset);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Bridge routines for new stream converter XP-COM interface // Bridge routines for new stream converter XP-COM interface
@ -1960,8 +1965,11 @@ ResetChannelCharset(MimeObject *obj)
(*cSet != CR) && (*cSet != LF) && (*cSet != '"') ) (*cSet != CR) && (*cSet != LF) && (*cSet != '"') )
ptr2++; ptr2++;
if (*cSet) if (*cSet) {
obj->options->override_charset = nsCRT::strdup(cSet); PR_FREEIF(obj->options->default_charset);
obj->options->default_charset = nsCRT::strdup(cSet);
obj->options->override_charset = PR_TRUE;
}
PR_FREEIF(cSet); PR_FREEIF(cSet);
} }

Просмотреть файл

@ -437,8 +437,8 @@ HG09091
const char *input_charset = NULL; const char *input_charset = NULL;
MimeInlineText *text = (MimeInlineText *) body; MimeInlineText *text = (MimeInlineText *) body;
if (obj->options->override_charset && (*obj->options->override_charset)) if (obj->options->override_charset && (*obj->options->default_charset))
input_charset = obj->options->override_charset; input_charset = obj->options->default_charset;
else if ( (text) && (text->charset) && (*(text->charset)) ) else if ( (text) && (text->charset) && (*(text->charset)) )
input_charset = text->charset; input_charset = text->charset;
else else

Просмотреть файл

@ -190,7 +190,7 @@ MimeSunAttachment_create_child(MimeObject *obj)
obj->options && obj->options &&
obj->options->file_type_fn) obj->options->file_type_fn)
{ {
char *name = MimeHeaders_get_name(mult->hdrs); char *name = MimeHeaders_get_name(mult->hdrs, obj->options);
if (name) if (name)
{ {
mime_ct2 = obj->options->file_type_fn(name, mime_ct2 = obj->options->file_type_fn(name,

Просмотреть файл

@ -81,7 +81,7 @@ MimeInlineText_initialize (MimeObject *obj)
{ {
if (obj->options && obj->options->override_charset) if (obj->options && obj->options->override_charset)
{ {
text->charset = nsCRT::strdup(obj->options->override_charset); text->charset = nsCRT::strdup(obj->options->default_charset);
} }
else else
{ {
@ -329,8 +329,8 @@ MimeInlineText_rotate_convert_and_parse_line(char *line, PRInt32 length,
if (!input_charset) if (!input_charset)
{ {
if (obj->options->override_charset && (*obj->options->override_charset)) if (obj->options->override_charset && (*obj->options->default_charset))
input_charset = obj->options->override_charset; input_charset = obj->options->default_charset;
else if ( (text) && (text->charset) && (*(text->charset)) ) else if ( (text) && (text->charset) && (*(text->charset)) )
input_charset = text->charset; input_charset = text->charset;
else else

Просмотреть файл

@ -202,13 +202,12 @@ public:
assume when no other one is specified via a assume when no other one is specified via a
`charset' parameter. `charset' parameter.
*/ */
char *override_charset; /* If this is non-NULL, then we will assume that PRBool override_charset; /* If this is PR_TRUE, then we will assume that
all data is in this charset, regardless of what all data is in the default_charset, regardless
the `charset' parameter of that part says. of what the `charset' parameter of that part
This overrides `default_charset' as well. says. (This is to cope with the fact that, in
(This is to cope with the fact that, in the the real world, many messages are mislabelled
real world, many messages are mislabelled with with the wrong charset.)
the wrong charset.)
*/ */
PRBool force_user_charset; /* this is the new strategy to deal with incorrectly PRBool force_user_charset; /* this is the new strategy to deal with incorrectly
labeled attachments */ labeled attachments */

Просмотреть файл

@ -118,7 +118,7 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType)
{ {
if (session->data_object) if (session->data_object)
{ {
char **override_charset = nsnull; PRBool *override_charset = nsnull;
char **default_charset = nsnull; char **default_charset = nsnull;
char **url_name = nsnull; char **url_name = nsnull;
@ -155,16 +155,22 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType)
if (i18nUrl) if (i18nUrl)
{ {
nsXPIDLString uniCharset; nsXPIDLString uniCharset;
i18nUrl->GetFolderCharset(getter_Copies(uniCharset)); nsAutoString charset;
nsAutoString charset(uniCharset);
if (!charset.IsEmpty())
*default_charset = charset.ToNewCString();
// check to see if we have a charset override...and if we do, set that field appropriately too... // 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)); nsresult rv = i18nUrl->GetCharsetOverRide(getter_Copies(uniCharset));
charset = uniCharset; charset = uniCharset;
if (NS_SUCCEEDED(rv) && !charset.IsEmpty() ) if (NS_SUCCEEDED(rv) && !charset.IsEmpty() ) {
*override_charset = charset.ToNewCString(); *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 // if there is no manual override and a folder charset exists
// then check if we have a folder level override // 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; PRBool folderCharsetOverride;
rv = i18nUrl->GetFolderCharsetOverride(&folderCharsetOverride); rv = i18nUrl->GetFolderCharsetOverride(&folderCharsetOverride);
if (NS_SUCCEEDED(rv) && 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) // notify the default to msgWindow (for the menu check mark)
nsCOMPtr<nsIMsgMailNewsUrl> msgurl (do_QueryInterface(aURI)); nsCOMPtr<nsIMsgMailNewsUrl> msgurl (do_QueryInterface(aURI));
@ -184,22 +190,18 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType)
if (msgWindow) if (msgWindow)
msgWindow->SetMailCharacterSet(NS_ConvertASCIItoUCS2(*default_charset)); msgWindow->SetMailCharacterSet(NS_ConvertASCIItoUCS2(*default_charset));
} }
}
// if the pref says always override and no manual override then set the folder charset to override // 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 (!*override_charset) {
if (charset.IsEmpty()) { nsCOMPtr <nsIPref> prefs = do_GetService(kPrefCID, &rv);
nsCOMPtr <nsIPref> prefs = do_GetService(kPrefCID, &rv); if (NS_SUCCEEDED(rv) && prefs)
if (NS_SUCCEEDED(rv) && prefs)
{
PRBool force_override;
rv = prefs->GetBoolPref("mailnews.force_charset_override", &force_override);
if (NS_SUCCEEDED(rv) && force_override)
{ {
i18nUrl->GetFolderCharset(getter_Copies(uniCharset)); PRBool force_override;
charset.Assign(uniCharset); rv = prefs->GetBoolPref("mailnews.force_charset_override", &force_override);
if (!charset.IsEmpty()) if (NS_SUCCEEDED(rv) && force_override)
*override_charset = charset.ToNewCString(); {
*override_charset = PR_TRUE;
}
} }
} }
} }