Bug 647480 - Don't try to create a textrun using a null font. Setup a default font also when there is no pres shell. r=jfkthame

This commit is contained in:
Mats Palmgren 2011-04-10 22:01:01 +02:00
parent 51c54bf6a6
commit a704143976
3 changed files with 155 additions and 30 deletions

View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
var ctx = canvas.getContext("2d");
document.implementation.createDocument("", "", null).adoptNode(canvas);
try { ctx.save(); } catch(e){}
try { ctx.restore(); } catch(e){}
try { ctx.scale(0,0); } catch(e){}
try { ctx.rotate(90); } catch(e){}
try { ctx.translate(1,1); } catch(e){}
try { ctx.transform(0,100,200,300,10,10); } catch(e){}
try { ctx.setTransform(0,100,200,300,10,10); } catch(e){}
try { x = ctx.globalAlpha; } catch(e){}
try { ctx.globalAlpha = 0.8; } catch(e){}
try { x = ctx.globalCompositeOperation; } catch(e){}
try { ctx.globalCompositeOperation = "copy"; } catch(e){}
try { x = ctx.strokeStyle; } catch(e){}
try { ctx.strokeStyle = "red"; } catch(e){}
try { x = ctx.fillStyle; } catch(e){}
try { ctx.fillStyle = "red"; } catch(e){}
try { ctx.createLinearGradient(0,100,100,100); } catch(e){}
try { ctx.createRadialGradient(0,100,100,100,10,10); } catch(e){}
try { ctx.createPattern(document.getElementsByTagName('img')[0], "repeat"); } catch(e){}
try { x = ctx.lineWidth; } catch(e){}
try { ctx.lineWidth = 2; } catch(e){}
try { x = ctx.lineCap; } catch(e){}
try { ctx.lineCap = "round"; } catch(e){}
try { x = ctx.lineJoin; } catch(e){}
try { ctx.lineJoin = "bevel"; } catch(e){}
try { x = ctx.miterLimit; } catch(e){}
try { ctx.miterLimit = 12; } catch(e){}
try { x = ctx.shadowOffsetX; } catch(e){}
try { ctx.shadowOffsetX = 1; } catch(e){}
try { x = ctx.shadowOffsetY; } catch(e){}
try { ctx.shadowOffsetY = 1; } catch(e){}
try { x = ctx.shadowBlur; } catch(e){}
try { ctx.shadowBlur = 1; } catch(e){}
try { x = ctx.shadowColor; } catch(e){}
try { ctx.shadowColor = "red"; } catch(e){}
try { ctx.clearRect(0,0,100,100); } catch(e){}
try { ctx.fillRect(0,0,100,100); } catch(e){}
try { ctx.strokeRect(0,0,100,100); } catch(e){}
try { ctx.beginPath(); } catch(e){}
try { ctx.moveTo(1,1); } catch(e){}
try { ctx.lineTo(10,10); } catch(e){}
try { ctx.quadraticCurveTo(1,2,3,4); } catch(e){}
try { ctx.bezierCurveTo(1,2,3,4,5,6); } catch(e){}
try { ctx.arcTo(1,2,3,4,5); } catch(e){}
try { ctx.arc(1,2,3,4,5); } catch(e){}
try { ctx.arc(1,2,3,4,5,true); } catch(e){}
try { ctx.rect(1,2,3,4); } catch(e){}
try { ctx.closePath(); } catch(e){}
try { ctx.fill(); } catch(e){}
try { ctx.stroke(); } catch(e){}
try { ctx.clip(); } catch(e){}
try { x = ctx.font; } catch(e){}
try { ctx.font = "14px sans-serif"; } catch(e){}
try { x = ctx.mozTextStyle; } catch(e){}
try { ctx.mozTextStyle = "14px sans-serif"; } catch(e){}
try { x = ctx.textAlign; } catch(e){}
try { ctx.textAlign = "right"; } catch(e){}
try { x = ctx.textBaseline; } catch(e){}
try { ctx.textBaseline = "top"; } catch(e){}
try { ctx.fillText("",0,0); } catch(e){}
try { ctx.strokeText("",0,0); } catch(e){}
try { ctx.measureText(""); } catch(e){}
try { ctx.mozDrawText(""); } catch(e){}
try { ctx.mozPathText(""); } catch(e){}
try { ctx.mozTextAlongPath("",true); } catch(e){}
try { ctx.mozTextAlongPath("",false); } catch(e){}
try { ctx.drawImage(document.getElementsByTagName('img')[0], 0, 0); } catch(e){}
try { ctx.isPointInPath(0, 0); } catch(e){}
try { ctx.createImageData(); } catch(e){}
try { ctx.getImageData(); } catch(e){}
try { ctx.putImageData(); } catch(e){}
try { x = ctx.mozImageSmoothingEnabled; } catch(e){}
try { ctx.mozImageSmoothingEnabled = false; } catch(e){}
try { ctx.mozImageSmoothingEnabled = true; } catch(e){}
try { ctx.drawWindow(window, 0, 0, 0, 0, "red"); } catch(e){}
}
</script>
</head>
<body onload="boom();"><img width="100" height="100" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs="></body>
</html>

View File

@ -1,3 +1,4 @@
load 360293-1.html
load 421715-1.html
load 553938-1.html
load 647480.html

