{
  "WorkItem": {
    "AffectedComponent": {
      "Name": "",
      "DisplayName": ""
    },
    "ClosedComment": "changeset 32065. Will be first avail in v1.8.3.11",
    "ClosedDate": "2009-05-26T12:04:25.23-07:00",
    "CommentCount": 0,
    "Custom": null,
    "Description": "According to MS documentation, any implementation of the IO.Stream.Read function must:\n(a) throw an exception if offset & count reference an invalid part of the buffer, or if count < 0, or if buffer is null\n(b) return 0 only upon EOF, or if count = 0\n(c) if not EOF, then return at least 1 byte, up to <count> bytes\n \nThe ZlibBaseStream.Read function does not follow this schematic, and so simple compression and decompression tasks using DeflateStream fail, as shown below:\n \nSub Main()\n    Dim TextToCompress As String = \"This is a test; this is a test\"\n    Dim CompressedDataStream As New IO.MemoryStream\n    Dim CompressionStream As New Ionic.Zlib.DeflateStream(CompressedDataStream, Ionic.Zlib.CompressionMode.Compress)\n    Dim MyTextWriter As New IO.StreamWriter(CompressionStream)\n    MyTextWriter.Write(TextToCompress)\n    MyTextWriter.Close()\n    CompressedDataStream = New IO.MemoryStream(CompressedDataStream.ToArray, False)\n    Console.WriteLine(\"Writing \" & TextToCompress.Length & \" bytes to compression stream: '\" & TextToCompress & \"'\")\n    Console.WriteLine(\"Compressed stream is \" & CompressedDataStream.Length & \" bytes long\")\n    Dim DecompressionStream As New Ionic.Zlib.DeflateStream(CompressedDataStream, Ionic.Zlib.CompressionMode.Decompress)\n    Dim MyTextReader As New IO.StreamReader(DecompressionStream)\n    Dim DecompressedText As String = MyTextReader.ReadToEnd\n    Console.WriteLine(\"Read \" & DecompressedText.Length & \" characters: '\" & DecompressedText & \"'\")\n    Console.WriteLine(\"Press enter to exit\")\n    Console.ReadLine()\nEnd Sub\n \nPlease see the attached VB module (a console app), which also demonstrates a problem with the LEVEL1 compression mode, which may or may not be related.\n \nNote that using Microsoft's DeflateStream implementation works properly, even if it's worthless due to poor \"compression\" code, which usually produces 'compressed' data that's larger than the original.\n \nThanks, Shane",
    "LastUpdatedDate": "2013-05-16T05:32:22.93-07:00",
    "PlannedForRelease": "",
    "ReleaseVisibleToPublic": false,
    "Priority": {
      "Name": "Low",
      "Severity": 50,
      "Id": 1
    },
    "ProjectName": "DotNetZip",
    "ReportedDate": "2009-05-25T11:45:14.85-07:00",
    "Status": {
      "Name": "Closed",
      "Id": 4
    },
    "ReasonClosed": {
      "Name": "Unassigned"
    },
    "Summary": "ZlibBaseStream.Read does not return 0 upon EOF",
    "Type": {
      "Name": "Issue",
      "Id": 3
    },
    "VoteCount": 1,
    "Id": 7809
  },
  "FileAttachments": [
    {
      "FileId": 1969,
      "FileName": "Module1.vb",
      "DownloadUrl": ".\\1969"
    },
    {
      "FileId": 1970,
      "FileName": "updated zlib code.txt",
      "DownloadUrl": ".\\1970"
    }
  ],
  "Comments": [
    {
      "Message": "I see you updated the Read function to properly return 0 in your latest 1.8.3.9 release.  However, it still does not properly decode all streams.  This is due to a Z_BUF_ERROR when the input stream is empty.  These lines of code fix the issue:\r\n\r\nif (_z.AvailableBytesIn == 0) nomoreinput = true;\r\n\r\nand\r\n\r\nif (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR))\r\nreturn (0);\r\n\r\nThis issue is demonstratable in the test program attached above (module1.vb) with your new source code, but works properly with the above changes.  (This is the LEVEL1 compression mode problem I mentioned previously).\r\n\r\nI also changed the call to SharedUtils.ReadInput to a direct call to the stream's Read function, since the SharedUtils.ReadInput function is pointless.\r\n\r\nAlso, if the caller passes an invalid buffer or offset/count parameters to your function, the internal memory structures of the codec will be messed up if the error is caught.  I added checks for invalid buffers in the code.\r\n\r\nI also moved the CanRead check into the reader initialization if block, saving a check of this parameter upon every call to Read, and also changed the next if block to an elseif block.\r\n\r\nPlease see updated Read function, attached.\r\n\r\nHope this helps,\r\nShane",
      "PostedDate": "2009-05-26T08:34:30.76-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2009-05-26T08:34:33.243-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Oh, \"break;\" might be more appropriate than \"return (0);\", although it should not make a difference during execution.\r\n\r\nif (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR))\r\nbreak;",
      "PostedDate": "2009-05-26T08:36:27.537-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Shane, thanks, very helpful. I love to see bug reports with test code, and you even provide the fix.  Nice work, thank you.\r\n",
      "PostedDate": "2009-05-26T11:12:59.123-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2009-05-26T12:04:25.23-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-02-21T18:44:19.727-08:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-05-16T05:32:22.93-07:00",
      "Id": -2147483648
    }
  ]
}