Skip to content

Opening a tar.gz file directly from the network makes SharpZipLib to an attempt to access an already disposed Stream #379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
koide opened this issue Aug 23, 2019 · 2 comments
Labels
bug core stream gzip tar Related to TAR file format

Comments

@koide
Copy link

koide commented Aug 23, 2019

I'm downloading a file from an FTP server and unzipping, untarring it on the fly, via the underlying streams. The code looks like this:

var request = WebRequest.Create("ftp://host/file.tgz");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential("user","password");
var response = (FtpWebResponse) await request.GetResponseAsync();
using (var gzStr = new GZipInputStream(response.GetResponseStream()))
{
    gzStr.IsStreamOwner = false;
    var tar = TarArchive.CreateInputTarArchive(gzStr);
    Directory.CreateDirectory(_targetPath);
    tar.IsStreamOwner = false;
    tar.ExtractContents(_targetPath);
}

With the current 1.2.0 release (and 1.1.0 and 1.0.0) I get an ObjectDisposedException on the network socket stream, but it happens after the whole file has been extracted successfully, so it seems to be yet another exceptional case happening after finishing the file.

In my total ignorance of this code, I've tracked the issue to this line:

catch (Exception ex) when (completedLastBlock && (ex is GZipException || ex is EndOfStreamException))

 catch (Exception ex) when (completedLastBlock && 
    (ex is GZipException || ex is EndOfStreamException)) 

and, changing it to

catch (Exception ex) when (completedLastBlock && 
    (ex is GZipException || ex is EndOfStreamException ||
     ex is ObjectDisposedException))

makes my specific case work successfully. I think that the server ends the connection after the file is downloaded so the stream is not there to be read from anymore.

@piksel piksel added bug core stream gzip tar Related to TAR file format labels Aug 23, 2019
@Numpsy
Copy link
Contributor

Numpsy commented Aug 24, 2019

The discussion @ https://stackoverflow.com/questions/48829032/streamreader-readline-throwing-disposed-exception-rather-than-returning-null suggests that the FTP response stream closes itself when all the data is read, which could cause issues with stacked streams?

Maybe the multiple-block handling loop in GZipInputStream.Read could check stream.CanRead before trying to read a second block?

@koide
Copy link
Author

koide commented Aug 26, 2019

Yup, looks like it's not the server but FtpWebRequest's FtpDataStream.

I can confirm that doing

while (toRead > 0 && inputStream.CanRead)

instead of

makes it work in my case as well, and looks like a saner approach.

Numpsy added a commit to Numpsy/SharpZipLib that referenced this issue Sep 15, 2019
@piksel piksel closed this as completed Jan 13, 2020
piksel pushed a commit that referenced this issue Feb 1, 2020
* Unit test for issue #379
* Change InflaterInputBuffer.Fill() to stop trying to read from inputStream in its CanRead property is false.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug core stream gzip tar Related to TAR file format
Projects
None yet
Development

No branches or pull requests

3 participants