Uploaded image for project: 'Xerces-C++'
  1. Xerces-C++
  2. XERCESC-1858

Using TranscodeToStr with strings shorter than two characters corrupts memory

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 3.0.0
    • 3.0.2, 3.1.0
    • Utilities
    • None
    • Windows XP Pro (32-bit), compiling with MS VisualStudio.Net 2003 with debugging symbols.

    Description

      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.

      Attachments

        1. XERCESC-1858.patch
          0.7 kB
          David N Bertoni

        Activity

          People

            jpcs John Snelson
            gcompton George Compton
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: