Mercurial > hg4j
comparison src/org/tmatesoft/hg/internal/InflaterDataAccess.java @ 399:fdc1db8f7f61 smartgit3
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Sat, 25 Feb 2012 19:31:57 +0100 |
parents | 856517285256 |
children | 6c22bdc0bdfd |
comparison
equal
deleted
inserted
replaced
397:5e95b0da26f2 | 399:fdc1db8f7f61 |
---|---|
156 public void readBytes(byte[] b, int off, int len) throws IOException { | 156 public void readBytes(byte[] b, int off, int len) throws IOException { |
157 try { | 157 try { |
158 int n; | 158 int n; |
159 while (len > 0) { | 159 while (len > 0) { |
160 while ((n = inflater.inflate(b, off, len)) == 0) { | 160 while ((n = inflater.inflate(b, off, len)) == 0) { |
161 // FIXME few last bytes (checksum?) may be ignored by inflater, thus inflate may return 0 in | 161 // XXX few last bytes (checksum?) may be ignored by inflater, thus inflate may return 0 in |
162 // perfectly legal conditions (when all data already expanded, but there are still some bytes | 162 // perfectly legal conditions (when all data already expanded, but there are still some bytes |
163 // in the input stream | 163 // in the input stream) |
164 if (inflater.finished() || inflater.needsDictionary()) { | 164 int toRead = -1; |
165 throw new EOFException(); | 165 if (inflater.needsInput() && (toRead = super.available()) > 0) { |
166 } | |
167 if (inflater.needsInput()) { | |
168 // fill: | 166 // fill: |
169 int toRead = super.available(); | |
170 if (toRead > buffer.length) { | 167 if (toRead > buffer.length) { |
171 toRead = buffer.length; | 168 toRead = buffer.length; |
172 } | 169 } |
173 super.readBytes(buffer, 0, toRead); | 170 super.readBytes(buffer, 0, toRead); |
174 inflater.setInput(buffer, 0, toRead); | 171 inflater.setInput(buffer, 0, toRead); |
172 } else { | |
173 // prevent hang up in this cycle if no more data is available, see Issue 25 | |
174 throw new EOFException(String.format("No more compressed data is available to satisfy request for %d bytes. [finished:%b, needDict:%b, needInp:%b, available:%d", len, inflater.finished(), inflater.needsDictionary(), inflater.needsInput(), toRead)); | |
175 } | 175 } |
176 } | 176 } |
177 off += n; | 177 off += n; |
178 len -= n; | 178 len -= n; |
179 decompressedPos += n; | 179 decompressedPos += n; |