Bug 162546 and bug 141883. Better handling of unknown area shapes and

more graceful handling of bogus rect coords.  r=jkeiser, sr=roc.
This commit is contained in:
bzbarsky%mit.edu 2002-08-27 20:49:54 +00:00
Родитель 21215a45c0
Коммит 06eb5d78dd
5 изменённых файлов: 232 добавлений и 24 удалений

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

@ -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<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIStringBundleService> stringBundleService =
do_GetService(kCStringBundleServiceCID, &rv);
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIStringBundle> 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;

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

@ -57,6 +57,7 @@ REQUIRES = xpcom \
xpconnect \
java \
exthandler \
intl \
$(NULL)
# Sun's Complex Text Layout support

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

@ -1,3 +1,4 @@
en-US.jar:
locale/en-US/global/printing.properties
locale/en-US/global/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 <bzbarsky@mit.edu> (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 <area shape="rect" coords="%S"> is not in the "left,top,right,bottom" format.

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

@ -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<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIStringBundleService> stringBundleService =
do_GetService(kCStringBundleServiceCID, &rv);
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIStringBundle> 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;