Merge pull request #189268 from onny/sanic
python310Packages.sanic: 22.3.2 -> 22.6.2
This commit is contained in:
commit
bbb3b41625
5 changed files with 75 additions and 157 deletions
38
pkgs/development/python-modules/aioquic/default.nix
Normal file
38
pkgs/development/python-modules/aioquic/default.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ lib
|
||||
, fetchPypi
|
||||
, buildPythonPackage
|
||||
, openssl
|
||||
, pylsqpack
|
||||
, certifi
|
||||
, pytestCheckHook
|
||||
, pyopenssl
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aioquic";
|
||||
version = "0.9.20";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-7ENqqs6Ze4RrAeUgDtv34+VrkYJqFE77l0j9jd0zK74=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
certifi
|
||||
pylsqpack
|
||||
pyopenssl
|
||||
];
|
||||
|
||||
buildInputs = [ openssl ];
|
||||
|
||||
checkInputs = [ pytestCheckHook ];
|
||||
|
||||
pythonImportsCheck = [ "aioquic" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Implementation of QUIC and HTTP/3";
|
||||
homepage = "https://github.com/aiortc/aioquic";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ onny ];
|
||||
};
|
||||
}
|
26
pkgs/development/python-modules/pylsqpack/default.nix
Normal file
26
pkgs/development/python-modules/pylsqpack/default.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ lib
|
||||
, fetchPypi
|
||||
, buildPythonPackage
|
||||
, pytestCheckHook
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "pylsqpack";
|
||||
version = "0.3.16";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-tnps4/aTfYUGgYJ3FL5zCqNhwEnjd1Lj7Z3xHn8jL/s=";
|
||||
};
|
||||
|
||||
checkInputs = [ pytestCheckHook ];
|
||||
|
||||
pythonImportsCheck = [ "pylsqpack" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Python wrapper for the ls-qpack QPACK library";
|
||||
homepage = "https://github.com/aiortc/pylsqpack";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ onny ];
|
||||
};
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
Based on upstream 9d415e4ec63d31b3749fd540e2c2ac7c98dedcdd and
|
||||
2fa28f1711a8e59c6f4d3468e9c2f8b6991188a2, adjusted to apply to
|
||||
v22.3.2, raise the same exception as before and not remove any
|
||||
imports.
|
||||
|
||||
diff --git a/sanic/mixins/routes.py b/sanic/mixins/routes.py
|
||||
index 9e2cf96..e0cf86b 100644
|
||||
--- a/sanic/mixins/routes.py
|
||||
+++ b/sanic/mixins/routes.py
|
||||
@@ -3,7 +3,7 @@ from contextlib import suppress
|
||||
from functools import partial, wraps
|
||||
from inspect import getsource, signature
|
||||
from mimetypes import guess_type
|
||||
-from os import path
|
||||
+from os import path, sep
|
||||
from pathlib import PurePath
|
||||
from re import sub
|
||||
from textwrap import dedent
|
||||
@@ -775,23 +775,23 @@ class RouteMixin(metaclass=SanicMeta):
|
||||
content_type=None,
|
||||
__file_uri__=None,
|
||||
):
|
||||
- # Using this to determine if the URL is trying to break out of the path
|
||||
- # served. os.path.realpath seems to be very slow
|
||||
- if __file_uri__ and "../" in __file_uri__:
|
||||
- raise InvalidUsage("Invalid URL")
|
||||
# Merge served directory and requested file if provided
|
||||
- # Strip all / that in the beginning of the URL to help prevent python
|
||||
- # from herping a derp and treating the uri as an absolute path
|
||||
- root_path = file_path = file_or_directory
|
||||
+ root_path = file_path = path.abspath(unquote(file_or_directory))
|
||||
+
|
||||
if __file_uri__:
|
||||
- file_path = path.join(
|
||||
- file_or_directory, sub("^[/]*", "", __file_uri__)
|
||||
- )
|
||||
+ # Strip all / that in the beginning of the URL to help prevent
|
||||
+ # python from herping a derp and treating the uri as an
|
||||
+ # absolute path
|
||||
+ unquoted_file_uri = unquote(__file_uri__).lstrip("/")
|
||||
+
|
||||
+ segments = unquoted_file_uri.split("/")
|
||||
+ if ".." in segments or any(sep in segment for segment in segments):
|
||||
+ raise InvalidUsage("Invalid URL")
|
||||
+
|
||||
+ file_path = path.join(file_or_directory, unquoted_file_uri)
|
||||
+ file_path = path.abspath(file_path)
|
||||
|
||||
- # URL decode the path sent by the browser otherwise we won't be able to
|
||||
- # match filenames which got encoded (filenames with spaces etc)
|
||||
- file_path = path.abspath(unquote(file_path))
|
||||
- if not file_path.startswith(path.abspath(unquote(root_path))):
|
||||
+ if not file_path.startswith(root_path):
|
||||
error_logger.exception(
|
||||
f"File not found: path={file_or_directory}, "
|
||||
f"relative_url={__file_uri__}"
|
||||
diff --git a/tests/test_static.py b/tests/test_static.py
|
||||
index 36a98e1..aeb625b 100644
|
||||
--- a/tests/test_static.py
|
||||
+++ b/tests/test_static.py
|
||||
@@ -1,6 +1,7 @@
|
||||
import inspect
|
||||
import logging
|
||||
import os
|
||||
+import sys
|
||||
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
@@ -8,7 +9,7 @@ from time import gmtime, strftime
|
||||
|
||||
import pytest
|
||||
|
||||
-from sanic import text
|
||||
+from sanic import Sanic, text
|
||||
from sanic.exceptions import FileNotFound
|
||||
|
||||
|
||||
@@ -21,6 +22,22 @@ def static_file_directory():
|
||||
return static_directory
|
||||
|
||||
|
||||
+@pytest.fixture(scope="module")
|
||||
+def double_dotted_directory_file(static_file_directory: str):
|
||||
+ """Generate double dotted directory and its files"""
|
||||
+ if sys.platform == "win32":
|
||||
+ raise Exception("Windows doesn't support double dotted directories")
|
||||
+
|
||||
+ file_path = Path(static_file_directory) / "dotted.." / "dot.txt"
|
||||
+ double_dotted_dir = file_path.parent
|
||||
+ Path.mkdir(double_dotted_dir, exist_ok=True)
|
||||
+ with open(file_path, "w") as f:
|
||||
+ f.write("DOT\n")
|
||||
+ yield file_path
|
||||
+ Path.unlink(file_path)
|
||||
+ Path.rmdir(double_dotted_dir)
|
||||
+
|
||||
+
|
||||
def get_file_path(static_file_directory, file_name):
|
||||
return os.path.join(static_file_directory, file_name)
|
||||
|
||||
@@ -578,3 +595,40 @@ def test_resource_type_dir(app, static_file_directory):
|
||||
def test_resource_type_unknown(app, static_file_directory, caplog):
|
||||
with pytest.raises(ValueError):
|
||||
app.static("/static", static_file_directory, resource_type="unknown")
|
||||
+
|
||||
+
|
||||
+@pytest.mark.skipif(
|
||||
+ sys.platform == "win32",
|
||||
+ reason="Windows does not support double dotted directories",
|
||||
+)
|
||||
+def test_dotted_dir_ok(
|
||||
+ app: Sanic, static_file_directory: str, double_dotted_directory_file: Path
|
||||
+):
|
||||
+ app.static("/foo", static_file_directory)
|
||||
+ dot_relative_path = str(
|
||||
+ double_dotted_directory_file.relative_to(static_file_directory)
|
||||
+ )
|
||||
+ _, response = app.test_client.get("/foo/" + dot_relative_path)
|
||||
+ assert response.status == 200
|
||||
+ assert response.body == b"DOT\n"
|
||||
+
|
||||
+
|
||||
+def test_breakout(app: Sanic, static_file_directory: str):
|
||||
+ app.static("/foo", static_file_directory)
|
||||
+
|
||||
+ _, response = app.test_client.get("/foo/..%2Fstatic/test.file")
|
||||
+ assert response.status == 400
|
||||
+
|
||||
+
|
||||
+@pytest.mark.skipif(
|
||||
+ sys.platform != "win32", reason="Block backslash on Windows only"
|
||||
+)
|
||||
+def test_double_backslash_prohibited_on_win32(
|
||||
+ app: Sanic, static_file_directory: str
|
||||
+):
|
||||
+ app.static("/foo", static_file_directory)
|
||||
+
|
||||
+ _, response = app.test_client.get("/foo/static/..\\static/test.file")
|
||||
+ assert response.status == 400
|
||||
+ _, response = app.test_client.get("/foo/static\\../static/test.file")
|
||||
+ assert response.status == 400
|
|
@ -20,11 +20,12 @@
|
|||
, uvicorn
|
||||
, uvloop
|
||||
, websockets
|
||||
, aioquic
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "sanic";
|
||||
version = "22.3.2";
|
||||
version = "22.6.2";
|
||||
format = "setuptools";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
|
@ -33,22 +34,12 @@ buildPythonPackage rec {
|
|||
owner = "sanic-org";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
hash = "sha256-4zdPp3X22dfZ5YlW3G5/OqeUxrt+NiFO9dk2XjEKXEg=";
|
||||
hash = "sha256-krEQd0ak9Uua+r+pYmLStlizgE4HmZBO8Q0I2/gWAwU=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
./22.3.2-CVE-2022-35920.patch
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# Loosen dependency requirements.
|
||||
substituteInPlace setup.py \
|
||||
--replace "pytest==6.2.5" "pytest" \
|
||||
--replace "gunicorn==20.0.4" "gunicorn"
|
||||
'';
|
||||
|
||||
propagatedBuildInputs = [
|
||||
aiofiles
|
||||
aioquic
|
||||
httptools
|
||||
multidict
|
||||
sanic-routing
|
||||
|
@ -88,6 +79,8 @@ buildPythonPackage rec {
|
|||
];
|
||||
|
||||
disabledTests = [
|
||||
# Require networking
|
||||
"test_full_message"
|
||||
# Fails to parse cmdline arguments
|
||||
"test_dev"
|
||||
"test_auto_reload"
|
||||
|
@ -130,9 +123,7 @@ buildPythonPackage rec {
|
|||
# for the same local port
|
||||
__darwinAllowLocalNetworking = true;
|
||||
|
||||
pythonImportsCheck = [
|
||||
"sanic"
|
||||
];
|
||||
pythonImportsCheck = [ "sanic" ];
|
||||
|
||||
meta = with lib; {
|
||||
broken = stdenv.isDarwin;
|
||||
|
|
|
@ -284,6 +284,8 @@ self: super: with self; {
|
|||
|
||||
aioqsw = callPackage ../development/python-modules/aioqsw { };
|
||||
|
||||
aioquic = callPackage ../development/python-modules/aioquic { };
|
||||
|
||||
aiorecollect = callPackage ../development/python-modules/aiorecollect { };
|
||||
|
||||
aioredis = callPackage ../development/python-modules/aioredis { };
|
||||
|
@ -8036,6 +8038,8 @@ self: super: with self; {
|
|||
|
||||
pylru = callPackage ../development/python-modules/pylru { };
|
||||
|
||||
pylsqpack = callPackage ../development/python-modules/pylsqpack { };
|
||||
|
||||
pyls-black = callPackage ../development/python-modules/pyls-black { };
|
||||
|
||||
pyls-flake8 = callPackage ../development/python-modules/pyls-flake8 { };
|
||||
|
|
Loading…
Reference in a new issue