Using TranscodeToStr with strings shorter than two characters corrupts memory 
------------------------------------------------------------------------------

                 Key: XERCESC-1858
                 URL: https://issues.apache.org/jira/browse/XERCESC-1858
             Project: Xerces-C++
          Issue Type: Bug
          Components: Utilities
    Affects Versions: 3.0.0
         Environment: Windows XP Pro (32-bit), compiling with MS 
VisualStudio.Net 2003 with debugging symbols.  
            Reporter: George Compton
            Priority: Minor


I have observed this problem when using TranscodeToStr to transcode "" (empty 
string) and "1" (the numeral one) to US-ASCII.  Both caused the program to 
crash, apparently because the debug heap noticed that it had been corrupted.  

TranscodeToStr::transcode will overrun the allocated string fString when called 
with an input string that is less than two characters long.  When determining 
whether it needs to allocate additional space for terminating null characters, 
it uses the expression :
    if(fBytesWritten > (allocSize - 4)) {
allocSize is of type XMLSize_t, which is unsigned, assuming I followed all the 
typedefs correctly.  So, when the input string contains exactly one non-null 
character, allocSize is one times the size of XMLCh.  That's two bytes on 
Windows.  (2 - 4) in unsigned arithmetic wraps back to a large number, so the 
conditional is false, and additional memory for the terminator is not 
allocated.  The four terminating characters are then written to bytes 2, 3, 4, 
and 5 of a two byte array, corrupting whatever lies after it.  

Something similar happens with empty strings.  I haven't followed that all the 
way through a debugger, but I think there may be an additional problem there.  
The method's while(true) loop will transcode at least one character, because it 
doesn't check the input length until half way through the first iteration.  
Now, it's possible the allocator always allocates at least one byte, or it's 
possible that the transcoder won't write anything for a NULL character.  I 
haven't checked either into of those possibilities, but it seems risky to rely 
on those, even if they are the case.  

I have not had a chance to try fixing either problem yet.  For the first, just 
changing it to (fBytesWritten + 4 > allocSize) should probably work.  The 
second will probably require moving the length check or adding a second length 
check outside the loop.  

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to