diff --git a/docker/api/build.py b/docker/api/build.py index 439f4dc3..1f6a6e2d 100644 --- a/docker/api/build.py +++ b/docker/api/build.py @@ -129,6 +129,9 @@ class BuildApiMixin: raise errors.DockerException( 'Can not use custom encoding if gzip is enabled' ) + if tag is not None: + if not utils.match_tag(tag): + raise errors.DockerException(f"invalid tag '{tag}': invalid reference format") for key in container_limits.keys(): if key not in constants.CONTAINER_LIMITS_KEYS: diff --git a/docker/utils/__init__.py b/docker/utils/__init__.py index 944c6e65..b4bef7d4 100644 --- a/docker/utils/__init__.py +++ b/docker/utils/__init__.py @@ -1,5 +1,5 @@ -from .build import create_archive, exclude_paths, mkbuildcontext, tar +from .build import match_tag, create_archive, exclude_paths, mkbuildcontext, tar from .decorators import check_resource, minimum_version, update_headers from .utils import ( compare_version, convert_port_bindings, convert_volume_binds, diff --git a/docker/utils/build.py b/docker/utils/build.py index 8d18c2be..a5c4b0c2 100644 --- a/docker/utils/build.py +++ b/docker/utils/build.py @@ -9,6 +9,14 @@ from ..constants import IS_WINDOWS_PLATFORM _SEP = re.compile('/|\\\\') if IS_WINDOWS_PLATFORM else re.compile('/') +_TAG = re.compile( + r"^[a-z0-9]+((\.|_|__|-+)[a-z0-9]+)*(\/[a-z0-9]+((\.|_|__|-+)[a-z0-9]+)*)*" \ + + "(:[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127})?$" +) + + +def match_tag(tag: str) -> bool: + return bool(_TAG.match(tag)) def tar(path, exclude=None, dockerfile=None, fileobj=None, gzip=False): diff --git a/tests/unit/api_build_test.py b/tests/unit/api_build_test.py index cbecd1e5..7ea8fddf 100644 --- a/tests/unit/api_build_test.py +++ b/tests/unit/api_build_test.py @@ -100,6 +100,12 @@ class BuildTest(BaseAPIClientTest): def test_build_container_with_named_dockerfile(self): self.client.build('.', dockerfile='nameddockerfile') + def test_build_with_invalid_tag(self): + with pytest.raises(TypeError): + self.client.build( + ".", dockerfile="nameddockerfile", tag="https://example.com" + ) + def test_build_container_with_container_limits(self): self.client.build('.', container_limits={ 'memory': 1024 * 1024,