Apache OpenOffice (AOO) Bugzilla – Issue 101455
Code in idl/source/objects/bastyp.cxx smells
Last modified: 2009-09-25 12:11:23 UTC
Found during review of a compiler warning patch: the code patche in issue 96834 does not look as if it does what it is meant to do. To verify the proposed changes, a test case is needed, means: idl files that can trigger the "smelling" code.
Just to make hay while the sun shines: target 3.2
Btw. translate the German comment...
Fixed in CWS mba32issues02
.
The code obviously works fine. Please have a look on the code and verify that the change is correct.
@mba: The modification of idl/source/objects/bastype.cxx in <http://hg.services.openoffice.org/hg/cws/mba32issues02/rev/53b0444724da> is still not correct: - it fails to multiply the final result assigned to *pValue by nSign; - it arbitrarily fails for LONG_MIN; - technically speaking, it incurs undefined behavior when casting between long and unsigned long; - it violates our coding standards (tabs, C-style casts). As the only call to ReadRangeSvIdl is with nMin == 0, why not simply drop support for reading negative numbers in the first place and simplify accordingly?
Good idea. :-)
So something like that: static BOOL ReadRangeSvIdl( SvStringHashEntry * pName, SvTokenStream & rInStm, ULONG nMin, ULONG nMax, ULONG* pValue ) { UINT32 nTokPos = rInStm.Tell(); SvToken * pTok = rInStm.GetToken_Next(); if( pTok->Is( pName ) ) { BOOL bOk = TRUE; BOOL bBraket = rInStm.Read( '(' ); if( bBraket || rInStm.Read( '=' ) ) { short nSign = 1; pTok = rInStm.GetToken_Next(); if( pTok->IsChar() && pTok->GetChar() == '-' ) { nSign = -1; pTok = rInStm.GetToken_Next(); } else if( pTok->IsChar() && pTok->GetChar() == '+' ) pTok = rInStm.GetToken_Next(); if( pTok->IsInteger() ) { if ( nSign == -1 ) return FALSE; ULONG n = pTok->GetNumber(); if ( n >= nMin && n =< nMax ) { *pValue = n; } else bOk = FALSE; if( bOk && bBraket ) bOk = rInStm.Read( ')' ); } else bOk = pTok->IsChar() && pTok->GetChar() == ')'; } if( bOk ) return TRUE; } rInStm.Seek( nTokPos ); return FALSE; }
@mba: looks better (it fails for input "-0" for which the original would have succeeded, however, and it might make sense to drop scanning for '-' and having nSign in the code completely)
OK, makes sense. Then it also makes sense not to look for brackets. Looks very simple now and of course works. Please verify: static BOOL ReadRangeSvIdl( SvStringHashEntry * pName, SvTokenStream & rInStm, ULONG nMin, ULONG nMax, ULONG* pValue ) { UINT32 nTokPos = rInStm.Tell(); SvToken * pTok = rInStm.GetToken_Next(); if( pTok->Is( pName ) ) { BOOL bOk = FALSE; if( rInStm.Read( '=' ) ) { pTok = rInStm.GetToken_Next(); if( pTok->IsInteger() ) { ULONG n = pTok->GetNumber(); if ( n >= nMin && n <= nMax ) { *pValue = n; bOK = TRUE; } } } if( bOk ) return TRUE; } rInStm.Seek( nTokPos ); return FALSE; } Now the method does much less than the old one, but everything needed at the only place where it is used.
Code works in all tested modules. Please verify again.
yes, final version looks good---if n at calling site is changed from long to ULONG and code is actually committed ;)
Of course. :-) I will now push it to the outgoing repository.