Commit 27a02d32 authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

fully implement nul termination for LINE_READER::ReadLine()

parent c3924e6f
Loading
Loading
Loading
Loading
+11 −9
Original line number Original line Diff line number Diff line
@@ -86,10 +86,11 @@ void DSNLEXER::PushReader( LINE_READER* aLineReader )
{
{
    readerStack.push_back( aLineReader );
    readerStack.push_back( aLineReader );
    reader = aLineReader;
    reader = aLineReader;
    start  = (char*) (*reader);


    // force a new readLine() as first thing.
    // force a new readLine() as first thing.
    limit = start();
    limit = start;
    next  = start();
    next  = start;
}
}




@@ -101,10 +102,11 @@ bool DSNLEXER::PopReader()
        readerStack.pop_back();
        readerStack.pop_back();


        reader = &readerStack.back();
        reader = &readerStack.back();
        start  = (char*) (*reader);


        // force a new readLine() as first thing.
        // force a new readLine() as first thing.
        limit = start();
        limit = start;
        next  = start();
        next  = start;
        return true;
        return true;
    }
    }
    return false;
    return false;
@@ -331,7 +333,7 @@ L_read:
                goto exit;
                goto exit;
            }
            }


            cur = start();
            cur = start;


            // skip leading whitespace
            // skip leading whitespace
            while( cur<limit && isSpace(*cur) )
            while( cur<limit && isSpace(*cur) )
