Changeset 12002

Show
Ignore:
Timestamp:
08/30/07 00:53:52 (1 year ago)
Author:
warmerdam
Message:

handle multi-byte strings more accurately (#1526)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/frmts/iso8211/ddfsubfielddefn.cpp

    r10645 r12002  
    262262    { 
    263263        int     nLength = 0; 
    264         int     bCheckFieldTerminator = TRUE; 
     264        int     bAsciiField = TRUE; 
     265        int     extraConsumedBytes = 0; 
    265266 
    266267        /* We only check for the field terminator because of some buggy  
    267268         * datasets with missing format terminators.  However, we have found 
    268          * the field terminator is a legal character within the fields of 
    269          * some extended datasets (such as JP34NC94.000).  So we don't check 
    270          * for the field terminator if the field appears to be multi-byte 
    271          * which we established by the first character being out of the  
    272          * ASCII printable range (32-127).  
     269         * the field terminator and unit terminators are legal characters  
     270         * within the fields of some extended datasets (such as JP34NC94.000). 
     271         * So we don't check for the field terminator and unit terminators as  
     272         * a single byte if the field appears to be multi-byte which we  
     273         * established by the first character being out of the ASCII printable 
     274         * range (32-127).  
     275         * 
     276         * In the case of S57, the subfield ATVL of the NATF field can be  
     277         * encoded in lexical level 2 (see S57 specification, Edition 3.1,  
     278         * paragraph 2.4 and 2.5). In that case the Unit Terminator and Field  
     279         * Terminator are followed by the NULL character. 
     280         * A better fix would be to read the NALL tag in the DSSI to check  
     281         * that the lexical level is 2, instead of relying on the value of  
     282         * the first byte as we are doing.  
     283         * (Fix for bug #1526) 
    273284         */ 
    274285 
    275         if( pachSourceData[0] < 32 || pachSourceData[0] >= 127 ) 
    276             bCheckFieldTerminator = FALSE; 
    277          
    278         while( nLength < nMaxBytes 
    279                && pachSourceData[nLength] != chFormatDelimeter ) 
    280         { 
    281             if( bCheckFieldTerminator  
    282                 && pachSourceData[nLength] == DDF_FIELD_TERMINATOR ) 
    283                 break; 
    284  
    285             nLength++; 
     286        if( (unsigned char)pachSourceData[0] < 32 || (unsigned char)pachSourceData[0] >= 127 ) 
     287            bAsciiField = FALSE; 
     288        if (pachSourceData[0] != chFormatDelimeter) 
     289        { 
     290            while( nLength < nMaxBytes) 
     291            { 
     292                if (bAsciiField) 
     293                { 
     294                    if (pachSourceData[nLength] == chFormatDelimeter || 
     295                        pachSourceData[nLength] == DDF_FIELD_TERMINATOR) 
     296                        break; 
     297                } 
     298                else 
     299                { 
     300                    if ((pachSourceData[nLength] == chFormatDelimeter || 
     301                        pachSourceData[nLength] == DDF_FIELD_TERMINATOR) && 
     302                        nLength+1 < nMaxBytes && 
     303                        pachSourceData[nLength+1] == 0) 
     304                    { 
     305                        extraConsumedBytes = 1; 
     306                        if (nLength+2 < nMaxBytes && 
     307                            pachSourceData[nLength+2] == DDF_FIELD_TERMINATOR) 
     308                            extraConsumedBytes++; 
     309                        break; 
     310                    }  
     311                } 
     312     
     313                nLength++; 
     314            } 
    286315        } 
    287316 
     
    289318        { 
    290319            if( nMaxBytes == 0 ) 
    291                 *pnConsumedBytes = nLength
     320                *pnConsumedBytes = nLength + extraConsumedBytes
    292321            else 
    293                 *pnConsumedBytes = nLength+1; 
     322                *pnConsumedBytes = nLength + extraConsumedBytes + 1; 
    294323        } 
    295324