From d8f58536bae855f498bcbf6c1ec2dc7edaa55d9a Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Tue, 27 Aug 2002 20:49:54 +0000 Subject: [PATCH] Bug 162546 and bug 141883. Better handling of unknown area shapes and more graceful handling of bogus rect coords. r=jkeiser, sr=roc. git-svn-id: svn://10.0.0.236/trunk@128287 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsImageMap.cpp | 108 ++++++++++++++++-- mozilla/layout/html/base/src/Makefile.in | 1 + mozilla/layout/html/base/src/jar.mn | 1 + .../html/base/src/layout_errors.properties | 38 ++++++ mozilla/layout/html/base/src/nsImageMap.cpp | 108 ++++++++++++++++-- 5 files changed, 232 insertions(+), 24 deletions(-) create mode 100644 mozilla/layout/html/base/src/layout_errors.properties diff --git a/mozilla/layout/generic/nsImageMap.cpp b/mozilla/layout/generic/nsImageMap.cpp index 1c613f8bf4e..455feb01b34 100644 --- a/mozilla/layout/generic/nsImageMap.cpp +++ b/mozilla/layout/generic/nsImageMap.cpp @@ -63,13 +63,18 @@ #include "nsIViewManager.h" #include "nsCoord.h" #include "nsIImageMap.h" +#include "nsIConsoleService.h" +#include "nsIScriptError.h" +#include "nsIStringBundle.h" + +static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); class Area { public: Area(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL); virtual ~Area(); - void ParseCoords(const nsString& aSpec); + virtual void ParseCoords(const nsString& aSpec); virtual PRBool IsInside(nscoord x, nscoord y) = 0; virtual void Draw(nsIPresContext* aCX, @@ -436,6 +441,7 @@ public: RectArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL); ~RectArea(); + virtual void ParseCoords(const nsString& aSpec); virtual PRBool IsInside(nscoord x, nscoord y); virtual void Draw(nsIPresContext* aCX, nsIRenderingContext& aRC); @@ -452,6 +458,82 @@ RectArea::~RectArea() { } +void RectArea::ParseCoords(const nsString& aSpec) +{ + Area::ParseCoords(aSpec); + + PRBool saneRect = PR_TRUE; + PRInt32 flag = nsIScriptError::warningFlag; + if (mNumCoords >= 4) { + if (mCoords[0] > mCoords[2]) { + // x-coords in reversed order + nscoord x = mCoords[2]; + mCoords[2] = mCoords[0]; + mCoords[0] = x; + saneRect = PR_FALSE; + } + + if (mCoords[1] > mCoords[3]) { + // y-coords in reversed order + nscoord y = mCoords[3]; + mCoords[3] = mCoords[1]; + mCoords[1] = y; + saneRect = PR_FALSE; + } + + if (mNumCoords > 4) { + // Someone missed the concept of a rect here + saneRect = PR_FALSE; + } + } else { + saneRect = PR_FALSE; + flag = nsIScriptError::errorFlag; + } + + if (!saneRect) { + // Report the error to the console. + nsresult rv; + nsCOMPtr consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return; + nsCOMPtr errorObject = + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return; + nsCOMPtr stringBundleService = + do_GetService(kCStringBundleServiceCID, &rv); + if (NS_FAILED(rv)) + return; + nsCOMPtr bundle; + rv = stringBundleService->CreateBundle( + "chrome://global/locale/layout_errors.properties", + getter_AddRefs(bundle)); + if (NS_FAILED(rv)) + return; + nsXPIDLString errorText; + const PRUnichar* flatSpec = aSpec.get(); + rv = + bundle->FormatStringFromName(NS_LITERAL_STRING("ImageMapRectBoundsError").get(), + &flatSpec, 1, + getter_Copies(errorText)); + if (NS_FAILED(rv)) + return; + + rv = errorObject->Init(errorText.get(), + NS_LITERAL_STRING("").get(), /* file name */ + NS_LITERAL_STRING("").get(), /* source line */ + 0, /* line number */ + 0, /* column number */ + flag, + "ImageMap"); + if (NS_FAILED(rv)) + return; + + consoleService->LogMessage(errorObject); + } +} + PRBool RectArea::IsInside(nscoord x, nscoord y) { if (mNumCoords >= 4) { // Note: > is for nav compatabilty @@ -459,10 +541,8 @@ PRBool RectArea::IsInside(nscoord x, nscoord y) nscoord y1 = mCoords[1]; nscoord x2 = mCoords[2]; nscoord y2 = mCoords[3]; - if ((x1 > x2)|| (y1 > y2)) { - // Can't be inside a screwed up rect - return PR_FALSE; - } + NS_ASSERTION(x1 <= x2 && y1 <= y2, + "Someone screwed up RectArea::ParseCoords"); if ((x >= x1) && (x <= x2) && (y >= y1) && (y <= y2)) { return PR_TRUE; } @@ -480,9 +560,8 @@ void RectArea::Draw(nsIPresContext* aCX, nsIRenderingContext& aRC) nscoord y1 = NSIntPixelsToTwips(mCoords[1], p2t); nscoord x2 = NSIntPixelsToTwips(mCoords[2], p2t); nscoord y2 = NSIntPixelsToTwips(mCoords[3], p2t); - if ((x1 > x2)|| (y1 > y2)) { - return; - } + NS_ASSERTION(x1 <= x2 && y1 <= y2, + "Someone screwed up RectArea::ParseCoords"); aRC.DrawLine(x1, y1, x1, y2); aRC.DrawLine(x1, y2, x2, y2); aRC.DrawLine(x1, y1, x2, y1); @@ -500,9 +579,8 @@ void RectArea::GetRect(nsIPresContext* aCX, nsRect& aRect) nscoord y1 = NSIntPixelsToTwips(mCoords[1], p2t); nscoord x2 = NSIntPixelsToTwips(mCoords[2], p2t); nscoord y2 = NSIntPixelsToTwips(mCoords[3], p2t); - if ((x1 > x2)|| (y1 > y2)) { - return; - } + NS_ASSERTION(x1 <= x2 && y1 <= y2, + "Someone screwed up RectArea::ParseCoords"); nsRect tmp(x1, y1, x2, y2); aRect = tmp; @@ -961,9 +1039,15 @@ nsImageMap::AddArea(nsIContent* aArea) shape.EqualsIgnoreCase("circ")) { area = new CircleArea(aArea, suppress, hasURL); } - else { + else if (shape.EqualsIgnoreCase("default")) { area = new DefaultArea(aArea, suppress, hasURL); } + else { + // Unknown area type; bail + return NS_OK; + } + if (!area) + return NS_ERROR_OUT_OF_MEMORY; area->ParseCoords(coords); mAreas.AppendElement(area); return NS_OK; diff --git a/mozilla/layout/html/base/src/Makefile.in b/mozilla/layout/html/base/src/Makefile.in index 90207ece692..7470dc45d6f 100644 --- a/mozilla/layout/html/base/src/Makefile.in +++ b/mozilla/layout/html/base/src/Makefile.in @@ -57,6 +57,7 @@ REQUIRES = xpcom \ xpconnect \ java \ exthandler \ + intl \ $(NULL) # Sun's Complex Text Layout support diff --git a/mozilla/layout/html/base/src/jar.mn b/mozilla/layout/html/base/src/jar.mn index 1f35b575a87..e32b5662fe5 100644 --- a/mozilla/layout/html/base/src/jar.mn +++ b/mozilla/layout/html/base/src/jar.mn @@ -1,3 +1,4 @@ en-US.jar: locale/en-US/global/printing.properties + locale/en-US/global/layout_errors.properties diff --git a/mozilla/layout/html/base/src/layout_errors.properties b/mozilla/layout/html/base/src/layout_errors.properties new file mode 100644 index 00000000000..38bf067ea5b --- /dev/null +++ b/mozilla/layout/html/base/src/layout_errors.properties @@ -0,0 +1,38 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2002 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Boris Zbarsky (original author) +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +ImageMapRectBoundsError=The "coords" attribute of is not in the "left,top,right,bottom" format. diff --git a/mozilla/layout/html/base/src/nsImageMap.cpp b/mozilla/layout/html/base/src/nsImageMap.cpp index 1c613f8bf4e..455feb01b34 100644 --- a/mozilla/layout/html/base/src/nsImageMap.cpp +++ b/mozilla/layout/html/base/src/nsImageMap.cpp @@ -63,13 +63,18 @@ #include "nsIViewManager.h" #include "nsCoord.h" #include "nsIImageMap.h" +#include "nsIConsoleService.h" +#include "nsIScriptError.h" +#include "nsIStringBundle.h" + +static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); class Area { public: Area(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL); virtual ~Area(); - void ParseCoords(const nsString& aSpec); + virtual void ParseCoords(const nsString& aSpec); virtual PRBool IsInside(nscoord x, nscoord y) = 0; virtual void Draw(nsIPresContext* aCX, @@ -436,6 +441,7 @@ public: RectArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL); ~RectArea(); + virtual void ParseCoords(const nsString& aSpec); virtual PRBool IsInside(nscoord x, nscoord y); virtual void Draw(nsIPresContext* aCX, nsIRenderingContext& aRC); @@ -452,6 +458,82 @@ RectArea::~RectArea() { } +void RectArea::ParseCoords(const nsString& aSpec) +{ + Area::ParseCoords(aSpec); + + PRBool saneRect = PR_TRUE; + PRInt32 flag = nsIScriptError::warningFlag; + if (mNumCoords >= 4) { + if (mCoords[0] > mCoords[2]) { + // x-coords in reversed order + nscoord x = mCoords[2]; + mCoords[2] = mCoords[0]; + mCoords[0] = x; + saneRect = PR_FALSE; + } + + if (mCoords[1] > mCoords[3]) { + // y-coords in reversed order + nscoord y = mCoords[3]; + mCoords[3] = mCoords[1]; + mCoords[1] = y; + saneRect = PR_FALSE; + } + + if (mNumCoords > 4) { + // Someone missed the concept of a rect here + saneRect = PR_FALSE; + } + } else { + saneRect = PR_FALSE; + flag = nsIScriptError::errorFlag; + } + + if (!saneRect) { + // Report the error to the console. + nsresult rv; + nsCOMPtr consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return; + nsCOMPtr errorObject = + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return; + nsCOMPtr stringBundleService = + do_GetService(kCStringBundleServiceCID, &rv); + if (NS_FAILED(rv)) + return; + nsCOMPtr bundle; + rv = stringBundleService->CreateBundle( + "chrome://global/locale/layout_errors.properties", + getter_AddRefs(bundle)); + if (NS_FAILED(rv)) + return; + nsXPIDLString errorText; + const PRUnichar* flatSpec = aSpec.get(); + rv = + bundle->FormatStringFromName(NS_LITERAL_STRING("ImageMapRectBoundsError").get(), + &flatSpec, 1, + getter_Copies(errorText)); + if (NS_FAILED(rv)) + return; + + rv = errorObject->Init(errorText.get(), + NS_LITERAL_STRING("").get(), /* file name */ + NS_LITERAL_STRING("").get(), /* source line */ + 0, /* line number */ + 0, /* column number */ + flag, + "ImageMap"); + if (NS_FAILED(rv)) + return; + + consoleService->LogMessage(errorObject); + } +} + PRBool RectArea::IsInside(nscoord x, nscoord y) { if (mNumCoords >= 4) { // Note: > is for nav compatabilty @@ -459,10 +541,8 @@ PRBool RectArea::IsInside(nscoord x, nscoord y) nscoord y1 = mCoords[1]; nscoord x2 = mCoords[2]; nscoord y2 = mCoords[3]; - if ((x1 > x2)|| (y1 > y2)) { - // Can't be inside a screwed up rect - return PR_FALSE; - } + NS_ASSERTION(x1 <= x2 && y1 <= y2, + "Someone screwed up RectArea::ParseCoords"); if ((x >= x1) && (x <= x2) && (y >= y1) && (y <= y2)) { return PR_TRUE; } @@ -480,9 +560,8 @@ void RectArea::Draw(nsIPresContext* aCX, nsIRenderingContext& aRC) nscoord y1 = NSIntPixelsToTwips(mCoords[1], p2t); nscoord x2 = NSIntPixelsToTwips(mCoords[2], p2t); nscoord y2 = NSIntPixelsToTwips(mCoords[3], p2t); - if ((x1 > x2)|| (y1 > y2)) { - return; - } + NS_ASSERTION(x1 <= x2 && y1 <= y2, + "Someone screwed up RectArea::ParseCoords"); aRC.DrawLine(x1, y1, x1, y2); aRC.DrawLine(x1, y2, x2, y2); aRC.DrawLine(x1, y1, x2, y1); @@ -500,9 +579,8 @@ void RectArea::GetRect(nsIPresContext* aCX, nsRect& aRect) nscoord y1 = NSIntPixelsToTwips(mCoords[1], p2t); nscoord x2 = NSIntPixelsToTwips(mCoords[2], p2t); nscoord y2 = NSIntPixelsToTwips(mCoords[3], p2t); - if ((x1 > x2)|| (y1 > y2)) { - return; - } + NS_ASSERTION(x1 <= x2 && y1 <= y2, + "Someone screwed up RectArea::ParseCoords"); nsRect tmp(x1, y1, x2, y2); aRect = tmp; @@ -961,9 +1039,15 @@ nsImageMap::AddArea(nsIContent* aArea) shape.EqualsIgnoreCase("circ")) { area = new CircleArea(aArea, suppress, hasURL); } - else { + else if (shape.EqualsIgnoreCase("default")) { area = new DefaultArea(aArea, suppress, hasURL); } + else { + // Unknown area type; bail + return NS_OK; + } + if (!area) + return NS_ERROR_OUT_OF_MEMORY; area->ParseCoords(coords); mAreas.AppendElement(area); return NS_OK;