summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-06-12 21:28:26 +0100
committerCaolán McNamara <caolanm@redhat.com>2018-06-13 15:28:21 +0200
commit39e75712b253430489089ed1d70f2ead1d7f6aa6 (patch)
tree1ed364ce905e3303ae810c97a68ce6840449028e /basic
parent011b7c54c000061f4abd5a54b47e5655f35473cf (diff)
valgrind: use OUString::operator to access into string
address some out of bounds oddness seen with rtl_ustr_getlength_heap_buffer_overflow.sample Change-Id: I5a9772de9607644f43e74174f73053d292ca7cc0 Reviewed-on: https://gerrit.libreoffice.org/55722 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'basic')
-rw-r--r--basic/source/comp/scanner.cxx115
-rw-r--r--basic/source/inc/scanner.hxx8
2 files changed, 64 insertions, 59 deletions
diff --git a/basic/source/comp/scanner.cxx b/basic/source/comp/scanner.cxx
index e79f145c29b9..bbe02978bb14 100644
--- a/basic/source/comp/scanner.cxx
+++ b/basic/source/comp/scanner.cxx
@@ -29,7 +29,7 @@
SbiScanner::SbiScanner( const OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
{
pBasic = p;
- pLine = nullptr;
+ nLineIdx = -1;
nVal = 0;
eScanType = SbxVARIANT;
nErrors = 0;
@@ -50,7 +50,7 @@ SbiScanner::SbiScanner( const OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
bInStatement =
bPrevLineExtentsComment = false;
bHash = true;
- pSaveLine = nullptr;
+ nSaveLineIdx = -1;
}
SbiScanner::~SbiScanner()
@@ -107,7 +107,7 @@ bool SbiScanner::DoesColonFollow()
{
if(nCol < aLine.getLength() && aLine[nCol] == ':')
{
- ++pLine; ++nCol;
+ ++nLineIdx; ++nCol;
return true;
}
else
@@ -145,7 +145,7 @@ void SbiScanner::scanAlphanumeric()
sal_Int32 n = nCol;
while(nCol < aLine.getLength() && (BasicCharClass::isAlphaNumeric(aLine[nCol], bCompatible) || aLine[nCol] == '_'))
{
- ++pLine;
+ ++nLineIdx;
++nCol;
}
aSym = aLine.copy(n, nCol - n);
@@ -163,7 +163,7 @@ void SbiScanner::scanGoto()
if(aTemp.equalsIgnoreAsciiCase("to"))
{
aSym = "goto";
- pLine += n + 2 - nCol;
+ nLineIdx += n + 2 - nCol;
nCol = n + 2;
}
}
@@ -194,7 +194,7 @@ bool SbiScanner::readLine()
++n;
nBufPos = n;
- pLine = aLine.getStr();
+ nLineIdx = 0;
++nLine;
nCol = nCol1 = nCol2 = 0;
@@ -217,7 +217,7 @@ bool SbiScanner::NextSym()
bool bCompilerDirective = false;
// read in line?
- if( !pLine )
+ if (nLineIdx == -1)
{
if(!readLine())
return false;
@@ -231,7 +231,7 @@ bool SbiScanner::NextSym()
bSpaces = true;
while(nCol < aLine.getLength() && BasicCharClass::isWhitespace(aLine[nCol]))
{
- ++pLine;
+ ++nLineIdx;
++nCol;
}
}
@@ -247,15 +247,15 @@ bool SbiScanner::NextSym()
if(nCol < aLine.getLength() && aLine[nCol] == '#')
{
- const sal_Unicode* pLineTemp = pLine;
+ sal_Int32 nLineTempIdx = nLineIdx;
do
{
- pLineTemp++;
- } while (*pLineTemp && !BasicCharClass::isWhitespace(*pLineTemp) && *pLineTemp != '#');
+ nLineTempIdx++;
+ } while (nLineTempIdx < aLine.getLength() && !BasicCharClass::isWhitespace(aLine[nLineTempIdx]) && aLine[nLineTempIdx] != '#');
// leave it if it is a date literal - it will be handled later
- if (*pLineTemp != '#')
+ if (nLineTempIdx >= aLine.getLength() || aLine[nLineTempIdx] != '#')
{
- ++pLine;
+ ++nLineIdx;
++nCol;
//ignore compiler directives (# is first non-space character)
if (nOldCol2 == 0)
@@ -272,7 +272,7 @@ bool SbiScanner::NextSym()
if(nCol + 1 == aLine.getLength() && aLine[nCol] == '_')
{
// Note that nCol is not incremented here...
- ++pLine;
+ ++nLineIdx;
goto eoln;
}
@@ -286,7 +286,7 @@ bool SbiScanner::NextSym()
// replace closing '_' by space when end of line is following
// (wrong line continuation otherwise)
- if(nCol == aLine.getLength() && aLine[nCol - 1] == '_' )
+ if (nCol == aLine.getLength() && aLine[nCol - 1] == '_')
{
// We are going to modify a potentially shared string, so force
// a copy, so that aSym is not modified by the following operation
@@ -294,7 +294,7 @@ bool SbiScanner::NextSym()
aSym = aSymCopy;
// HACK: modifying a potentially shared string here!
- *const_cast<sal_Unicode*>(pLine-1) = ' ';
+ const_cast<sal_Unicode*>(aLine.getStr())[nLineIdx - 1] = ' ';
}
// type recognition?
@@ -309,7 +309,7 @@ bool SbiScanner::NextSym()
if( t != SbxVARIANT )
{
eScanType = t;
- ++pLine;
+ ++nLineIdx;
++nCol;
}
}
@@ -332,7 +332,7 @@ bool SbiScanner::NextSym()
if( (p-buf) == (BUF_SIZE-1) )
{
bBufOverflow = true;
- ++pLine;
+ ++nLineIdx;
++nCol;
continue;
}
@@ -353,7 +353,7 @@ bool SbiScanner::NextSym()
*p++ = 'E';
if (nCol + 1 < aLine.getLength() && (aLine[nCol+1] == '+' || aLine[nCol+1] == '-'))
{
- ++pLine;
+ ++nLineIdx;
++nCol;
if( (p-buf) == (BUF_SIZE-1) )
{
@@ -368,7 +368,7 @@ bool SbiScanner::NextSym()
{
*p++ = aLine[nCol];
}
- ++pLine;
+ ++nLineIdx;
++nCol;
}
*p = 0;
@@ -378,7 +378,7 @@ bool SbiScanner::NextSym()
ErrCode nError = ERRCODE_NONE;
if (bScanError)
{
- --pLine;
+ --nLineIdx;
--nCol;
aError = OUString( aLine[nCol]);
nError = ERRCODE_BASIC_BAD_CHAR_IN_NUMBER;
@@ -391,9 +391,9 @@ bool SbiScanner::NextSym()
{
// e.g. "12e" or "12e+", or with bScanError "12d"+"E".
sal_Int32 nChars = buf+(p-buf) - pParseEnd;
- pLine -= nChars;
+ nLineIdx -= nChars;
nCol -= nChars;
- // For bScanError, pLine and nCol were already decremented, just
+ // For bScanError, nLineIdx and nCol were already decremented, just
// add that character to the parse end.
if (bScanError)
++nChars;
@@ -430,7 +430,7 @@ bool SbiScanner::NextSym()
if( t != SbxVARIANT )
{
eScanType = t;
- ++pLine;
+ ++nLineIdx;
++nCol;
}
}
@@ -439,10 +439,10 @@ bool SbiScanner::NextSym()
// Hex/octal number? Read in and convert:
else if(aLine.getLength() - nCol > 1 && aLine[nCol] == '&')
{
- ++pLine; ++nCol;
+ ++nLineIdx; ++nCol;
sal_Unicode base = 16;
sal_Unicode xch = aLine[nCol];
- ++pLine; ++nCol;
+ ++nLineIdx; ++nCol;
switch( rtl::toAsciiUpperCase( xch ) )
{
case 'O':
@@ -452,7 +452,7 @@ bool SbiScanner::NextSym()
break;
default :
// treated as an operator
- --pLine; --nCol; nCol1 = nCol-1;
+ --nLineIdx; --nCol; nCol1 = nCol-1;
aSym = "&";
return true;
}
@@ -464,7 +464,7 @@ bool SbiScanner::NextSym()
while(nCol < aLine.getLength() && BasicCharClass::isAlphaNumeric(aLine[nCol], false))
{
sal_Unicode ch = rtl::toAsciiUpperCase(aLine[nCol]);
- ++pLine; ++nCol;
+ ++nLineIdx; ++nCol;
if( ((base == 16 ) && rtl::isAsciiHexDigit( ch ) ) ||
((base == 8) && rtl::isAsciiOctalDigit( ch )))
{
@@ -484,7 +484,7 @@ bool SbiScanner::NextSym()
}
if(nCol < aLine.getLength() && aLine[nCol] == '&')
{
- ++pLine;
+ ++nLineIdx;
++nCol;
}
sal_Int32 ls = static_cast<sal_Int32>(lu);
@@ -495,27 +495,27 @@ bool SbiScanner::NextSym()
}
// Strings:
- else if( *pLine == '"' || *pLine == '[' )
+ else if (aLine[nLineIdx] == '"' || aLine[nLineIdx] == '[')
{
- sal_Unicode cSep = *pLine;
+ sal_Unicode cSep = aLine[nLineIdx];
if( cSep == '[' )
{
bSymbol = true;
cSep = ']';
}
sal_Int32 n = nCol + 1;
- while( *pLine )
+ while (nLineIdx < aLine.getLength())
{
do
{
- pLine++;
+ nLineIdx++;
nCol++;
}
- while( *pLine && ( *pLine != cSep ) );
- if( *pLine == cSep )
+ while (nLineIdx < aLine.getLength() && (aLine[nLineIdx] != cSep));
+ if (nLineIdx < aLine.getLength() && aLine[nLineIdx] == cSep)
{
- pLine++; nCol++;
- if( *pLine != cSep || cSep == ']' )
+ nLineIdx++; nCol++;
+ if (nLineIdx >= aLine.getLength() || aLine[nLineIdx] != cSep || cSep == ']')
{
// If VBA Interop then doesn't eat the [] chars
if ( cSep == ']' && bVBASupportOn )
@@ -545,18 +545,18 @@ bool SbiScanner::NextSym()
}
// Date:
- else if( *pLine == '#' )
+ else if (aLine[nLineIdx] == '#')
{
sal_Int32 n = nCol + 1;
do
{
- pLine++;
+ nLineIdx++;
nCol++;
}
- while( *pLine && ( *pLine != '#' ) );
- if( *pLine == '#' )
+ while (nLineIdx < aLine.getLength() && (aLine[nLineIdx] != '#'));
+ if (nLineIdx < aLine.getLength() && aLine[nLineIdx] == '#')
{
- pLine++; nCol++;
+ nLineIdx++; nCol++;
aSym = aLine.copy( n, nCol - n - 1 );
// parse date literal
@@ -592,22 +592,27 @@ bool SbiScanner::NextSym()
}
}
// invalid characters:
- else if( *pLine >= 0x7F )
+ else if (aLine[nLineIdx] >= 0x7F)
{
- GenError( ERRCODE_BASIC_SYNTAX ); pLine++; nCol++;
+ GenError( ERRCODE_BASIC_SYNTAX ); nLineIdx++; nCol++;
}
// other groups:
else
{
sal_Int32 n = 1;
- switch( *pLine++ )
+ auto nChar = nLineIdx < aLine.getLength() ? aLine[nLineIdx] : 0;
+ ++nLineIdx;
+ if (nLineIdx < aLine.getLength())
{
- case '<': if( *pLine == '>' || *pLine == '=' ) n = 2; break;
- case '>': if( *pLine == '=' ) n = 2; break;
- case ':': if( *pLine == '=' ) n = 2; break;
+ switch (nChar)
+ {
+ case '<': if( aLine[nLineIdx] == '>' || aLine[nLineIdx] == '=' ) n = 2; break;
+ case '>': if( aLine[nLineIdx] == '=' ) n = 2; break;
+ case ':': if( aLine[nLineIdx] == '=' ) n = 2; break;
+ }
}
aSym = aLine.copy(nCol, std::min(n, aLine.getLength() - nCol));
- pLine += n-1; nCol = nCol + n;
+ nLineIdx += n-1; nCol = nCol + n;
}
nCol2 = nCol-1;
@@ -621,19 +626,19 @@ PrevLineCommentLbl:
{
bPrevLineExtentsComment = false;
aSym = "REM";
- sal_Int32 nLen = rtl_ustr_getLength(pLine);
- if( bCompatible && pLine[ nLen - 1 ] == '_' && pLine[ nLen - 2 ] == ' ' )
+ sal_Int32 nLen = aLine.getLength() - nLineIdx;
+ if( bCompatible && aLine[nLineIdx + nLen - 1] == '_' && aLine[nLineIdx + nLen - 2] == ' ' )
bPrevLineExtentsComment = true;
nCol2 = nCol2 + nLen;
- pLine = nullptr;
+ nLineIdx = -1;
}
return true;
eoln:
- if( nCol && *--pLine == '_' )
+ if( nCol && aLine[--nLineIdx] == '_' )
{
- pLine = nullptr;
+ nLineIdx = -1;
bool bRes = NextSym();
if( aSym.startsWith(".") )
{
@@ -646,7 +651,7 @@ eoln:
}
else
{
- pLine = nullptr;
+ nLineIdx = -1;
nLine = nOldLine;
nCol1 = nOldCol1;
nCol2 = nOldCol2;
diff --git a/basic/source/inc/scanner.hxx b/basic/source/inc/scanner.hxx
index 25e038a8a1af..b0b0b00590f7 100644
--- a/basic/source/inc/scanner.hxx
+++ b/basic/source/inc/scanner.hxx
@@ -34,8 +34,8 @@ class SbiScanner
{
OUString aBuf; // input buffer
OUString aLine;
- const sal_Unicode* pLine;
- const sal_Unicode* pSaveLine;
+ sal_Int32 nLineIdx;
+ sal_Int32 nSaveLineIdx;
StarBASIC* pBasic; // instance for error callbacks
void scanAlphanumeric();
@@ -80,8 +80,8 @@ public:
sal_Int32 GetCol1() { return nCol1; }
void SetCol1( sal_Int32 n ) { nCol1 = n; }
StarBASIC* GetBasic() { return pBasic; }
- void SaveLine() { pSaveLine = pLine; }
- void RestoreLine() { pLine = pSaveLine; }
+ void SaveLine() { nSaveLineIdx = nLineIdx; }
+ void RestoreLine() { nLineIdx = nSaveLineIdx; }
void LockColumn();
void UnlockColumn();
bool DoesColonFollow();