diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py --- a/mercurial/hgweb/server.py +++ b/mercurial/hgweb/server.py @@ -118,6 +118,14 @@ class _httprequesthandler(httpservermod. self.sent_headers = False path, query = _splitURI(self.path) + # Ensure the slicing of path below is valid + if (path != self.server.prefix + and not path.startswith(self.server.prefix + b'/')): + self._start_response(common.statusmessage(404), []) + self._write("Not Found") + self._done() + return + env = {} env[r'GATEWAY_INTERFACE'] = r'CGI/1.1' env[r'REQUEST_METHOD'] = self.command diff --git a/tests/test-serve.t b/tests/test-serve.t --- a/tests/test-serve.t +++ b/tests/test-serve.t @@ -78,4 +78,24 @@ With --prefix /foo/ listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob) (?) % errors + $ $PYTHON $RUNTESTDIR/killdaemons.py $DAEMON_PIDS + +With out of bounds accesses + + $ rm access.log + $ hg serve -a localhost -p $HGPORT -d --prefix some/dir \ + > --pid-file=hg.pid -E errors.log + $ cat hg.pid >> "$DAEMON_PIDS" + + $ hg id http://localhost:$HGPORT/some/dir7 + abort: HTTP Error 404: Not Found + [255] + $ hg id http://localhost:$HGPORT/some + abort: HTTP Error 404: Not Found + [255] + + $ cat access.log errors.log + $LOCALIP - - [$LOGDATE$] "GET /some/dir7?cmd=capabilities HTTP/1.1" 404 - (glob) + $LOCALIP - - [$LOGDATE$] "GET /some?cmd=capabilities HTTP/1.1" 404 - (glob) + $ cd ..