bug 715471 - use fallible allocation for potentially large buffers in nsTextFrameThebes.cpp. r=roc

This commit is contained in:
Jonathan Kew 2012-01-13 10:35:02 +00:00
parent 2c90f7fcba
commit b028150574

View File

@ -838,7 +838,7 @@ public:
* we constructed just a partial textrun to set up linebreaker and other
* state for following textruns.
*/
gfxTextRun* BuildTextRunForFrames(void* aTextBuffer);
gfxTextRun* BuildTextRunForFrames();
bool SetupLineBreakerContext(gfxTextRun *aTextRun);
void AssignTextRun(gfxTextRun* aTextRun);
nsTextFrame* GetNextBreakBeforeFrame(PRUint32* aIndex);
@ -1383,13 +1383,10 @@ void BuildTextRunsScanner::FlushFrames(bool aFlushLineBreaks, bool aSuppressTrai
mNextRunContextInfo |= nsTextFrameUtils::INCOMING_ARABICCHAR;
}
} else {
nsAutoTArray<PRUint8,BIG_TEXT_NODE_SIZE> buffer;
PRUint32 bufferSize = mMaxTextLength*(mDoubleByteText ? 2 : 1);
if (bufferSize < mMaxTextLength || bufferSize == PR_UINT32_MAX ||
!buffer.AppendElements(bufferSize)) {
textRun = BuildTextRunForFrames();
if (!textRun) {
return;
}
textRun = BuildTextRunForFrames(buffer.Elements());
}
}
@ -1722,11 +1719,20 @@ static const nsTextFrameUtils::CompressionMode CSSWhitespaceToCompressionMode[]
};
gfxTextRun*
BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
BuildTextRunsScanner::BuildTextRunForFrames()
{
gfxSkipCharsBuilder builder;
const void* textPtr = aTextBuffer;
AutoFallibleTArray<PRUint8,BIG_TEXT_NODE_SIZE> buffer;
PRUint32 bufferSize = mMaxTextLength * (mDoubleByteText ? 2 : 1);
if (bufferSize < mMaxTextLength || bufferSize == PR_UINT32_MAX) {
return nsnull;
}
void* textPtr = buffer.AppendElements(bufferSize);
if (!textPtr) {
return nsnull;
}
bool anySmallcapsStyle = false;
bool anyTextTransformStyle = false;
PRUint32 textFlags = nsTextFrameUtils::TEXT_NO_BREAKS;
@ -1816,38 +1822,38 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
PRUint32 analysisFlags;
if (frag->Is2b()) {
NS_ASSERTION(mDoubleByteText, "Wrong buffer char size!");
PRUnichar* bufStart = static_cast<PRUnichar*>(aTextBuffer);
PRUnichar* bufStart = static_cast<PRUnichar*>(textPtr);
PRUnichar* bufEnd = nsTextFrameUtils::TransformText(
frag->Get2b() + contentStart, contentLength, bufStart,
compression, &mNextRunContextInfo, &builder, &analysisFlags);
aTextBuffer = bufEnd;
textPtr = bufEnd;
} else {
if (mDoubleByteText) {
// Need to expand the text. First transform it into a temporary buffer,
// then expand.
nsAutoTArray<PRUint8,BIG_TEXT_NODE_SIZE> tempBuf;
if (!tempBuf.AppendElements(contentLength)) {
AutoFallibleTArray<PRUint8,BIG_TEXT_NODE_SIZE> tempBuf;
PRUint8* bufStart = tempBuf.AppendElements(contentLength);
if (!bufStart) {
DestroyUserData(userDataToDestroy);
return nsnull;
}
PRUint8* bufStart = tempBuf.Elements();
PRUint8* end = nsTextFrameUtils::TransformText(
reinterpret_cast<const PRUint8*>(frag->Get1b()) + contentStart, contentLength,
bufStart, compression, &mNextRunContextInfo, &builder, &analysisFlags);
aTextBuffer = ExpandBuffer(static_cast<PRUnichar*>(aTextBuffer),
textPtr = ExpandBuffer(static_cast<PRUnichar*>(textPtr),
tempBuf.Elements(), end - tempBuf.Elements());
} else {
PRUint8* bufStart = static_cast<PRUint8*>(aTextBuffer);
PRUint8* bufStart = static_cast<PRUint8*>(textPtr);
PRUint8* end = nsTextFrameUtils::TransformText(
reinterpret_cast<const PRUint8*>(frag->Get1b()) + contentStart, contentLength,
bufStart, compression, &mNextRunContextInfo, &builder, &analysisFlags);
aTextBuffer = end;
textPtr = end;
}
}
textFlags |= analysisFlags;
currentTransformedTextOffset =
(static_cast<const PRUint8*>(aTextBuffer) - static_cast<const PRUint8*>(textPtr)) >> mDoubleByteText;
(static_cast<PRUint8*>(textPtr) - buffer.Elements()) >> mDoubleByteText;
}
// Check for out-of-memory in gfxSkipCharsBuilder
@ -2029,11 +2035,13 @@ BuildTextRunsScanner::SetupLineBreakerContext(gfxTextRun *aTextRun)
{
AutoFallibleTArray<PRUint8,BIG_TEXT_NODE_SIZE> buffer;
PRUint32 bufferSize = mMaxTextLength*(mDoubleByteText ? 2 : 1);
if (bufferSize < mMaxTextLength || bufferSize == PR_UINT32_MAX ||
!buffer.AppendElements(bufferSize)) {
if (bufferSize < mMaxTextLength || bufferSize == PR_UINT32_MAX) {
return false;
}
void *textPtr = buffer.AppendElements(bufferSize);
if (!textPtr) {
return false;
}
void *textPtr = buffer.Elements();
gfxSkipCharsBuilder builder;
@ -2106,11 +2114,11 @@ BuildTextRunsScanner::SetupLineBreakerContext(gfxTextRun *aTextRun)
// Need to expand the text. First transform it into a temporary buffer,
// then expand.
AutoFallibleTArray<PRUint8,BIG_TEXT_NODE_SIZE> tempBuf;
if (!tempBuf.AppendElements(contentLength)) {
PRUint8* bufStart = tempBuf.AppendElements(contentLength);
if (!bufStart) {
DestroyUserData(userDataToDestroy);
return false;
}
PRUint8* bufStart = tempBuf.Elements();
PRUint8* end = nsTextFrameUtils::TransformText(
reinterpret_cast<const PRUint8*>(frag->Get1b()) + contentStart, contentLength,
bufStart, compression, &mNextRunContextInfo, &builder, &analysisFlags);
@ -5098,10 +5106,12 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
const nsCharClipDisplayItem::ClipEdges& aClipEdges)
{
// Figure out which selections control the colors to use for each character.
nsAutoTArray<SelectionDetails*,BIG_TEXT_NODE_SIZE> prevailingSelectionsBuffer;
if (!prevailingSelectionsBuffer.AppendElements(aContentLength))
AutoFallibleTArray<SelectionDetails*,BIG_TEXT_NODE_SIZE> prevailingSelectionsBuffer;
SelectionDetails** prevailingSelections =
prevailingSelectionsBuffer.AppendElements(aContentLength);
if (!prevailingSelections) {
return false;
SelectionDetails** prevailingSelections = prevailingSelectionsBuffer.Elements();
}
SelectionType allTypes = 0;
for (PRUint32 i = 0; i < aContentLength; ++i) {
@ -5221,10 +5231,12 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
return;
// Figure out which characters will be decorated for this selection.
nsAutoTArray<SelectionDetails*, BIG_TEXT_NODE_SIZE> selectedCharsBuffer;
if (!selectedCharsBuffer.AppendElements(aContentLength))
AutoFallibleTArray<SelectionDetails*, BIG_TEXT_NODE_SIZE> selectedCharsBuffer;
SelectionDetails** selectedChars =
selectedCharsBuffer.AppendElements(aContentLength);
if (!selectedChars) {
return;
SelectionDetails** selectedChars = selectedCharsBuffer.Elements();
}
for (PRUint32 i = 0; i < aContentLength; ++i) {
selectedChars[i] = nsnull;
}
@ -6600,7 +6612,7 @@ nsTextFrame::AddInlineMinWidthForFlow(nsRenderingContext *aRenderingContext,
PRUint32 start =
FindStartAfterSkippingWhitespace(&provider, aData, textStyle, &iter, flowEndInTextRun);
nsAutoTArray<bool,BIG_TEXT_NODE_SIZE> hyphBuffer;
AutoFallibleTArray<bool,BIG_TEXT_NODE_SIZE> hyphBuffer;
bool *hyphBreakBefore = nsnull;
if (hyphenating) {
hyphBreakBefore = hyphBuffer.AppendElements(flowEndInTextRun - start);