You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by bu...@apache.org on 2003/01/05 20:08:06 UTC

DO NOT REPLY [Bug 15807] New: - POIFS may inoorrectly throw exception when opening InputStream with POIFS's file

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15807>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15807

POIFS may inoorrectly throw exception when opening InputStream with POIFS's file

           Summary: POIFS may inoorrectly throw exception when opening
                    InputStream with POIFS's file
           Product: POI
           Version: 2.0-dev
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Critical
          Priority: Other
         Component: POIFS
        AssignedTo: poi-dev@jakarta.apache.org
        ReportedBy: shimonp@rogers.com
                CC: shimonp@rogers.com


org.apache.poi.poifs.storage.RawDataBlock reads InputStream in chunks of 512 
bytes and throws exception in case chunk is smaller than 512 bytes. However, in 
the world of TCP/IP the chunk can actually be smaller than that. In this case 
POIFS will incorrectly throws exception and will refuse to parse the POIFS file 
despite file is the valid one. To resolve the issue, the constructor of 
RawDataBlock should be changed to read InputStream repeatedly until buffer 512 
bytes is filled in or EOF is reached. I suggest to modify it as follows (we 
tried it successfully here and it works for us - pay attention to internal loop 
in case count != POIFSConstants.BIG_BLOCK_SIZE):
=============
public RawDataBlock(final InputStream stream)
        throws IOException
    {
        _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ];
        
        _eof = false;
        
        int count = stream.read(_data);

        if (count == -1)
        {
            _eof = true;
        }
        else if (count != POIFSConstants.BIG_BLOCK_SIZE)
        {
            // Shimon: For remote objects read not necessarily returns 512 
bytes.
            // We need to read repeatedly until either buffer filled in or eof 
is reached
            int offset = 0;
            while(count > 0 && offset <= POIFSConstants.BIG_BLOCK_SIZE)
            {
               offset += count;
               count = stream.read(_data, offset, 
POIFSConstants.BIG_BLOCK_SIZE - offset);
               if(count == -1)
               {
                  _eof = true;
                  break;
               }
            }
       
            if(!_eof && count + offset != POIFSConstants.BIG_BLOCK_SIZE)
            {
               String type = " byte" + ((count == 1) ? ("")
                                                     : ("s"));
   
               throw new IOException("Unable to read entire block; " + count
                                     + type + " read; expected "
                                     + POIFSConstants.BIG_BLOCK_SIZE + " 
bytes");
            }   
        }
    }
=============