Skip to content

Commit

Permalink
Merge pull request #1177 from strictdoc-project/stanislaw/1157-includ…
Browse files Browse the repository at this point in the history
…e-exclude-filters

 helpers/path_filter: basic validation of user input
  • Loading branch information
stanislaw committed May 28, 2023
2 parents 9f57291 + 5370bb0 commit cdd46dd
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 11 deletions.
2 changes: 1 addition & 1 deletion strictdoc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from strictdoc.core.environment import SDocRuntimeEnvironment

__version__ = "0.0.42a3"
__version__ = "0.0.42a5"


environment = SDocRuntimeEnvironment(__file__)
40 changes: 40 additions & 0 deletions strictdoc/core/project_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import toml

from strictdoc.helpers.auto_described import auto_described
from strictdoc.helpers.path_filter import validate_mask


class ProjectFeature(str, Enum):
Expand Down Expand Up @@ -167,18 +168,57 @@ def _load_from_dictionary(config_dict: dict) -> ProjectConfig:
"include_doc_paths", include_doc_paths
)
assert isinstance(include_doc_paths, list)
for include_doc_path in include_doc_paths:
try:
validate_mask(include_doc_path)
except SyntaxError as exception:
print( # noqa: T201
f"error: strictdoc.toml: 'include_doc_paths': "
f"{exception} Provided string: '{include_doc_path}'."
)
sys.exit(1)

exclude_doc_paths = project_content.get(
"exclude_doc_paths", exclude_doc_paths
)
assert isinstance(exclude_doc_paths, list)
for exclude_doc_path in exclude_doc_paths:
try:
validate_mask(exclude_doc_path)
except SyntaxError as exception:
print( # noqa: T201
f"error: strictdoc.toml: 'exclude_doc_paths': "
f"{exception} Provided string: '{exclude_doc_path}'."
)
sys.exit(1)

include_source_paths = project_content.get(
"include_source_paths", include_source_paths
)
assert isinstance(include_source_paths, list)
for include_source_path in include_source_paths:
try:
validate_mask(include_source_path)
except SyntaxError as exception:
print( # noqa: T201
f"error: strictdoc.toml: 'include_source_paths': "
f"{exception} Provided string: '{include_source_path}'."
)
sys.exit(1)

exclude_source_paths = project_content.get(
"exclude_source_paths", exclude_source_paths
)
assert isinstance(exclude_source_paths, list)
for exclude_source_path in exclude_source_paths:
try:
validate_mask(exclude_source_path)
except SyntaxError as exception:
print( # noqa: T201
f"error: strictdoc.toml: 'exclude_source_paths': "
f"{exception} Provided string: '{exclude_source_path}'."
)
sys.exit(1)

if "server" in config_dict:
# FIXME: Introduce at least a basic validation for the host/port.
Expand Down
35 changes: 25 additions & 10 deletions strictdoc/helpers/path_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,33 @@
rf"(\\|\/)?({REGEX_NAME_PART})?((\\|\/){REGEX_NAME_PART})*(\\|\/)?"
)

REGEX_MASK_VALIDATION = rf"[^(\\|\/)]{REGEX_DOUBLE_WILDCARD}"

MOST_COMMON_CHARACTERS = ("[", "]", "(", ")", "{", "}", "?", "+", "!")


def validate_mask(mask: str):
assert not mask.startswith("/")
assert "***" not in mask
assert "//" not in mask
assert "\\" not in mask
assert "?" not in mask
assert "[" not in mask
assert "]" not in mask
assert "(" not in mask
assert ")" not in mask
assert "+" not in mask
if mask == "":
raise SyntaxError("Path mask must not be empty.")

if not mask[0].isalnum() and mask[0] != "*":
raise SyntaxError(
"Path mask must start with an alphanumeric character or "
"a wildcard symbol '*'."
)

if "//" in mask or "\\\\" in mask:
raise SyntaxError("Path mask must not contain double slashes.")

if "***" in mask:
raise SyntaxError("Invalid wildcard: '***'.")

for regex_symbol in MOST_COMMON_CHARACTERS:
if regex_symbol in mask:
raise SyntaxError(
f"Path mask must not contain any of the special characters: "
f"{MOST_COMMON_CHARACTERS}."
)


def compile_regex_mask(path_mask: str) -> str:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[DOCUMENT]
TITLE: Document 1

[FREETEXT]
**Hello world**
[/FREETEXT]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]

include_doc_paths = [
" "
]

features = []
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RUN: %expect_exit 1 %strictdoc export %S --output-dir Output/ | filecheck %s --dump-input=fail

CHECK: error: strictdoc.toml: 'include_doc_paths': Path mask must start with an alphanumeric character or a wildcard symbol '*'. Provided string: ' '.
43 changes: 43 additions & 0 deletions tests/unit/strictdoc/helpers/test_path_filter_mask_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pytest

from strictdoc.helpers.path_filter import validate_mask


def test_case_01_empty_mask_allows_everything():
# Does not raise is success.
validate_mask("docs/")
validate_mask("Docs/")

with pytest.raises(SyntaxError) as exc_info:
validate_mask("")
assert "Path mask must not be empty." in exc_info.value.args[0]

with pytest.raises(SyntaxError) as exc_info:
validate_mask(".")
assert (
"Path mask must start with an alphanumeric character or "
"a wildcard symbol '*'."
) in exc_info.value.args[0]

with pytest.raises(SyntaxError) as exc_info:
validate_mask("foo//")
assert (
"Path mask must not contain double slashes." in exc_info.value.args[0]
)

with pytest.raises(SyntaxError) as exc_info:
validate_mask("bar\\\\")
assert (
"Path mask must not contain double slashes." in exc_info.value.args[0]
)

with pytest.raises(SyntaxError) as exc_info:
validate_mask("***")
assert "Invalid wildcard: '***'." in exc_info.value.args[0]

with pytest.raises(SyntaxError) as exc_info:
validate_mask("a[")
assert (
"Path mask must not contain any of the special characters: "
"('[', ']', '(', ')', '{', '}', '?', '+', '!')."
) in exc_info.value.args[0]

0 comments on commit cdd46dd

Please sign in to comment.