[haiku-commits] haiku: hrev44902 - src/kits/interface

  • From: zooey@xxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 26 Nov 2012 11:36:48 +0100 (CET)

hrev44902 adds 1 changeset to branch 'master'
old head: 1a58fe65ee33a31ec6dc60ea414c1724aeca9c21
new head: c077f5002f86850a9f57ac61cd826c7fa40ecdd6
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=c077f50+%5E1a58fe6

----------------------------------------------------------------------------

c077f50: Fix #9217 - BTextView should clamp given offsets to avoid crashes
  
  * applied patch provided with ticket, thanks!
  * extended patch to implement offset clamping for all public methods
    of BTextView and remove some checks from private methods to define
    a clear baseline for sanity of offsets used in the code

                                    [ Oliver Tappe <zooey@xxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev44902
Commit:      c077f5002f86850a9f57ac61cd826c7fa40ecdd6
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c077f50
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Mon Nov 26 10:35:30 2012 UTC

Ticket:      https://dev.haiku-os.org/ticket/9217

----------------------------------------------------------------------------

1 file changed, 115 insertions(+), 42 deletions(-)
src/kits/interface/TextView.cpp | 157 ++++++++++++++++++++++++++----------

----------------------------------------------------------------------------

diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp
index cb08c8d..9a027c9 100644
--- a/src/kits/interface/TextView.cpp
+++ b/src/kits/interface/TextView.cpp
@@ -1258,6 +1258,11 @@ void
 BTextView::Insert(int32 startOffset, const char *inText, int32 inLength,
                                           const text_run_array *inRuns)
 {
+       // pin offset at reasonable values
+       if (startOffset < 0)
+               startOffset = 0;
+       else if (startOffset > fText->Length())
+               startOffset = fText->Length();
        if (inText != NULL && inLength > 0)
                _DoInsertText(inText, strnlen(inText, inLength), startOffset, 
inRuns);
 }
@@ -1280,6 +1285,17 @@ void
 BTextView::Delete(int32 startOffset, int32 endOffset)
 {
        CALLED();
+
+       // pin offsets at reasonable values
+       if (startOffset < 0)
+               startOffset = 0;
+       else if (startOffset > fText->Length())
+               startOffset = fText->Length();
+       if (endOffset < 0)
+               endOffset = 0;
+       else if (endOffset > fText->Length())
+               endOffset = fText->Length();
+
        // anything to delete?
        if (startOffset == endOffset)
                return;
@@ -1544,18 +1560,20 @@ BTextView::Select(int32 startOffset, int32 endOffset)
 
        _CancelInputMethod();
 
-       // a negative selection?
-       if (startOffset > endOffset)
-               return;
-
        // pin offsets at reasonable values
        if (startOffset < 0)
                startOffset = 0;
+       else if (startOffset > fText->Length())
+               startOffset = fText->Length();
        if (endOffset < 0)
                endOffset = 0;
        else if (endOffset > fText->Length())
                endOffset = fText->Length();
 
+       // a negative selection?
+       if (startOffset > endOffset)
+               return;
+
        // is the new selection any different from the current selection?
        if (startOffset == fSelStart && endOffset == fSelEnd)
                return;
@@ -1733,6 +1751,16 @@ BTextView::SetRunArray(int32 startOffset, int32 
endOffset,
                oneRun.runs[0] = inRuns->runs[0];
                oneRun.runs[0].offset = 0;
                runs = &oneRun;
+       } else {
+               // pin offsets at reasonable values
+               if (startOffset < 0)
+                       startOffset = 0;
+               else if (startOffset > fText->Length())
+                       startOffset = fText->Length();
+               if (endOffset < 0)
+                       endOffset = 0;
+               else if (endOffset > fText->Length())
+                       endOffset = fText->Length();
        }
 
        _SetRunArray(startOffset, endOffset, runs);
@@ -1754,6 +1782,16 @@ BTextView::SetRunArray(int32 startOffset, int32 
endOffset,
 text_run_array *
 BTextView::RunArray(int32 startOffset, int32 endOffset, int32 *outSize) const
 {
+       // pin offsets at reasonable values
+       if (startOffset < 0)
+               startOffset = 0;
+       else if (startOffset > fText->Length())
+               startOffset = fText->Length();
+       if (endOffset < 0)
+               endOffset = 0;
+       else if (endOffset > fText->Length())
+               endOffset = fText->Length();
+
        STEStyleRange* styleRange = fStyles->GetStyleRange(startOffset,
                endOffset - 1);
        if (styleRange == NULL)
@@ -1781,6 +1819,12 @@ BTextView::RunArray(int32 startOffset, int32 endOffset, 
int32 *outSize) const
 int32
 BTextView::LineAt(int32 offset) const
 {
+       // pin offset at reasonable values
+       if (offset < 0)
+               offset = 0;
+       else if (offset > fText->Length())
+               offset = fText->Length();
+
        int32 lineNum = _LineAt(offset);
        if (_IsOnEmptyLastLine(offset))
                lineNum++;
@@ -1811,6 +1855,12 @@ BTextView::LineAt(BPoint point) const
 BPoint
 BTextView::PointAt(int32 inOffset, float *outHeight) const
 {
+       // pin offset at reasonable values
+       if (inOffset < 0)
+               inOffset = 0;
+       else if (inOffset > fText->Length())
+               inOffset = fText->Length();
+
        // TODO: Cleanup.
        int32 lineNum = _LineAt(inOffset);
        STELine* line = (*fLines)[lineNum];
@@ -1971,6 +2021,21 @@ BTextView::OffsetAt(int32 line) const
 void
 BTextView::FindWord(int32 inOffset, int32 *outFromOffset, int32 *outToOffset)
 {
+       if (inOffset < 0) {
+               if (outFromOffset)
+                       *outFromOffset = 0;
+               if (outToOffset)
+                       *outToOffset = 0;
+               return;
+       }
+       if (inOffset > fText->Length()) {
+               if (outFromOffset)
+                       *outFromOffset = fText->Length();
+               if (outToOffset)
+                       *outToOffset = fText->Length();
+               return;
+       }
+
        if (outFromOffset)
                *outFromOffset = _PreviousWordBoundary(inOffset);
 
@@ -2100,7 +2165,11 @@ BTextView::TextHeight(int32 startLine, int32 endLine) 
const
        const int32 numLines = fLines->NumLines();
        if (startLine < 0)
                startLine = 0;
-       if (endLine > numLines - 1)
+       else if (startLine > numLines - 1)
+               startLine = numLines - 1;
+       if (endLine < 0)
+               endLine = 0;
+       else if (endLine > numLines - 1)
                endLine = numLines - 1;
 
        float height = (*fLines)[endLine + 1]->origin
@@ -2123,6 +2192,16 @@ BTextView::GetTextRegion(int32 startOffset, int32 
endOffset,
 
        outRegion->MakeEmpty();
 
+       // pin offsets at reasonable values
+       if (startOffset < 0)
+               startOffset = 0;
+       else if (startOffset > fText->Length())
+               startOffset = fText->Length();
+       if (endOffset < 0)
+               endOffset = 0;
+       else if (endOffset > fText->Length())
+               endOffset = fText->Length();
+
        // return an empty region if the range is invalid
        if (startOffset >= endOffset)
                return;
@@ -2177,6 +2256,12 @@ BTextView::GetTextRegion(int32 startOffset, int32 
endOffset,
 void
 BTextView::ScrollToOffset(int32 inOffset)
 {
+       // pin offset at reasonable values
+       if (inOffset < 0)
+               inOffset = 0;
+       else if (inOffset > fText->Length())
+               inOffset = fText->Length();
+
        BRect bounds = Bounds();
        float lineHeight = 0.0;
        float xDiff = 0.0;
@@ -2228,7 +2313,16 @@ BTextView::ScrollToSelection()
 void
 BTextView::Highlight(int32 startOffset, int32 endOffset)
 {
-       // get real
+       // pin offsets at reasonable values
+       if (startOffset < 0)
+               startOffset = 0;
+       else if (startOffset > fText->Length())
+               startOffset = fText->Length();
+       if (endOffset < 0)
+               endOffset = 0;
+       else if (endOffset > fText->Length())
+               endOffset = fText->Length();
+
        if (startOffset >= endOffset)
                return;
 
@@ -3105,8 +3199,17 @@ void
 BTextView::DeleteText(int32 fromOffset, int32 toOffset)
 {
        CALLED();
-       // sanity checking
-       if (fromOffset >= toOffset || fromOffset < 0 || toOffset > 
fText->Length())
+
+       if (fromOffset < 0)
+               fromOffset = 0;
+       else if (fromOffset > fText->Length())
+               fromOffset = fText->Length();
+       if (toOffset < 0)
+               toOffset = 0;
+       else if (toOffset > fText->Length())
+               toOffset = fText->Length();
+
+       if (fromOffset >= toOffset)
                return;
 
        // set nullStyle to style at beginning of range
@@ -4023,9 +4126,6 @@ BTextView::_FindLineBreak(int32 fromOffset, float 
*outAscent, float *outDescent,
 int32
 BTextView::_PreviousWordBoundary(int32 offset)
 {
-       if (offset <= 0)
-               return 0;
-
        uint32 charType = _CharClassification(offset);
        int32 previous;
        while (offset > 0) {
@@ -4042,10 +4142,7 @@ BTextView::_PreviousWordBoundary(int32 offset)
 int32
 BTextView::_NextWordBoundary(int32 offset)
 {
-       int32 textLen = TextLength();
-       if (offset >= textLen)
-               return textLen;
-
+       int32 textLen = fText->Length();
        uint32 charType = _CharClassification(offset);
        while (offset < textLen) {
                offset = _NextInitialByte(offset);
@@ -4087,10 +4184,7 @@ BTextView::_PreviousWordStart(int32 offset)
 int32
 BTextView::_NextWordEnd(int32 offset)
 {
-       int32 textLen = TextLength();
-       if (offset >= textLen)
-               return textLen;
-
+       int32 textLen = fText->Length();
        if (_CharClassification(offset) != CHAR_CLASS_DEFAULT) {
                // skip non-word characters
                while (offset < textLen) {
@@ -4497,10 +4591,6 @@ BTextView::_RequestDrawLines(int32 startLine, int32 
endLine)
                return;
 
        long maxLine = fLines->NumLines() - 1;
-       if (startLine < 0)
-               startLine = 0;
-       if (endLine > maxLine)
-               endLine = maxLine;
 
        STELine *from = (*fLines)[startLine];
        STELine *to = endLine == maxLine ? NULL : (*fLines)[endLine + 1];
@@ -5142,22 +5232,6 @@ void
 BTextView::_SetRunArray(int32 startOffset, int32 endOffset,
        const text_run_array *inRuns)
 {
-       if (startOffset > endOffset)
-               return;
-
-       const int32 textLength = fText->Length();
-
-       // pin offsets at reasonable values
-       if (startOffset < 0)
-               startOffset = 0;
-       else if (startOffset > textLength)
-               startOffset = textLength;
-
-       if (endOffset < 0)
-               endOffset = 0;
-       else if (endOffset > textLength)
-               endOffset = textLength;
-
        const int32 numStyles = inRuns->count;
        if (numStyles > 0) {
                const text_run *theRun = &inRuns->runs[0];
@@ -5255,9 +5329,8 @@ BTextView::_CharClassification(int32 offset) const
 int32
 BTextView::_NextInitialByte(int32 offset) const
 {
-       int32 textLength = TextLength();
-       if (offset >= textLength)
-               return textLength;
+       if (offset >= fText->Length())
+               return offset;
 
        for (++offset; (ByteAt(offset) & 0xC0) == 0x80; ++offset)
                ;


Other related posts:

  • » [haiku-commits] haiku: hrev44902 - src/kits/interface - zooey