Bug 15807

Summary: POIFS may inoorrectly throw exception when opening InputStream with POIFS's file
Product: POI Reporter: Shimon Pozin <shimonp>
Component: POIFSAssignee: POI Developers List <dev>
Status: RESOLVED DUPLICATE    
Severity: critical CC: shimonp
Priority: P3    
Version: 2.0-dev   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description Shimon Pozin 2003-01-05 19:08:05 UTC
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");
            }   
        }
    }
=============
Comment 1 Andy Oliver 2003-01-05 19:15:24 UTC
supply a patch and a unit test and I'll apply it (see
http://jakarta.apache.org/poi/getinvolved/index.html)...
Comment 2 Chris Nokleberg 2003-06-03 00:20:54 UTC

*** This bug has been marked as a duplicate of 13478 ***