Issue 101455 - Code in idl/source/objects/bastyp.cxx smells
Summary: Code in idl/source/objects/bastyp.cxx smells
Status: CLOSED FIXED
Alias: None
Product: General
Classification: Code
Component: code (show other issues)
Version: OOo 1.0.0
Hardware: Unknown All
: P3 Trivial (vote)
Target Milestone: OOo 3.2
Assignee: Stephan Bergmann
QA Contact: issues@framework
URL:
Keywords:
Depends on:
Blocks: 96084
  Show dependency tree
 
Reported: 2009-04-30 13:12 UTC by Mathias_Bauer
Modified: 2009-09-25 12:11 UTC (History)
4 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: ---
Developer Difficulty: ---


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Mathias_Bauer 2009-04-30 13:12:07 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.
Comment 1 Mathias_Bauer 2009-04-30 13:13:09 UTC
Just to make hay while the sun shines: target 3.2
Comment 2 christian.lins 2009-04-30 13:50:12 UTC
Btw. translate the German comment...
Comment 3 Mathias_Bauer 2009-06-26 09:35:27 UTC
Fixed in CWS mba32issues02
Comment 4 Mathias_Bauer 2009-06-26 14:09:08 UTC
.
Comment 5 Mathias_Bauer 2009-09-01 11:29:41 UTC
The code obviously works fine. Please have a look on the code and verify that
the change is correct.
Comment 6 Stephan Bergmann 2009-09-01 12:32:55 UTC
@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?
Comment 7 Stephan Bergmann 2009-09-01 12:34:00 UTC
.
Comment 8 Mathias_Bauer 2009-09-01 12:58:03 UTC
Good idea. :-)
Comment 9 Mathias_Bauer 2009-09-01 13:14:12 UTC
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;
}
Comment 10 Stephan Bergmann 2009-09-01 14:11:18 UTC
@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)
Comment 11 Mathias_Bauer 2009-09-01 15:54:32 UTC
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.
Comment 12 Mathias_Bauer 2009-09-01 15:55:57 UTC
Code works in all tested modules. 

Please verify again.
Comment 13 Stephan Bergmann 2009-09-01 16:09:51 UTC
yes, final version looks good---if n at calling site is changed from long to
ULONG and code is actually committed ;)
Comment 14 Mathias_Bauer 2009-09-01 16:13:00 UTC
Of course. :-)
I will now push it to the outgoing repository.
Comment 15 Stephan Bergmann 2009-09-25 12:11:23 UTC
.