summaryrefslogtreecommitdiff
path: root/devel/viewvc-devel
diff options
context:
space:
mode:
Diffstat (limited to 'devel/viewvc-devel')
-rw-r--r--devel/viewvc-devel/Makefile1
-rw-r--r--devel/viewvc-devel/files/patch-bin_standalone.py74
-rw-r--r--devel/viewvc-devel/files/patch-lib_viewvc.py39
-rw-r--r--devel/viewvc-devel/pkg-plist58
4 files changed, 143 insertions, 29 deletions
diff --git a/devel/viewvc-devel/Makefile b/devel/viewvc-devel/Makefile
index 658733568732..96e7f66c20a4 100644
--- a/devel/viewvc-devel/Makefile
+++ b/devel/viewvc-devel/Makefile
@@ -1,5 +1,6 @@
PORTNAME= viewvc
DISTVERSION= 1.3.0-20250316
+PORTREVISION= 1
CATEGORIES= devel python
PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
PKGNAMESUFFIX= -devel
diff --git a/devel/viewvc-devel/files/patch-bin_standalone.py b/devel/viewvc-devel/files/patch-bin_standalone.py
new file mode 100644
index 000000000000..4397053b7391
--- /dev/null
+++ b/devel/viewvc-devel/files/patch-bin_standalone.py
@@ -0,0 +1,74 @@
+--- bin/standalone.py.orig 2025-07-22 12:12:06 UTC
++++ bin/standalone.py
+@@ -191,18 +191,17 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe
+ </html>"""
+ )
+
+- def is_viewvc(self):
++ def is_viewvc(self, path):
+ """Check whether self.path is, or is a child of, the ScriptAlias"""
++ if not path.startswith("/"):
++ return False
+ if not options.script_alias:
+- return 1
+- if self.path == "/" + options.script_alias:
+- return 1
+- alias_len = len(options.script_alias)
+- if self.path[: (alias_len + 2)] == "/" + options.script_alias + "/":
+- return 1
+- if self.path[: (alias_len + 2)] == "/" + options.script_alias + "?":
+- return 1
+- return 0
++ return True
++ if path == "/" + options.script_alias:
++ return True
++ if path.startswith("/" + options.script_alias + "/"):
++ return True
++ return False
+
+ def validate_password(self, htpasswd_file, username, password):
+ """Compare USERNAME and PASSWORD against HTPASSWD_FILE."""
+@@ -219,8 +218,18 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe
+ # NOTE: Much of this is adapter from Python's standard library
+ # module CGIHTTPServer.
+
++ i = self.path.rfind("?")
++ if i >= 0:
++ path = _unquote(self.path[:i], "utf-8", "surrogateescape")
++ query = self.path[(i + 1) :]
++ else:
++ path = _unquote(self.path)
++ query = ""
++ # normalize path
++ path = os.path.normpath(path) + ("/" if path[-1] == "/" else "")
++
+ # Is this request even aimed at ViewVC? If not, complain.
+- if not self.is_viewvc():
++ if not self.is_viewvc(path):
+ raise NotViewVCLocationException()
+
+ # If htpasswd authentication is enabled, try to authenticate the user.
+@@ -245,12 +254,7 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe
+
+ scriptname = options.script_alias and "/" + options.script_alias or ""
+
+- rest = self.path[len(scriptname) :]
+- i = rest.rfind("?")
+- if i >= 0:
+- rest, query = rest[:i], rest[(i + 1) :]
+- else:
+- query = ""
++ rest = path[len(scriptname) :]
+
+ # Since we're going to modify the env in the parent, provide empty
+ # values to override previously set values
+@@ -274,8 +278,7 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe
+ env["SERVER_PROTOCOL"] = self.protocol_version
+ env["SERVER_PORT"] = str(self.server.server_port)
+ env["REQUEST_METHOD"] = self.command
+- uqrest = _unquote(rest, "utf-8", "surrogateescape")
+- env["PATH_INFO"] = uqrest
++ env["PATH_INFO"] = rest
+ env["SCRIPT_NAME"] = scriptname
+ if query:
+ env["QUERY_STRING"] = query
diff --git a/devel/viewvc-devel/files/patch-lib_viewvc.py b/devel/viewvc-devel/files/patch-lib_viewvc.py
new file mode 100644
index 000000000000..739d60e1a50a
--- /dev/null
+++ b/devel/viewvc-devel/files/patch-lib_viewvc.py
@@ -0,0 +1,39 @@
+--- lib/viewvc.py.orig 2025-07-22 12:12:06 UTC
++++ lib/viewvc.py
+@@ -193,6 +193,10 @@ class Request:
+ # TODO: we might want to redirect to the cleaned up URL
+ path_parts = _path_parts(path_info)
+
++ # Protect against directory traversal attacks.
++ if ".." in path_parts:
++ raise ViewVCException("An illegal path was provided.", "400 Bad Request")
++
+ if path_parts:
+ # handle docroot magic path prefixes
+ if path_parts[0] == docroot_magic_path:
+@@ -3401,10 +3405,8 @@ def view_doc(request):
+ # Stat the file to get content length and last-modified date.
+ try:
+ info = os.stat(filename)
+- except OSError as v:
+- raise ViewVCException(
+- 'Static file "%s" not available (%s)' % (document, str(v)), "404 Not Found"
+- )
++ except OSError:
++ raise ViewVCException('Static file "%s" not available' % (document), "404 Not Found")
+ content_length = str(info[stat.ST_SIZE])
+ last_modified = info[stat.ST_MTIME]
+
+@@ -3414,10 +3416,8 @@ def view_doc(request):
+
+ try:
+ fp = open(filename, "rb")
+- except IOError as v:
+- raise ViewVCException(
+- 'Static file "%s" not available (%s)' % (document, str(v)), "404 Not Found"
+- )
++ except IOError:
++ raise ViewVCException('Static file "%s" not available' % (document), "404 Not Found")
+
+ if document[-3:] == "png":
+ mime_type = "image/png"
diff --git a/devel/viewvc-devel/pkg-plist b/devel/viewvc-devel/pkg-plist
index a5b30420e2f9..e7ec935b8792 100644
--- a/devel/viewvc-devel/pkg-plist
+++ b/devel/viewvc-devel/pkg-plist
@@ -10,17 +10,17 @@ viewvc/bin/standalone.py
viewvc/bin/wsgi/viewvc.fcgi
viewvc/bin/wsgi/viewvc.wsgi
@sample viewvc/cvsgraph.conf.sample
-viewvc/lib/__pycache__/accept%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/blame%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/common%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/config%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/cvsdb%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/dbi%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/ezt%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/idiff%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/popen%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/sapi%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/__pycache__/viewvc%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/__pycache__/accept%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/blame%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/common%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/config%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/cvsdb%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/dbi%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/ezt%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/idiff%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/popen%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/sapi%%PYTHON_TAG%%.pyc
+viewvc/lib/__pycache__/viewvc%%PYTHON_TAG%%.pyc
viewvc/lib/accept.py
viewvc/lib/blame.py
viewvc/lib/common.py
@@ -32,30 +32,30 @@ viewvc/lib/idiff.py
viewvc/lib/popen.py
viewvc/lib/sapi.py
viewvc/lib/vcauth/__init__.py
-viewvc/lib/vcauth/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vcauth/__pycache__/__init__%%PYTHON_TAG%%.pyc
viewvc/lib/vcauth/forbidden/__init__.py
-viewvc/lib/vcauth/forbidden/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vcauth/forbidden/__pycache__/__init__%%PYTHON_TAG%%.pyc
viewvc/lib/vcauth/forbiddenre/__init__.py
-viewvc/lib/vcauth/forbiddenre/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vcauth/forbiddenre/__pycache__/__init__%%PYTHON_TAG%%.pyc
viewvc/lib/vcauth/svnauthz/__init__.py
-viewvc/lib/vcauth/svnauthz/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vcauth/svnauthz/__pycache__/__init__%%PYTHON_TAG%%.pyc
viewvc/lib/vclib/__init__.py
-viewvc/lib/vclib/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vclib/__pycache__/__init__%%PYTHON_TAG%%.pyc
viewvc/lib/vclib/ccvs/__init__.py
-viewvc/lib/vclib/ccvs/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/__pycache__/bincvs%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/__pycache__/blame%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/__pycache__/ccvs%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vclib/ccvs/__pycache__/__init__%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/__pycache__/bincvs%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/__pycache__/blame%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/__pycache__/ccvs%%PYTHON_TAG%%.pyc
viewvc/lib/vclib/ccvs/bincvs.py
viewvc/lib/vclib/ccvs/blame.py
viewvc/lib/vclib/ccvs/ccvs.py
viewvc/lib/vclib/ccvs/rcsparse/__init__.py
-viewvc/lib/vclib/ccvs/rcsparse/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/rcsparse/__pycache__/common%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/rcsparse/__pycache__/debug%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/rcsparse/__pycache__/default%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/rcsparse/__pycache__/parse_rcs_file%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/ccvs/rcsparse/__pycache__/run-tests%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vclib/ccvs/rcsparse/__pycache__/__init__%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/rcsparse/__pycache__/common%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/rcsparse/__pycache__/debug%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/rcsparse/__pycache__/default%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/rcsparse/__pycache__/parse_rcs_file%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/ccvs/rcsparse/__pycache__/run-tests%%PYTHON_TAG%%.pyc
viewvc/lib/vclib/ccvs/rcsparse/common.py
viewvc/lib/vclib/ccvs/rcsparse/debug.py
viewvc/lib/vclib/ccvs/rcsparse/default.py
@@ -66,9 +66,9 @@ viewvc/lib/vclib/ccvs/rcsparse/test-data/default.out
viewvc/lib/vclib/ccvs/rcsparse/test-data/empty-file,v
viewvc/lib/vclib/ccvs/rcsparse/test-data/empty-file.out
viewvc/lib/vclib/svn/__init__.py
-viewvc/lib/vclib/svn/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/svn/__pycache__/svn_ra%%PYTHON_EXT_SUFFIX%%.pyc
-viewvc/lib/vclib/svn/__pycache__/svn_repos%%PYTHON_EXT_SUFFIX%%.pyc
+viewvc/lib/vclib/svn/__pycache__/__init__%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/svn/__pycache__/svn_ra%%PYTHON_TAG%%.pyc
+viewvc/lib/vclib/svn/__pycache__/svn_repos%%PYTHON_TAG%%.pyc
viewvc/lib/vclib/svn/svn_ra.py
viewvc/lib/vclib/svn/svn_repos.py
viewvc/lib/viewvc.py