diff --git a/ChangeLog b/ChangeLog index bb289b14c..f540e8c0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2009-09-14 Wolfgang Sourdeau + * UI/WebServerResources/MailerUI.js (configureLoadImagesButton): + retrieve all "img" elements with an "unsafe-src" attribute and + remember them in an array attached to $("messageContent"). + + * UI/MailPartViewers/UIxMailPartHTMLViewer.m + (-startElement:namespace:rawName:attributes:): treat tag names as + lowercase (xhtml compliance). Replace all "src" tagnames with + "unsafe-src" for distant images. No longer take an "unsafe" url + parameter into account. + * UI/MailPartViewers/UIxMailPartSignedViewer.[hm]: new module class that implements the viewer for multipart/signed messages. diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.h b/UI/MailPartViewers/UIxMailPartHTMLViewer.h index dc799eab8..bbfb0e049 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.h +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.h @@ -28,11 +28,9 @@ @interface UIxMailPartHTMLViewer : UIxMailPartViewer { id handler; - BOOL unsafe; } - (NSString *) flatContentAsString; -- (void) setUnsafe: (BOOL) b; @end diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 814eeb2e4..d475200a7 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -111,8 +111,6 @@ _xmlCharsetForCharset (NSString *charset) BOOL inStyle; BOOL inCSSDeclaration; BOOL hasEmbeddedCSS; - BOOL hasExternalImages; - BOOL unsafe; xmlCharEncoding contentEncoding; } @@ -126,8 +124,8 @@ _xmlCharsetForCharset (NSString *charset) { if (!BannedTags) { - BannedTags = [NSArray arrayWithObjects: @"SCRIPT", @"LINK", @"BASE", - @"META", @"TITLE", nil]; + BannedTags = [NSArray arrayWithObjects: @"script", @"link", @"base", + @"meta", @"title", nil]; [BannedTags retain]; } } @@ -153,16 +151,6 @@ _xmlCharsetForCharset (NSString *charset) [super dealloc]; } -- (BOOL) hasExternalImages -{ - return hasExternalImages; -} - -- (void) setUnsafe: (BOOL) b -{ - unsafe = b; -} - - (void) setContentEncoding: (xmlCharEncoding) newContentEncoding { contentEncoding = newContentEncoding; @@ -290,28 +278,28 @@ _xmlCharsetForCharset (NSString *charset) attributes: (id ) _attributes { unsigned int count, max; - NSString *name, *value, *cid, *upperName; + NSString *name, *value, *cid, *lowerName; NSMutableString *resultPart; BOOL skipAttribute; showWhoWeAre(); - upperName = [_localName uppercaseString]; + lowerName = [_localName lowercaseString]; if (inStyle || ignoreContent) ; - else if ([upperName isEqualToString: @"BASE"]) + else if ([lowerName isEqualToString: @"base"]) ; - else if ([upperName isEqualToString: @"META"]) + else if ([lowerName isEqualToString: @"meta"]) ; - else if ([upperName isEqualToString: @"BODY"]) + else if ([lowerName isEqualToString: @"body"]) inBody = YES; - else if ([upperName isEqualToString: @"STYLE"]) + else if ([lowerName isEqualToString: @"style"]) inStyle = YES; else if (inBody) { - if ([BannedTags containsObject: upperName]) + if ([BannedTags containsObject: lowerName]) { - ignoreTag = [upperName copy]; + ignoreTag = [lowerName copy]; ignoreContent = YES; } else @@ -323,10 +311,10 @@ _xmlCharsetForCharset (NSString *charset) for (count = 0; count < max; count++) { skipAttribute = NO; - name = [[_attributes nameAtIndex: count] uppercaseString]; + name = [[_attributes nameAtIndex: count] lowercaseString]; if ([name hasPrefix: @"ON"]) skipAttribute = YES; - else if ([name isEqualToString: @"SRC"]) + else if ([name isEqualToString: @"src"]) { value = [_attributes valueAtIndex: count]; if ([value hasPrefix: @"cid:"]) @@ -336,17 +324,17 @@ _xmlCharsetForCharset (NSString *charset) value = [attachmentIds objectForKey: cid]; skipAttribute = (value == nil); } - else if ([upperName isEqualToString: @"IMG"]) + else if ([lowerName isEqualToString: @"img"]) { - hasExternalImages = YES; - - if (!unsafe) skipAttribute = YES; + /* [resultPart appendString: + @"src=\"/SOGo.woa/WebServerResources/empty.gif\""]; */ + name = @"unsafe-src"; } else skipAttribute = YES; } - else if ([name isEqualToString: @"HREF"] - || [name isEqualToString: @"ACTION"]) + else if ([name isEqualToString: @"href"] + || [name isEqualToString: @"action"]) { value = [_attributes valueAtIndex: count]; skipAttribute = ([value rangeOfString: @"://"].location @@ -391,15 +379,15 @@ _xmlCharsetForCharset (NSString *charset) namespace: (NSString *) _ns rawName: (NSString *) _rawName { - NSString *upperName; + NSString *lowerName; showWhoWeAre(); - upperName = [_localName uppercaseString]; + lowerName = [_localName lowercaseString]; if (ignoreContent) { - if ([upperName isEqualToString: ignoreTag]) + if ([lowerName isEqualToString: ignoreTag]) { ignoreContent = NO; [ignoreTag release]; @@ -410,7 +398,7 @@ _xmlCharsetForCharset (NSString *charset) { if (inStyle) { - if ([upperName isEqualToString: @"STYLE"]) + if ([lowerName isEqualToString: @"style"]) { inStyle = NO; inCSSDeclaration = NO; @@ -418,7 +406,7 @@ _xmlCharsetForCharset (NSString *charset) } else if (inBody) { - if ([upperName isEqualToString: @"BODY"]) + if ([lowerName isEqualToString: @"body"]) { inBody = NO; if (css) @@ -624,17 +612,11 @@ _xmlCharsetForCharset (NSString *charset) } [handler setContentEncoding: enc]; - [handler setUnsafe: unsafe]; [parser setContentHandler: handler]; [parser parseFromSource: preparsedContent]; } -- (BOOL) hasExternalImages -{ - return [handler hasExternalImages]; -} - - (NSString *) cssContent { NSString *cssContent, *css; @@ -661,23 +643,6 @@ _xmlCharsetForCharset (NSString *charset) return [handler result]; } -- (void) setUnsafe: (BOOL) b -{ - unsafe = b; -} - -- (BOOL) displayLoadImages -{ - BOOL b; - - b = [handler hasExternalImages]; - - if (b && unsafe) - return NO; - - return b; -} - @end @implementation UIxMailPartExternalHTMLViewer diff --git a/UI/MailPartViewers/UIxMailRenderingContext.h b/UI/MailPartViewers/UIxMailRenderingContext.h index 9edcf1ca9..1ac62538f 100644 --- a/UI/MailPartViewers/UIxMailRenderingContext.h +++ b/UI/MailPartViewers/UIxMailRenderingContext.h @@ -43,7 +43,6 @@ WOComponent *viewer; /* non-retained! */ WOContext *context; /* non-retained! */ NSDictionary *flatContents; /* IMAP4 name to NSData */ - BOOL unsafe; } - (id) initWithViewer: (WOComponent *) _viewer @@ -52,7 +51,6 @@ /* state */ - (void) reset; -- (void) setUnsafe: (BOOL) b; /* fetching */ diff --git a/UI/MailPartViewers/UIxMailRenderingContext.m b/UI/MailPartViewers/UIxMailRenderingContext.m index 867dd00cc..95ffecf93 100644 --- a/UI/MailPartViewers/UIxMailRenderingContext.m +++ b/UI/MailPartViewers/UIxMailRenderingContext.m @@ -87,11 +87,6 @@ static BOOL showNamedTextAttachmentsInline = NO; flatContents = nil; } -- (void) setUnsafe: (BOOL) b -{ - unsafe = b; -} - /* fetching */ - (NSDictionary *) flatContents @@ -161,7 +156,6 @@ static BOOL showNamedTextAttachmentsInline = NO; id o; o = [viewer pageWithName: @"UIxMailPartHTMLViewer"]; - [o setUnsafe: unsafe]; return o; } diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index fcf350dcb..a0ab3f58d 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -208,17 +208,14 @@ static NSString *mailETag = nil; { UIxMailRenderingContext *mctx; WORequest *request; - NSString *unsafe; request = [_ctx request]; - unsafe = [request formValueForKey: @"unsafe"]; if (mailETag != nil) [[_ctx response] setHeader:mailETag forKey:@"etag"]; mctx = [[UIxMailRenderingContext alloc] initWithViewer: self context: _ctx]; - [mctx setUnsafe: (unsafe != nil ? YES : NO)]; [_ctx pushMailRenderingContext: mctx]; [mctx release]; diff --git a/UI/Templates/MailPartViewers/UIxMailPartHTMLViewer.wox b/UI/Templates/MailPartViewers/UIxMailPartHTMLViewer.wox index 8a7b2a110..c4bd4faea 100644 --- a/UI/Templates/MailPartViewers/UIxMailPartHTMLViewer.wox +++ b/UI/Templates/MailPartViewers/UIxMailPartHTMLViewer.wox @@ -7,8 +7,6 @@ xmlns:rsrc="OGo:url" xmlns:label="OGo:label"> -
diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 2132e1da5..28bc4f705 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -680,7 +680,7 @@ function messageListCallback(http) { else { // Add table div.update(http.responseText); - table = $('messageList'); + table = $("messageList"); configureMessageListEvents(table); TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true}); configureDraggables(); @@ -953,15 +953,22 @@ function loadMessage(idx) { function configureLoadImagesButton() { // We show/hide the "Load Images" button var loadImagesButton = $("loadImagesButton"); - var displayLoadImages = $("displayLoadImages"); + var content = $("messageContent"); + var hiddenImgs = []; + var imgs = content.select("IMG"); + $(imgs).each(function(img) { + var unsafeSrc = img.getAttribute("unsafe-src"); + if (unsafeSrc && unsafeSrc.length > 0) { + hiddenImgs.push(img); + } + }); + content.hiddenImgs = hiddenImgs; if (typeof(loadImagesButton) == "undefined" || loadImagesButton == null ) { return; } - if (typeof(displayLoadImages) == "undefined" || - displayLoadImages == null || - displayLoadImages.value == 0) { + if (hiddenImgs.length == 0) { loadImagesButton.setStyle({ display: 'none' }); } } @@ -1021,8 +1028,7 @@ function configureLinksInMessage() { var loadImagesButton = $("loadImagesButton"); if (loadImagesButton) - loadImagesButton.observe("click", - onMessageLoadImages.bindAsEventListener(loadImagesButton)); + $(loadImagesButton).observe("click", onMessageLoadImages); configureiCalLinksInMessage(); } @@ -1176,11 +1182,18 @@ function onMessageEditDraft(event) { } function onMessageLoadImages(event) { - var msguid = Mailer.currentMessages[Mailer.currentMailbox]; - var url = (ApplicationBaseURL + encodeURI(Mailer.currentMailbox) + "/" - + msguid + "/view?noframe=1&unsafe=1"); - document.messageAjaxRequest - = triggerAjaxRequest(url, messageCallback, msguid); + var content = $("messageContent"); + $(content.hiddenImgs).each(function(img) { + var unSafeSrc = img.getAttribute("unsafe-src"); + log ("unsafesrc: " + unSafeSrc); + img.src = img.getAttribute("unsafe-src"); + }); + + delete content.hiddenImgs; + var loadImagesButton = $("loadImagesButton"); + loadImagesButton.setStyle({ display: 'none' }); + + Event.stop(event); } function onEmailAddressClick(event) { diff --git a/UI/WebServerResources/UIxMailPopupView.js b/UI/WebServerResources/UIxMailPopupView.js index d021baa3a..f7e4b06b1 100644 --- a/UI/WebServerResources/UIxMailPopupView.js +++ b/UI/WebServerResources/UIxMailPopupView.js @@ -10,23 +10,10 @@ function initPopupMailer(event) { configureLinksInMessage(); resizeMailContent(); - var loadImagesButton = $("loadImagesButton"); - if (loadImagesButton) - loadImagesButton.observe("click", - onMessageLoadImages.bindAsEventListener(loadImagesButton)); - configureLoadImagesButton(); configureSignatureFlagImage(); } -function onMessageLoadImages(event) { - var msguid = window.opener.Mailer.currentMessages[window.opener.Mailer.currentMailbox]; - var url = (window.opener.ApplicationBaseURL + window.opener.encodeURI(window.opener.Mailer.currentMailbox) + "/" - + msguid + "/view?noframe=1&unsafe=1"); - document.messageAjaxRequest - = triggerAjaxRequest(url, messageCallback, msguid); -} - function onICalendarButtonClick(event) { var link = $("iCalendarAttachment").value; if (link) {