1

Closed

ZipInputStream throws NullReferenceException when using ZipEntry.Extract()

description

The following code throws a NullReference Exception. Exception details follow code.
 
Dim tZip As Ionic.Zip.ZipInputStream = Nothing
Dim tEntry As Ionic.Zip.ZipEntry = Nothing
Dim tModelStream As Stream = Assembly.GetExecutingAssembly.GetManifestResourceStream(tFeature.Manifest.MediaID & ".Models.zip")
 
tZip = New Ionic.Zip.ZipInputStream(tModelStream, False)
Do
tEntry = tZip.GetNextEntry
tEntry.Extract(sModelPath, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently)
Loop Until tEntry Is Nothing
 
 
" at Ionic.Zip.ZipEntry.InternalExtract(String baseDir, Stream outstream, String password) at Ionic.Zip.ZipEntry.Extract(String baseDirectory, ExtractExistingFileAction extractExistingFile) ..... ..... ..... etc etc
Closed Jun 18, 2011 at 5:04 AM by Cheeso
fixed in changeset 79370 - now there is a clear exception describing the error when you use ZipEntry.Extract with ZipInputStream. don't do this! The first binary to contain this fix (the better exception) will be v1.9.1.6.

comments

Cheeso wrote Mar 5, 2010 at 11:24 AM

I need the entire exception in order to figure this out. Not just the exception location. The actual exception, plus the complete stacktrace. Also, have you verified that tModelStream is not Nothing?

saracoth wrote Apr 22, 2010 at 3:15 PM

I believe I know what the issue is, as I've run into something similar with similar code. In my case, however, I was extracting to a stream, not a file path.

Message: Object reference not set to an instance of an object. (NullReferenceException)
Stack Trace: at Ionic.Zip.ZipEntry.InternalExtract(String baseDir, Stream outstream, String password) in C:\DotNetZip\v1.9.1.5\DotNetZip\Zip Partial DLL\ZipEntry.Extract.cs:line 602
at Ionic.Zip.ZipEntry.Extract(Stream stream) in C:\DotNetZip\v1.9.1.5\DotNetZip\Zip Partial DLL\ZipEntry.Extract.cs:line 112
at StarkBros.Biz.Finance.Paymentech.NetConnectBatchTransport.GetResponses() in C:\StarkBros\src\ursa\BusinessLayer\Finance\Paymentech\Transport.vb:line 323

Note that InternalExtract calls _container.ZipFile.Reset(), which is presumably an issue because the container is a ZipInputStream, not a ZipFile. Based on that, I wouldn't expect ZipEntry.InternalExtract to ever work for a ZipInputStream.

I switched to using the Read(Byte(), Integer, Integer) method on the ZipInputStream itself, which works fine for my case.

Nanalich wrote May 24, 2010 at 2:36 PM

// class ZipInputStream
internal string _password;

// class ZipContainer
public string Password
{
get
{
if (_zis != null) return _zis._password;
if (_zos != null) return _zos._password;
return _zf._Password;
//if (_zf != null) return _zf._Password;
//return _zos._password;
}
}

Nanalich wrote May 24, 2010 at 3:27 PM

the code i just posted also fix same Exception in OpenReader()

Cheeso wrote Jun 2, 2010 at 10:48 PM

Thanks, nanalich, I've put those changes in.

Cheeso wrote Jun 18, 2011 at 5:03 AM

I am reversing myself on this. The ZipInputStream model and metaphor calls for just READing the stream itself, there should be no need to call ZipEntry.Extract(). See the "workaround" described by saracoth - this is actually the documented, accepted, correct usage model for ZipInputStream. Check the documentation on that class for more details and examples.

I don't know why I thought it was a good idea to allow this, previously. I was confused.

If you want to call ZipEntry.Extract(), you should use a ZipFile() class, which is a different metaphor. I've made a code change to throw a clear exception if you try to call ZipEntry.Extract on an entry you received from a ZipInputStream.

CPtEddie wrote Aug 18, 2011 at 8:49 AM

Cheeso, I got the same problem as saracoth.

I do the following:

ZipEntry MyEntry = MyZipInputStream.GetNextEntry();
while (MyEntry != null)
{
using (MemoryStream MyExtractedFile = new MemoryStream())
{
    MyEntry.Extract(MyExtractedFile);
}
MyEntry = MyZipInputStream.GetNextEntry();
}


The stacktrace I then have, is the same as saracoth. So MyEntry.Extract(MyExtractedFile) will call InternalExtract(null, MyExtractedFile, Null).

the function works until:
    private void InternalExtract(string baseDir, Stream outstream, string password)
    {
        // workitem 7958
        if (_container == null)
            throw new BadStateException("This ZipEntry is an orphan.");

        _container.ZipFile.Reset();
_container.Zipfile.Reset();

_container is not null, but Zipfile is, so we receive a nullreference exception.

CPtEddie wrote Aug 18, 2011 at 9:02 AM

Ok this was really my fault. I used wrong syntax. Ofcourse....

I used a ZipInputReader, but actually I needed a plain ZipFile as in:

using(ZipFile myZipFile = new ZipFile(pathtofile))

Foreach (ZipEntry MyEntry in myZipFile.Entries)
{
using (MemoryStream MyExtractedFile = new MemoryStream())
{
MyEntry.Extract(MyExtractedFile);
}
}