Mercurial > public > mercurial-scm > hg
comparison mercurial/httppeer.py @ 39484:98995b689e03
httppeer: use util.readexactly() to abort on incomplete responses
Plain resp.read(n) may not return exactly n bytes when we need, and to detect
such cases before trying to interpret whatever has been read, we can use
util.readexactly(), which raises an Abort when stream ends unexpectedly. In the
first case here, readexactly() prevents a traceback with struct.error, in the
second it avoids looking for invalid compression engines.
In this test case, _wraphttpresponse doesn't catch the problem (presumably
because it doesn't know transfer encoding), and the code continues reading the
response until it gets to compression engine data. Maybe there should be checks
before the execution gets there, but I'm not sure where (httplib?)
author | Anton Shestakov <av6@dwimlabs.net> |
---|---|
date | Sat, 08 Sep 2018 21:58:51 +0800 |
parents | 1fc39367eafd |
children | 089fc0db0954 |
comparison
equal
deleted
inserted
replaced
39483:1fc39367eafd | 39484:98995b689e03 |
---|---|
399 resp = util.compengines['zlib'].decompressorreader(resp) | 399 resp = util.compengines['zlib'].decompressorreader(resp) |
400 | 400 |
401 elif version_info == (0, 2): | 401 elif version_info == (0, 2): |
402 # application/mercurial-0.2 always identifies the compression | 402 # application/mercurial-0.2 always identifies the compression |
403 # engine in the payload header. | 403 # engine in the payload header. |
404 elen = struct.unpack('B', resp.read(1))[0] | 404 elen = struct.unpack('B', util.readexactly(resp, 1))[0] |
405 ename = resp.read(elen) | 405 ename = util.readexactly(resp, elen) |
406 engine = util.compengines.forwiretype(ename) | 406 engine = util.compengines.forwiretype(ename) |
407 | 407 |
408 resp = engine.decompressorreader(resp) | 408 resp = engine.decompressorreader(resp) |
409 else: | 409 else: |
410 raise error.RepoError(_("'%s' uses newer protocol %s") % | 410 raise error.RepoError(_("'%s' uses newer protocol %s") % |