Back to index

lightning-sunbird  0.9+nobinonly
mimethsa.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org libmime code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Ben Bucksch <http://www.bucksch.org/1/projects/mozilla/>.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* Most of this code is copied from mimethpl; see there for source comments.
00039    If you find a bug here, check that class, too.
00040 */
00041 
00042 #include "mimethsa.h"
00043 #include "prmem.h"
00044 #include "prlog.h"
00045 #include "msgCore.h"
00046 #include "mimemoz2.h"
00047 #include "nsIPrefBranch.h"
00048 #include "nsString.h"
00049 #include "nsReadableUtils.h"
00050 
00051 //#define DEBUG_BenB
00052 
00053 #define MIME_SUPERCLASS mimeInlineTextHTMLClass
00054 MimeDefClass(MimeInlineTextHTMLSanitized, MimeInlineTextHTMLSanitizedClass,
00055                       mimeInlineTextHTMLSanitizedClass, &MIME_SUPERCLASS);
00056 
00057 static int MimeInlineTextHTMLSanitized_parse_line (char *, PRInt32,
00058                                                    MimeObject *);
00059 static int MimeInlineTextHTMLSanitized_parse_begin (MimeObject *obj);
00060 static int MimeInlineTextHTMLSanitized_parse_eof (MimeObject *, PRBool);
00061 static void MimeInlineTextHTMLSanitized_finalize (MimeObject *obj);
00062 
00063 static int
00064 MimeInlineTextHTMLSanitizedClassInitialize(MimeInlineTextHTMLSanitizedClass *clazz)
00065 {
00066   MimeObjectClass *oclass = (MimeObjectClass *) clazz;
00067   NS_ASSERTION(!oclass->class_initialized, "problem with superclass");
00068   oclass->parse_line  = MimeInlineTextHTMLSanitized_parse_line;
00069   oclass->parse_begin = MimeInlineTextHTMLSanitized_parse_begin;
00070   oclass->parse_eof   = MimeInlineTextHTMLSanitized_parse_eof;
00071   oclass->finalize    = MimeInlineTextHTMLSanitized_finalize;
00072 
00073   return 0;
00074 }
00075 
00076 static int
00077 MimeInlineTextHTMLSanitized_parse_begin (MimeObject *obj)
00078 {
00079 #ifdef DEBUG_BenB
00080 printf("parse_begin\n");
00081 #endif
00082   MimeInlineTextHTMLSanitized *textHTMLSan =
00083                                        (MimeInlineTextHTMLSanitized *) obj;
00084   textHTMLSan->complete_buffer = new nsString();
00085 #ifdef DEBUG_BenB
00086 printf(" B1\n");
00087 printf(" cbp: %d\n", textHTMLSan->complete_buffer);
00088 #endif
00089   int status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_begin(obj);
00090   if (status < 0)
00091     return status;
00092 #ifdef DEBUG_BenB
00093 printf(" B2\n");
00094 #endif
00095 
00096   // charset
00097   /* honestly, I don't know how that charset stuff works in libmime.
00098      The part in mimethtm doesn't make much sense to me either.
00099      I'll just dump the charset we get in the mime headers into a
00100      HTML meta http-equiv.
00101      XXX Not sure, if that is correct, though. */
00102   char *content_type =
00103     (obj->headers
00104      ? MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, PR_FALSE, PR_FALSE)
00105      : 0);
00106   if (content_type)
00107   {
00108     char* charset = MimeHeaders_get_parameter(content_type,
00109                                               HEADER_PARM_CHARSET,
00110                                               NULL, NULL);
00111     PR_Free(content_type);
00112     if (charset)
00113     {
00114       nsCAutoString charsetline(
00115         "\n<meta http-equiv=\"Context-Type\" content=\"text/html; charset=");
00116       charsetline += charset;
00117       charsetline += "\">\n";
00118       int status = MimeObject_write(obj,
00119                                     charsetline.get(),
00120                                     charsetline.Length(),
00121                                     PR_TRUE);
00122       PR_Free(charset);
00123       if (status < 0)
00124         return status;
00125     }
00126   }
00127 #ifdef DEBUG_BenB
00128 printf("/parse_begin\n");
00129 #endif
00130   return 0;
00131 }
00132 
00133 static int
00134 MimeInlineTextHTMLSanitized_parse_eof (MimeObject *obj, PRBool abort_p)
00135 {
00136 #ifdef DEBUG_BenB
00137 printf("parse_eof\n");
00138 #endif
00139 
00140   if (obj->closed_p)
00141     return 0;
00142   int status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
00143   if (status < 0) 
00144     return status;
00145   MimeInlineTextHTMLSanitized *textHTMLSan =
00146                                        (MimeInlineTextHTMLSanitized *) obj;
00147 
00148 #ifdef DEBUG_BenB
00149 printf(" cbp: %d\n", textHTMLSan->complete_buffer);
00150 printf(" closed_p: %s\n", obj->closed_p?"true":"false");
00151 #endif
00152   if (!textHTMLSan || !textHTMLSan->complete_buffer)
00153   {
00154 #ifdef DEBUG_BenB
00155 printf("/parse_eof (early exit)\n");
00156 #endif
00157     return 0;
00158   }
00159 #ifdef DEBUG_BenB
00160 printf(" E1\n");
00161 printf("buffer: -%s-\n", NS_LossyConvertUCS2toASCII(*textHTMLSan->complete_buffer).get());
00162 #endif
00163 
00164   char* allowedTags = 0;
00165   nsIPrefBranch *prefBranch = GetPrefBranch(obj->options);
00166   if (prefBranch)
00167     prefBranch->GetCharPref("mailnews.display.html_sanitizer.allowed_tags",
00168                             &allowedTags);
00169 
00170 #ifdef DEBUG_BenB
00171 printf(" E2\n");
00172 #endif
00173   nsString& cb = *(textHTMLSan->complete_buffer);
00174 #ifdef DEBUG_BenB
00175 printf(" E3\n");
00176 #endif
00177   nsString sanitized;
00178 #ifdef DEBUG_BenB
00179 printf(" E4\n");
00180 #endif
00181   HTMLSanitize(cb, sanitized, 0, NS_ConvertASCIItoUCS2(allowedTags));
00182 #ifdef DEBUG_BenB
00183 printf(" E5\n");
00184 #endif
00185 
00186   NS_ConvertUTF16toUTF8 resultCStr(sanitized);
00187 #ifdef DEBUG_BenB
00188 printf(" E6\n");
00189 #endif
00190   // TODO parse each line independently
00191   /* That function doesn't work correctly, if the first META tag is no
00192      charset spec. (It assumes that it's on its own line.)
00193      Most likely not fatally wrong, however. */
00194   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_line(
00195                              resultCStr.BeginWriting(),
00196                              resultCStr.Length(),
00197                              obj);
00198 #ifdef DEBUG_BenB
00199 printf(" E7\n");
00200 #endif
00201 
00202 #ifdef DEBUG_BenB
00203 printf(" E8\n");
00204 #endif
00205 
00206   cb.Truncate();
00207 
00208 #ifdef DEBUG_BenB
00209 printf("/parse_eof\n");
00210 #endif
00211 
00212   return status;
00213 }
00214 
00215 void
00216 MimeInlineTextHTMLSanitized_finalize (MimeObject *obj)
00217 {
00218 #ifdef DEBUG_BenB
00219 printf("finalize\n");
00220 #endif
00221   MimeInlineTextHTMLSanitized *textHTMLSan =
00222                                         (MimeInlineTextHTMLSanitized *) obj;
00223 #ifdef DEBUG_BenB
00224 printf(" cbp: %d\n", textHTMLSan->complete_buffer);
00225 printf(" F1\n");
00226 #endif
00227 
00228   if (textHTMLSan && textHTMLSan->complete_buffer)
00229   {
00230     obj->clazz->parse_eof(obj, PR_FALSE);
00231 #ifdef DEBUG_BenB
00232 printf(" F2\n");
00233 #endif
00234     delete textHTMLSan->complete_buffer;
00235 #ifdef DEBUG_BenB
00236 printf(" cbp: %d\n", textHTMLSan->complete_buffer);
00237 printf(" F3\n");
00238 #endif
00239     textHTMLSan->complete_buffer = NULL;
00240   }
00241 
00242 #ifdef DEBUG_BenB
00243 printf(" cbp: %d\n", textHTMLSan->complete_buffer);
00244 printf(" F4\n");
00245 #endif
00246   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize (obj);
00247 #ifdef DEBUG_BenB
00248 printf("/finalize\n");
00249 #endif
00250 }
00251 
00252 static int
00253 MimeInlineTextHTMLSanitized_parse_line (char *line, PRInt32 length,
00254                                           MimeObject *obj)
00255 {
00256 #ifdef DEBUG_BenB
00257 printf("p");
00258 #endif
00259   MimeInlineTextHTMLSanitized *textHTMLSan =
00260                                        (MimeInlineTextHTMLSanitized *) obj;
00261 #ifdef DEBUG_BenB
00262 printf("%d", textHTMLSan->complete_buffer);
00263 #endif
00264 
00265   if (!textHTMLSan || !(textHTMLSan->complete_buffer))
00266   {
00267 #ifdef DEBUG
00268 printf("Can't output: %s\n", line);
00269 #endif
00270     return -1;
00271   }
00272 
00273   nsCString linestr(line, length);
00274   NS_ConvertUTF8toUCS2 line_ucs2(linestr.get());
00275   if (length && line_ucs2.IsEmpty())
00276     line_ucs2.AssignWithConversion(linestr.get());
00277   (textHTMLSan->complete_buffer)->Append(line_ucs2);
00278 
00279 #ifdef DEBUG_BenB
00280 printf("l ");
00281 #endif
00282   return 0;
00283 }