View File

@ -127,6 +127,10 @@ using namespace mozilla;
using namespace mozilla::layers;
using namespace mozilla::dom;
static float kDefaultFontSize = 10.0;
static NS_NAMED_LITERAL_STRING(kDefaultFontName, "sans-serif");
static NS_NAMED_LITERAL_STRING(kDefaultFontStyle, "10px sans-serif");
/* Float validation stuff */
#define VALIDATE(_f) if (!NS_finite(_f)) return PR_FALSE
@ -645,7 +649,11 @@ protected:
TEXT_BASELINE_BOTTOM
};
gfxFontGroup *GetCurrentFontStyle();
gfxFontGroup* GetCurrentFontStyle();
gfxTextRun* MakeTextRun(const PRUnichar* aText,
PRUint32 aLength,
PRUint32 aAppUnitsPerDevUnit,
PRUint32 aFlags);
enum TextDrawOperation {
TEXT_DRAW_OPERATION_FILL,
@ -2292,9 +2300,9 @@ nsCanvasRenderingContext2D::SetFont(const nsAString& font)
nsnull,
presShell);
} else {
// otherwise inherit from default (10px sans-serif)
// otherwise inherit from default
nsRefPtr<css::StyleRule> parentRule;
rv = CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
rv = CreateFontStyleRule(kDefaultFontStyle,
document,
getter_AddRefs(parentRule));
if (NS_FAILED(rv))
@ -2887,20 +2895,47 @@ nsCanvasRenderingContext2D::GetMozTextStyle(nsAString& textStyle)
return GetFont(textStyle);
}
gfxFontGroup *nsCanvasRenderingContext2D::GetCurrentFontStyle()
gfxFontGroup*
nsCanvasRenderingContext2D::GetCurrentFontStyle()
{
// use lazy initilization for the font group since it's rather expensive
if(!CurrentState().fontGroup) {
#ifdef DEBUG
nsresult res =
#endif
SetMozTextStyle(NS_LITERAL_STRING("10px sans-serif"));
NS_ASSERTION(res == NS_OK, "Default canvas font is invalid");
nsresult rv = SetMozTextStyle(kDefaultFontStyle);
if (NS_FAILED(rv)) {
gfxFontStyle style;
style.size = kDefaultFontSize;
CurrentState().fontGroup =
gfxPlatform::GetPlatform()->CreateFontGroup(kDefaultFontName,
&style,
nsnull);
if (CurrentState().fontGroup) {
CurrentState().font = kDefaultFontStyle;
rv = NS_OK;
} else {
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
NS_ASSERTION(NS_SUCCEEDED(rv), "Default canvas font is invalid");
}
return CurrentState().fontGroup;
}
gfxTextRun*
nsCanvasRenderingContext2D::MakeTextRun(const PRUnichar* aText,
PRUint32 aLength,
PRUint32 aAppUnitsPerDevUnit,
PRUint32 aFlags)
{
gfxFontGroup* currentFontStyle = GetCurrentFontStyle();
if (!currentFontStyle)
return nsnull;
return gfxTextRunCache::MakeTextRun(aText, aLength, currentFontStyle,
mThebes, aAppUnitsPerDevUnit, aFlags);
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::MozDrawText(const nsAString& textToDraw)
{
@ -2912,13 +2947,8 @@ nsCanvasRenderingContext2D::MozDrawText(const nsAString& textToDraw)
PRUint32 aupdp;
GetAppUnitsValues(&aupdp, NULL);
gfxTextRunCache::AutoTextRun textRun;
textRun = gfxTextRunCache::MakeTextRun(textdata,
textToDraw.Length(),
GetCurrentFontStyle(),
mThebes,
aupdp,
textrunflags);
gfxTextRunCache::AutoTextRun textRun =
MakeTextRun(textdata, textToDraw.Length(), aupdp, textrunflags);
if(!textRun.get())
return NS_ERROR_FAILURE;
@ -2960,13 +2990,8 @@ nsCanvasRenderingContext2D::MozPathText(const nsAString& textToPath)
PRUint32 aupdp;
GetAppUnitsValues(&aupdp, NULL);
gfxTextRunCache::AutoTextRun textRun;
textRun = gfxTextRunCache::MakeTextRun(textdata,
textToPath.Length(),
GetCurrentFontStyle(),
mThebes,
aupdp,
textrunflags);
gfxTextRunCache::AutoTextRun textRun =
MakeTextRun(textdata, textToPath.Length(), aupdp, textrunflags);
if(!textRun.get())
return NS_ERROR_FAILURE;
@ -2996,13 +3021,8 @@ nsCanvasRenderingContext2D::MozTextAlongPath(const nsAString& textToDraw, PRBool
PRUint32 aupdp;
GetAppUnitsValues(&aupdp, NULL);
gfxTextRunCache::AutoTextRun textRun;
textRun = gfxTextRunCache::MakeTextRun(textdata,
textToDraw.Length(),
GetCurrentFontStyle(),
mThebes,
aupdp,
textrunflags);
gfxTextRunCache::AutoTextRun textRun =
MakeTextRun(textdata, textToDraw.Length(), aupdp, textrunflags);
if(!textRun.get())
return NS_ERROR_FAILURE;