Kaydet (Commit) 39e75712 authored tarafından Caolán McNamara's avatar Caolán McNamara

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/55722Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst 011b7c54
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
SbiScanner::SbiScanner( const OUString& rBuf, StarBASIC* p ) : aBuf( rBuf ) SbiScanner::SbiScanner( const OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
{ {
pBasic = p; pBasic = p;
pLine = nullptr; nLineIdx = -1;
nVal = 0; nVal = 0;
eScanType = SbxVARIANT; eScanType = SbxVARIANT;
nErrors = 0; nErrors = 0;
...@@ -50,7 +50,7 @@ SbiScanner::SbiScanner( const OUString& rBuf, StarBASIC* p ) : aBuf( rBuf ) ...@@ -50,7 +50,7 @@ SbiScanner::SbiScanner( const OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
bInStatement = bInStatement =
bPrevLineExtentsComment = false; bPrevLineExtentsComment = false;
bHash = true; bHash = true;
pSaveLine = nullptr; nSaveLineIdx = -1;
} }
SbiScanner::~SbiScanner() SbiScanner::~SbiScanner()
...@@ -107,7 +107,7 @@ bool SbiScanner::DoesColonFollow() ...@@ -107,7 +107,7 @@ bool SbiScanner::DoesColonFollow()
{ {
if(nCol < aLine.getLength() && aLine[nCol] == ':') if(nCol < aLine.getLength() && aLine[nCol] == ':')
{ {
++pLine; ++nCol; ++nLineIdx; ++nCol;
return true; return true;
} }
else else
...@@ -145,7 +145,7 @@ void SbiScanner::scanAlphanumeric() ...@@ -145,7 +145,7 @@ void SbiScanner::scanAlphanumeric()
sal_Int32 n = nCol; sal_Int32 n = nCol;
while(nCol < aLine.getLength() && (BasicCharClass::isAlphaNumeric(aLine[nCol], bCompatible) || aLine[nCol] == '_')) while(nCol < aLine.getLength() && (BasicCharClass::isAlphaNumeric(aLine[nCol], bCompatible) || aLine[nCol] == '_'))
{ {
++pLine; ++nLineIdx;
++nCol; ++nCol;
} }
aSym = aLine.copy(n, nCol - n); aSym = aLine.copy(n, nCol - n);
...@@ -163,7 +163,7 @@ void SbiScanner::scanGoto() ...@@ -163,7 +163,7 @@ void SbiScanner::scanGoto()
if(aTemp.equalsIgnoreAsciiCase("to")) if(aTemp.equalsIgnoreAsciiCase("to"))
{ {
aSym = "goto"; aSym = "goto";
pLine += n + 2 - nCol; nLineIdx += n + 2 - nCol;
nCol = n + 2; nCol = n + 2;
} }
} }
...@@ -194,7 +194,7 @@ bool SbiScanner::readLine() ...@@ -194,7 +194,7 @@ bool SbiScanner::readLine()
++n; ++n;
nBufPos = n; nBufPos = n;
pLine = aLine.getStr(); nLineIdx = 0;
++nLine; ++nLine;
nCol = nCol1 = nCol2 = 0; nCol = nCol1 = nCol2 = 0;
...@@ -217,7 +217,7 @@ bool SbiScanner::NextSym() ...@@ -217,7 +217,7 @@ bool SbiScanner::NextSym()
bool bCompilerDirective = false; bool bCompilerDirective = false;
// read in line? // read in line?
if( !pLine ) if (nLineIdx == -1)
{ {
if(!readLine()) if(!readLine())
return false; return false;
...@@ -231,7 +231,7 @@ bool SbiScanner::NextSym() ...@@ -231,7 +231,7 @@ bool SbiScanner::NextSym()
bSpaces = true; bSpaces = true;
while(nCol < aLine.getLength() && BasicCharClass::isWhitespace(aLine[nCol])) while(nCol < aLine.getLength() && BasicCharClass::isWhitespace(aLine[nCol]))
{ {
++pLine; ++nLineIdx;
++nCol; ++nCol;
} }
} }
...@@ -247,15 +247,15 @@ bool SbiScanner::NextSym() ...@@ -247,15 +247,15 @@ bool SbiScanner::NextSym()
if(nCol < aLine.getLength() && aLine[nCol] == '#') if(nCol < aLine.getLength() && aLine[nCol] == '#')
{ {
const sal_Unicode* pLineTemp = pLine; sal_Int32 nLineTempIdx = nLineIdx;
do do
{ {
pLineTemp++; nLineTempIdx++;
} while (*pLineTemp && !BasicCharClass::isWhitespace(*pLineTemp) && *pLineTemp != '#'); } while (nLineTempIdx < aLine.getLength() && !BasicCharClass::isWhitespace(aLine[nLineTempIdx]) && aLine[nLineTempIdx] != '#');
// leave it if it is a date literal - it will be handled later // leave it if it is a date literal - it will be handled later
if (*pLineTemp != '#') if (nLineTempIdx >= aLine.getLength() || aLine[nLineTempIdx] != '#')
{ {
++pLine; ++nLineIdx;
++nCol; ++nCol;
//ignore compiler directives (# is first non-space character) //ignore compiler directives (# is first non-space character)
if (nOldCol2 == 0) if (nOldCol2 == 0)
...@@ -272,7 +272,7 @@ bool SbiScanner::NextSym() ...@@ -272,7 +272,7 @@ bool SbiScanner::NextSym()
if(nCol + 1 == aLine.getLength() && aLine[nCol] == '_') if(nCol + 1 == aLine.getLength() && aLine[nCol] == '_')
{ {
// Note that nCol is not incremented here... // Note that nCol is not incremented here...
++pLine; ++nLineIdx;
goto eoln; goto eoln;
} }
...@@ -286,7 +286,7 @@ bool SbiScanner::NextSym() ...@@ -286,7 +286,7 @@ bool SbiScanner::NextSym()
// replace closing '_' by space when end of line is following // replace closing '_' by space when end of line is following
// (wrong line continuation otherwise) // (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 // We are going to modify a potentially shared string, so force
// a copy, so that aSym is not modified by the following operation // a copy, so that aSym is not modified by the following operation
...@@ -294,7 +294,7 @@ bool SbiScanner::NextSym() ...@@ -294,7 +294,7 @@ bool SbiScanner::NextSym()
aSym = aSymCopy; aSym = aSymCopy;
// HACK: modifying a potentially shared string here! // HACK: modifying a potentially shared string here!
*const_cast<sal_Unicode*>(pLine-1) = ' '; const_cast<sal_Unicode*>(aLine.getStr())[nLineIdx - 1] = ' ';
} }
// type recognition? // type recognition?
...@@ -309,7 +309,7 @@ bool SbiScanner::NextSym() ...@@ -309,7 +309,7 @@ bool SbiScanner::NextSym()
if( t != SbxVARIANT ) if( t != SbxVARIANT )
{ {
eScanType = t; eScanType = t;
++pLine; ++nLineIdx;
++nCol; ++nCol;
} }
} }
...@@ -332,7 +332,7 @@ bool SbiScanner::NextSym() ...@@ -332,7 +332,7 @@ bool SbiScanner::NextSym()
if( (p-buf) == (BUF_SIZE-1) ) if( (p-buf) == (BUF_SIZE-1) )
{ {
bBufOverflow = true; bBufOverflow = true;
++pLine; ++nLineIdx;
++nCol; ++nCol;
continue; continue;
} }
...@@ -353,7 +353,7 @@ bool SbiScanner::NextSym() ...@@ -353,7 +353,7 @@ bool SbiScanner::NextSym()
*p++ = 'E'; *p++ = 'E';
if (nCol + 1 < aLine.getLength() && (aLine[nCol+1] == '+' || aLine[nCol+1] == '-')) if (nCol + 1 < aLine.getLength() && (aLine[nCol+1] == '+' || aLine[nCol+1] == '-'))
{ {
++pLine; ++nLineIdx;
++nCol; ++nCol;
if( (p-buf) == (BUF_SIZE-1) ) if( (p-buf) == (BUF_SIZE-1) )
{ {
...@@ -368,7 +368,7 @@ bool SbiScanner::NextSym() ...@@ -368,7 +368,7 @@ bool SbiScanner::NextSym()
{ {
*p++ = aLine[nCol]; *p++ = aLine[nCol];
} }
++pLine; ++nLineIdx;
++nCol; ++nCol;
} }
*p = 0; *p = 0;
...@@ -378,7 +378,7 @@ bool SbiScanner::NextSym() ...@@ -378,7 +378,7 @@ bool SbiScanner::NextSym()
ErrCode nError = ERRCODE_NONE; ErrCode nError = ERRCODE_NONE;
if (bScanError) if (bScanError)
{ {
--pLine; --nLineIdx;
--nCol; --nCol;
aError = OUString( aLine[nCol]); aError = OUString( aLine[nCol]);
nError = ERRCODE_BASIC_BAD_CHAR_IN_NUMBER; nError = ERRCODE_BASIC_BAD_CHAR_IN_NUMBER;
...@@ -391,9 +391,9 @@ bool SbiScanner::NextSym() ...@@ -391,9 +391,9 @@ bool SbiScanner::NextSym()
{ {
// e.g. "12e" or "12e+", or with bScanError "12d"+"E". // e.g. "12e" or "12e+", or with bScanError "12d"+"E".
sal_Int32 nChars = buf+(p-buf) - pParseEnd; sal_Int32 nChars = buf+(p-buf) - pParseEnd;
pLine -= nChars; nLineIdx -= nChars;
nCol -= 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. // add that character to the parse end.
if (bScanError) if (bScanError)
++nChars; ++nChars;
...@@ -430,7 +430,7 @@ bool SbiScanner::NextSym() ...@@ -430,7 +430,7 @@ bool SbiScanner::NextSym()
if( t != SbxVARIANT ) if( t != SbxVARIANT )
{ {
eScanType = t; eScanType = t;
++pLine; ++nLineIdx;
++nCol; ++nCol;
} }
} }
...@@ -439,10 +439,10 @@ bool SbiScanner::NextSym() ...@@ -439,10 +439,10 @@ bool SbiScanner::NextSym()
// Hex/octal number? Read in and convert: // Hex/octal number? Read in and convert:
else if(aLine.getLength() - nCol > 1 && aLine[nCol] == '&') else if(aLine.getLength() - nCol > 1 && aLine[nCol] == '&')
{ {
++pLine; ++nCol; ++nLineIdx; ++nCol;
sal_Unicode base = 16; sal_Unicode base = 16;
sal_Unicode xch = aLine[nCol]; sal_Unicode xch = aLine[nCol];
++pLine; ++nCol; ++nLineIdx; ++nCol;
switch( rtl::toAsciiUpperCase( xch ) ) switch( rtl::toAsciiUpperCase( xch ) )
{ {
case 'O': case 'O':
...@@ -452,7 +452,7 @@ bool SbiScanner::NextSym() ...@@ -452,7 +452,7 @@ bool SbiScanner::NextSym()
break; break;
default : default :
// treated as an operator // treated as an operator
--pLine; --nCol; nCol1 = nCol-1; --nLineIdx; --nCol; nCol1 = nCol-1;
aSym = "&"; aSym = "&";
return true; return true;
} }
...@@ -464,7 +464,7 @@ bool SbiScanner::NextSym() ...@@ -464,7 +464,7 @@ bool SbiScanner::NextSym()
while(nCol < aLine.getLength() && BasicCharClass::isAlphaNumeric(aLine[nCol], false)) while(nCol < aLine.getLength() && BasicCharClass::isAlphaNumeric(aLine[nCol], false))
{ {
sal_Unicode ch = rtl::toAsciiUpperCase(aLine[nCol]); sal_Unicode ch = rtl::toAsciiUpperCase(aLine[nCol]);
++pLine; ++nCol; ++nLineIdx; ++nCol;
if( ((base == 16 ) && rtl::isAsciiHexDigit( ch ) ) || if( ((base == 16 ) && rtl::isAsciiHexDigit( ch ) ) ||
((base == 8) && rtl::isAsciiOctalDigit( ch ))) ((base == 8) && rtl::isAsciiOctalDigit( ch )))
{ {
...@@ -484,7 +484,7 @@ bool SbiScanner::NextSym() ...@@ -484,7 +484,7 @@ bool SbiScanner::NextSym()
} }
if(nCol < aLine.getLength() && aLine[nCol] == '&') if(nCol < aLine.getLength() && aLine[nCol] == '&')
{ {
++pLine; ++nLineIdx;
++nCol; ++nCol;
} }
sal_Int32 ls = static_cast<sal_Int32>(lu); sal_Int32 ls = static_cast<sal_Int32>(lu);
...@@ -495,27 +495,27 @@ bool SbiScanner::NextSym() ...@@ -495,27 +495,27 @@ bool SbiScanner::NextSym()
} }
// Strings: // Strings:
else if( *pLine == '"' || *pLine == '[' ) else if (aLine[nLineIdx] == '"' || aLine[nLineIdx] == '[')
{ {
sal_Unicode cSep = *pLine; sal_Unicode cSep = aLine[nLineIdx];
if( cSep == '[' ) if( cSep == '[' )
{ {
bSymbol = true; bSymbol = true;
cSep = ']'; cSep = ']';
} }
sal_Int32 n = nCol + 1; sal_Int32 n = nCol + 1;
while( *pLine ) while (nLineIdx < aLine.getLength())
{ {
do do
{ {
pLine++; nLineIdx++;
nCol++; nCol++;
} }
while( *pLine && ( *pLine != cSep ) ); while (nLineIdx < aLine.getLength() && (aLine[nLineIdx] != cSep));
if( *pLine == cSep ) if (nLineIdx < aLine.getLength() && aLine[nLineIdx] == cSep)
{ {
pLine++; nCol++; nLineIdx++; nCol++;
if( *pLine != cSep || cSep == ']' ) if (nLineIdx >= aLine.getLength() || aLine[nLineIdx] != cSep || cSep == ']')
{ {
// If VBA Interop then doesn't eat the [] chars // If VBA Interop then doesn't eat the [] chars
if ( cSep == ']' && bVBASupportOn ) if ( cSep == ']' && bVBASupportOn )
...@@ -545,18 +545,18 @@ bool SbiScanner::NextSym() ...@@ -545,18 +545,18 @@ bool SbiScanner::NextSym()
} }
// Date: // Date:
else if( *pLine == '#' ) else if (aLine[nLineIdx] == '#')
{ {
sal_Int32 n = nCol + 1; sal_Int32 n = nCol + 1;
do do
{ {
pLine++; nLineIdx++;
nCol++; nCol++;
} }
while( *pLine && ( *pLine != '#' ) ); while (nLineIdx < aLine.getLength() && (aLine[nLineIdx] != '#'));
if( *pLine == '#' ) if (nLineIdx < aLine.getLength() && aLine[nLineIdx] == '#')
{ {
pLine++; nCol++; nLineIdx++; nCol++;
aSym = aLine.copy( n, nCol - n - 1 ); aSym = aLine.copy( n, nCol - n - 1 );
// parse date literal // parse date literal
...@@ -592,22 +592,27 @@ bool SbiScanner::NextSym() ...@@ -592,22 +592,27 @@ bool SbiScanner::NextSym()
} }
} }
// invalid characters: // 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: // other groups:
else else
{ {
sal_Int32 n = 1; 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; switch (nChar)
case '>': if( *pLine == '=' ) n = 2; break; {
case ':': if( *pLine == '=' ) n = 2; break; 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)); 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; nCol2 = nCol-1;
...@@ -621,19 +626,19 @@ PrevLineCommentLbl: ...@@ -621,19 +626,19 @@ PrevLineCommentLbl:
{ {
bPrevLineExtentsComment = false; bPrevLineExtentsComment = false;
aSym = "REM"; aSym = "REM";
sal_Int32 nLen = rtl_ustr_getLength(pLine); sal_Int32 nLen = aLine.getLength() - nLineIdx;
if( bCompatible && pLine[ nLen - 1 ] == '_' && pLine[ nLen - 2 ] == ' ' ) if( bCompatible && aLine[nLineIdx + nLen - 1] == '_' && aLine[nLineIdx + nLen - 2] == ' ' )
bPrevLineExtentsComment = true; bPrevLineExtentsComment = true;
nCol2 = nCol2 + nLen; nCol2 = nCol2 + nLen;
pLine = nullptr; nLineIdx = -1;
} }
return true; return true;
eoln: eoln:
if( nCol && *--pLine == '_' ) if( nCol && aLine[--nLineIdx] == '_' )
{ {
pLine = nullptr; nLineIdx = -1;
bool bRes = NextSym(); bool bRes = NextSym();
if( aSym.startsWith(".") ) if( aSym.startsWith(".") )
{ {
...@@ -646,7 +651,7 @@ eoln: ...@@ -646,7 +651,7 @@ eoln:
} }
else else
{ {
pLine = nullptr; nLineIdx = -1;
nLine = nOldLine; nLine = nOldLine;
nCol1 = nOldCol1; nCol1 = nOldCol1;
nCol2 = nOldCol2; nCol2 = nOldCol2;
......
...@@ -34,8 +34,8 @@ class SbiScanner ...@@ -34,8 +34,8 @@ class SbiScanner
{ {
OUString aBuf; // input buffer OUString aBuf; // input buffer
OUString aLine; OUString aLine;
const sal_Unicode* pLine; sal_Int32 nLineIdx;
const sal_Unicode* pSaveLine; sal_Int32 nSaveLineIdx;
StarBASIC* pBasic; // instance for error callbacks StarBASIC* pBasic; // instance for error callbacks
void scanAlphanumeric(); void scanAlphanumeric();
...@@ -80,8 +80,8 @@ public: ...@@ -80,8 +80,8 @@ public:
sal_Int32 GetCol1() { return nCol1; } sal_Int32 GetCol1() { return nCol1; }
void SetCol1( sal_Int32 n ) { nCol1 = n; } void SetCol1( sal_Int32 n ) { nCol1 = n; }
StarBASIC* GetBasic() { return pBasic; } StarBASIC* GetBasic() { return pBasic; }
void SaveLine() { pSaveLine = pLine; } void SaveLine() { nSaveLineIdx = nLineIdx; }
void RestoreLine() { pLine = pSaveLine; } void RestoreLine() { nLineIdx = nSaveLineIdx; }
void LockColumn(); void LockColumn();
void UnlockColumn(); void UnlockColumn();
bool DoesColonFollow(); bool DoesColonFollow();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment