зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1402109. Prevent crashes under SVGTextElement methods when the SVG is under non-displayed HTML. r=heycam
Summary: The implementations of most SVGTextElement methods flush layout when they're called. Any SVG <text> that is displayed normally will be reflowed by SVGTextFrame::ReflowSVG, and any <text> that is in displayed SVG but is not displayed directly (such as <text> under a <defs>) will be reflowed by SVGTextFrame::ReflowSVGNonDisplayText. Prior to this fix the changed code always assumed that one of these methods would reflow the text. However, in the case that the SVG is under an HTML element that isn't itself ever reflowed (such as if it's under an HTML <caption>) then the SVG text will not be reflowed either and the invariants of the code are broken. This patch modifies the functions that implement the SVGTextElement methods to return an error code if the text has not been reflowed. Note: I did try to reuse SVGTextFrame::ReflowSVGNonDisplayText in this case, but I ran into problems. Given that this is an edge case and likely one than normal authors will never run into I gave up trying to make that work for now. Reviewers: heycam Bug #: 1402109 Differential Revision: https://phabricator.services.mozilla.com/D107
This commit is contained in:
Родитель
60fa0649f2
Коммит
0ed5f27b33
|
@ -3996,6 +3996,13 @@ SVGTextFrame::ConvertTextElementCharIndexToAddressableIndex(
|
|||
uint32_t
|
||||
SVGTextFrame::GetNumberOfChars(nsIContent* aContent)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return 0;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
uint32_t n = 0;
|
||||
|
@ -4040,6 +4047,13 @@ nsresult
|
|||
SVGTextFrame::SelectSubString(nsIContent* aContent,
|
||||
uint32_t charnum, uint32_t nchars)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
// Convert charnum/nchars from addressable characters relative to
|
||||
|
@ -4271,6 +4285,13 @@ int32_t
|
|||
SVGTextFrame::GetCharNumAtPosition(nsIContent* aContent,
|
||||
mozilla::nsISVGPoint* aPoint)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return -1;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
nsPresContext* context = PresContext();
|
||||
|
@ -4304,6 +4325,13 @@ SVGTextFrame::GetStartPositionOfChar(nsIContent* aContent,
|
|||
uint32_t aCharNum,
|
||||
mozilla::nsISVGPoint** aResult)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
CharIterator it(this, CharIterator::eAddressable, aContent);
|
||||
|
@ -4329,6 +4357,13 @@ SVGTextFrame::GetEndPositionOfChar(nsIContent* aContent,
|
|||
uint32_t aCharNum,
|
||||
mozilla::nsISVGPoint** aResult)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
CharIterator it(this, CharIterator::eAddressable, aContent);
|
||||
|
@ -4366,6 +4401,13 @@ SVGTextFrame::GetExtentOfChar(nsIContent* aContent,
|
|||
uint32_t aCharNum,
|
||||
dom::SVGIRect** aResult)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
CharIterator it(this, CharIterator::eAddressable, aContent);
|
||||
|
@ -4426,6 +4468,13 @@ SVGTextFrame::GetRotationOfChar(nsIContent* aContent,
|
|||
uint32_t aCharNum,
|
||||
float* aResult)
|
||||
{
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (NS_SUBTREE_DIRTY(kid)) {
|
||||
// We're never reflowed if we're under a non-SVG element that is
|
||||
// never reflowed (such as the HTML 'caption' element).
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UpdateGlyphPositioning();
|
||||
|
||||
CharIterator it(this, CharIterator::eAddressable, aContent);
|
||||
|
|
Загрузка…
Ссылка в новой задаче