@@ -345,8 +347,8 @@ L_read:
                {
                {
                    // save the entire line, including new line as the current token.
                    // save the entire line, including new line as the current token.
                    // the '#' character may not be at offset zero.
                    // the '#' character may not be at offset zero.
                    curText = start();      // entire line is the token
                    curText = start;      // entire line is the token
                    cur     = start();      // ensure a good curOffset below
                    cur     = start;      // ensure a good curOffset below
                    curTok  = DSN_COMMENT;
                    curTok  = DSN_COMMENT;
                    head    = limit;        // do a readLine() on next call in here.
                    head    = limit;        // do a readLine() on next call in here.
                    goto exit;
                    goto exit;
@@ -414,7 +416,7 @@ L_read:
            like:  U2-14 or "U2"-"14"
            like:  U2-14 or "U2"-"14"
            This is detectable by a non-space immediately preceeding the dash.
            This is detectable by a non-space immediately preceeding the dash.
        */
        */
        if( *cur == '-' && cur>start() && !isSpace( cur[-1] ) )
        if( *cur == '-' && cur>start && !isSpace( cur[-1] ) )
        {
        {
            curText = '-';
            curText = '-';
            curTok = DSN_DASH;
            curTok = DSN_DASH;
@@ -535,7 +537,7 @@ L_read:


exit:   // single point of exit, no returns elsewhere please.
exit:   // single point of exit, no returns elsewhere please.


    curOffset = cur - start();
    curOffset = cur - start;


    next = head;
    next = head;


+9 −7
Original line number Original line Diff line number Diff line
@@ -47,8 +47,8 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength )
    capacity = LINE_READER_LINE_INITIAL_SIZE;
    capacity = LINE_READER_LINE_INITIAL_SIZE;


    // but never go above user's aMaxLineLength, and leave space for trailing nul
    // but never go above user's aMaxLineLength, and leave space for trailing nul
    if( capacity > aMaxLineLength-1 )
    if( capacity > aMaxLineLength+1 )
        capacity = aMaxLineLength-1;
        capacity = aMaxLineLength+1;


    line = new char[capacity];
    line = new char[capacity];


@@ -71,9 +71,10 @@ void LINE_READER::expandCapacity( unsigned newsize )
        // resize the buffer, and copy the original data
        // resize the buffer, and copy the original data
        char* bigger = new char[capacity];
        char* bigger = new char[capacity];


        wxASSERT( capacity >= length );
        wxASSERT( capacity >= length+1 );


        memcpy( bigger, line, length );
        memcpy( bigger, line, length );
        bigger[length] = 0;


        delete[] line;
        delete[] line;
        line = bigger;
        line = bigger;
@@ -102,8 +103,8 @@ unsigned FILE_LINE_READER::ReadLine() throw (IOError)
        if( length == maxLineLength )
        if( length == maxLineLength )
            throw IOError( _("Line length exceeded") );
            throw IOError( _("Line length exceeded") );


        // a normal line breaks here, once through
        // a normal line breaks here, once through while loop
        if( length < capacity-1 || line[length-1] == '\n' )
        if( length+1 < capacity || line[length-1] == '\n' )
            break;
            break;


        expandCapacity( capacity * 2 );
        expandCapacity( capacity * 2 );
@@ -130,12 +131,13 @@ unsigned STRING_LINE_READER::ReadLine() throw (IOError)
        if( length >= maxLineLength )
        if( length >= maxLineLength )
            throw IOError( _("Line length exceeded") );
            throw IOError( _("Line length exceeded") );


        if( length > capacity )
        if( length+1 > capacity )
            expandCapacity( length );
            expandCapacity( length+1 );


        wxASSERT( ndx + length <= lines.length() );
        wxASSERT( ndx + length <= lines.length() );


        memcpy( line, &source[ndx], length );
        memcpy( line, &source[ndx], length );
        line[length] = 0;


        ++lineNum;
        ++lineNum;
        ndx += length;
        ndx += length;
+5 −7
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ enum DSN_SYNTAX_T {
 */
 */
class DSNLEXER
class DSNLEXER
{
{
    char*               start;
    char*               next;
    char*               next;
    char*               limit;
    char*               limit;


@@ -99,20 +100,17 @@ class DSNLEXER
    const KEYWORD*      keywords;
    const KEYWORD*      keywords;
    unsigned            keywordCount;
    unsigned            keywordCount;


    /// Use casting char* operator to get start of line, which is dynamic since reader
    /// can be resizing its buffer at each reader->ReadLine() only.
    char*               start() const { return (char*) (*reader); }

    void init();
    void init();


    int readLine() throw (IOError)
    int readLine() throw (IOError)
    {
    {
        unsigned len = reader->ReadLine();
        unsigned len = reader->ReadLine();


        // set next and limit to start() and start() + len.
        // start may have changed in ReadLine(), which can resize and
        // start() is constant until the next ReadLine(), which could resize and
        // relocate reader's line buffer.
        // relocate reader's line buffer.
        next  = start();
        start = (*reader);

        next  = start;
        limit = next + len;
        limit = next + len;


        return len;
        return len;
+10 −26
Original line number Original line Diff line number Diff line
@@ -101,10 +101,10 @@ public:
    /**
    /**
     * Function ReadLine
     * Function ReadLine
     * reads a line of text into the buffer and increments the line number
     * reads a line of text into the buffer and increments the line number
     * counter.  If the line is larger than the buffer size, then an exception
     * counter.  If the line is larger than aMaxLineLength passed to the
     * is thrown.
     * constructor, then an exception is thrown.  The line is nul terminated.
     * @return unsigned - The number of bytes read, 0 at end of file.
     * @return unsigned - The number of bytes read, 0 at end of file.
     * @throw IOError only when a line is too long.
     * @throw IOError when a line is too long.
     */
     */
    virtual unsigned ReadLine() throw( IOError ) = 0;
    virtual unsigned ReadLine() throw( IOError ) = 0;


@@ -181,15 +181,7 @@ public:
            fclose( fp );
            fclose( fp );
    }
    }


    /**
    unsigned ReadLine() throw( IOError );   // see LINE_READER::ReadLine() description
     * Function ReadLine
     * reads a line of text into the buffer and increments the line number
     * counter.  If the line is larger than the buffer size, then an exception
     * is thrown.
     * @return unsigned - The number of bytes read, 0 at end of file.
     * @throw IOError only when a line is too long.
     */
    unsigned ReadLine() throw (IOError);


    /**
    /**
     * Function Rewind
     * Function Rewind
@@ -217,34 +209,26 @@ protected:
public:
public:


    /**
    /**
     * Constructor STRING_LINE_READER( const std::string& aString )
     * Constructor STRING_LINE_READER( const std::string&, const wxString& )
     *
     *
     * @param aString is a source string consisting of one or more lines
     * @param aString is a source string consisting of one or more lines
     * of text, where multiple lines are separated with a '\n' character.
     * of text, where multiple lines are separated with a '\n' character.
     * The last line does not necessarily need a trailing '\n'.
     * The last line does not necessarily need a trailing '\n'.
     *
     * @param aSource describes the source of aString for error reporting purposes
     * @param aSource describes the source of aString for error reporting purposes
     *  can be anything meaninful, such as wxT( "cliboard" ).
     *  can be anything meaninful, such as wxT( "cliboard" ).
     */
     */
    STRING_LINE_READER( const std::string& aString, const wxString& aSource ) :
    STRING_LINE_READER( const std::string& aString, const wxString& aSource ) :
        LINE_READER( 4096 ),
        LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
        lines( aString ),
        lines( aString ),
        ndx( 0 )
        ndx( 0 )
    {
    {
        // Clipboard text should be nice and _use multiple lines_ so that
        // Clipboard text should be nice and _use multiple lines_ so that
        // we can report _line number_ oriented error messages when parsing.
        // we can report _line number_ oriented error messages when parsing.
        // Therefore a line of 4096 characters max seems more than adequate.
        source = aSource;
        source = aSource;
    }
    }


    /**
     unsigned ReadLine() throw(IOError);    // see LINE_READER::ReadLine() description
     * Function ReadLine
     * reads a line of text into the buffer and increments the line number
     * counter.  If the line is larger than the buffer size, then an exception
     * is thrown.
     * @return unsigned - The number of bytes read, 0 at end of file.
     * @throw IOError only when a line is too long.
     */
    unsigned ReadLine() throw (IOError);
};
};