Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark diff colors safe and escape raw diff input #1993

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from datetime import datetime
from typing import Optional

from markupsafe import Markup

from strictdoc import __version__
from strictdoc.core.project_config import ProjectConfig
from strictdoc.export.html.html_templates import JinjaEnvironment
Expand Down Expand Up @@ -58,31 +60,30 @@ def __init__(
self.strictdoc_version = __version__
self.error_message: Optional[str] = None

def render_screen(self, jinja_environment: JinjaEnvironment):
template = jinja_environment.environment.overlay(
autoescape=False
).get_template("screens/git/index.jinja")
return template.render(view_object=self)
def render_screen(self, jinja_environment: JinjaEnvironment) -> Markup:
return jinja_environment.render_template_as_markup(
"screens/git/index.jinja", view_object=self
)

def render_url(self, url: str):
return self.link_renderer.render_url(url)
def render_url(self, url: str) -> Markup:
return Markup(self.link_renderer.render_url(url))

def render_node_link(self, incoming_link, document, document_type):
def render_node_link(self, incoming_link, document, document_type) -> str:
return self.link_renderer.render_node_link(
incoming_link, document, document_type
)

def render_static_url(self, url: str):
return self.link_renderer.render_static_url(url)
def render_static_url(self, url: str) -> Markup:
return Markup(self.link_renderer.render_static_url(url))

def render_static_url_with_prefix(self, url: str) -> str:
return self.link_renderer.render_static_url_with_prefix(url)

def render_local_anchor(self, node):
def render_local_anchor(self, node) -> str:
return self.link_renderer.render_local_anchor(node)

def is_empty_tree(self) -> bool:
return self.document_tree_iterator.is_empty_tree()

def date_today(self):
def date_today(self) -> str:
return datetime.today().strftime("%Y-%m-%d")
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from dataclasses import dataclass
from datetime import datetime

from markupsafe import Markup

from strictdoc import __version__
from strictdoc.core.project_config import ProjectConfig
from strictdoc.export.html.html_templates import JinjaEnvironment
Expand Down Expand Up @@ -39,27 +41,27 @@ def __init__(
self.is_running_on_server: bool = project_config.is_running_on_server
self.strictdoc_version = __version__

def render_screen(self, jinja_environment: JinjaEnvironment):
def render_screen(self, jinja_environment: JinjaEnvironment) -> Markup:
return jinja_environment.render_template_as_markup(
"screens/git/index.jinja", view_object=self
)

def render_url(self, url: str):
return self.link_renderer.render_url(url)
def render_url(self, url: str) -> Markup:
return Markup(self.link_renderer.render_url(url))

def render_node_link(self, incoming_link, document, document_type):
def render_node_link(self, incoming_link, document, document_type) -> str:
stanislaw marked this conversation as resolved.
Show resolved Hide resolved
return self.link_renderer.render_node_link(
incoming_link, document, document_type
)

def render_static_url(self, url: str):
return self.link_renderer.render_static_url(url)
def render_static_url(self, url: str) -> Markup:
return Markup(self.link_renderer.render_static_url(url))

def render_static_url_with_prefix(self, url: str) -> str:
return self.link_renderer.render_static_url_with_prefix(url)

def render_local_anchor(self, node):
def render_local_anchor(self, node) -> str:
return self.link_renderer.render_local_anchor(node)

def date_today(self):
def date_today(self) -> str:
return datetime.today().strftime("%Y-%m-%d")
32 changes: 17 additions & 15 deletions strictdoc/git/change.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from enum import Enum
from typing import Dict, List, Optional, Union

from markupsafe import Markup

from strictdoc.backend.sdoc.models.document import SDocDocument
from strictdoc.backend.sdoc.models.node import (
SDocNode,
Expand Down Expand Up @@ -36,24 +38,24 @@ def __init__(
rhs_document: Optional[SDocDocument],
uid_modified: bool,
title_modified: bool,
lhs_colored_title_diff: Optional[str],
rhs_colored_title_diff: Optional[str],
lhs_colored_title_diff: Optional[Markup],
rhs_colored_title_diff: Optional[Markup],
):
assert lhs_document is not None or rhs_document is not None
if matched_uid is not None:
assert len(matched_uid) > 0
self.matched_uid: Optional[str] = matched_uid
self.uid_modified: bool = uid_modified
self.title_modified: bool = title_modified
self.lhs_colored_title_diff: Optional[str] = lhs_colored_title_diff
self.rhs_colored_title_diff: Optional[str] = rhs_colored_title_diff
self.lhs_colored_title_diff: Optional[Markup] = lhs_colored_title_diff
self.rhs_colored_title_diff: Optional[Markup] = rhs_colored_title_diff

self.lhs_document: Optional[SDocDocument] = lhs_document
self.rhs_document: Optional[SDocDocument] = rhs_document

self.change_type: ChangeType = ChangeType.DOCUMENT_MODIFIED

def get_colored_title_diff(self, side: str) -> Optional[str]:
def get_colored_title_diff(self, side: str) -> Optional[Markup]:
assert self.title_modified
if side == "left":
return self.lhs_colored_title_diff
Expand All @@ -74,8 +76,8 @@ def __init__(
rhs_section: Optional[SDocSection],
uid_modified: bool,
title_modified: bool,
lhs_colored_title_diff: Optional[str],
rhs_colored_title_diff: Optional[str],
lhs_colored_title_diff: Optional[Markup],
rhs_colored_title_diff: Optional[Markup],
):
assert lhs_section is not None or rhs_section is not None
if matched_uid is not None:
Expand All @@ -85,8 +87,8 @@ def __init__(
self.section_token: Optional[str] = section_token
self.uid_modified: bool = uid_modified
self.title_modified: bool = title_modified
self.lhs_colored_title_diff: Optional[str] = lhs_colored_title_diff
self.rhs_colored_title_diff: Optional[str] = rhs_colored_title_diff
self.lhs_colored_title_diff: Optional[Markup] = lhs_colored_title_diff
self.rhs_colored_title_diff: Optional[Markup] = rhs_colored_title_diff

self.lhs_section: Optional[SDocSection] = lhs_section
self.rhs_section: Optional[SDocSection] = rhs_section
Expand All @@ -108,7 +110,7 @@ def __init__(
def is_paired_change(self) -> bool:
return self.lhs_section is not None and self.rhs_section is not None

def get_colored_title_diff(self, side: str) -> Optional[str]:
def get_colored_title_diff(self, side: str) -> Optional[Markup]:
assert self.title_modified
if side == "left":
return self.lhs_colored_title_diff
Expand All @@ -125,8 +127,8 @@ def __init__(
field_name: str,
lhs_field: Optional[SDocNodeField],
rhs_field: Optional[SDocNodeField],
left_diff: Optional[str],
right_diff: Optional[str],
left_diff: Optional[Markup],
right_diff: Optional[Markup],
):
assert isinstance(field_name, str) and len(field_name) > 0
assert lhs_field is not None or rhs_field is not None
Expand All @@ -137,10 +139,10 @@ def __init__(
self.field_name: str = field_name
self.lhs_field: Optional[SDocNodeField] = lhs_field
self.rhs_field: Optional[SDocNodeField] = rhs_field
self.left_diff: Optional[str] = left_diff
self.right_diff: Optional[str] = right_diff
self.left_diff: Optional[Markup] = left_diff
self.right_diff: Optional[Markup] = right_diff

def get_colored_free_text_diff(self, side: str) -> Optional[str]:
def get_colored_free_text_diff(self, side: str) -> Optional[Markup]:
if side == "left":
return self.left_diff
if side == "right":
Expand Down
28 changes: 15 additions & 13 deletions strictdoc/git/project_diff_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional, Set, Tuple, Union

from markupsafe import Markup

from strictdoc.backend.sdoc.models.document import SDocDocument
from strictdoc.backend.sdoc.models.node import (
SDocNode,
Expand All @@ -24,7 +26,7 @@
SectionChange,
)
from strictdoc.helpers.cast import assert_cast, assert_optional_cast
from strictdoc.helpers.diff import get_colored_diff_string, similar
from strictdoc.helpers.diff import get_colored_html_diff_string, similar
from strictdoc.helpers.mid import MID


Expand Down Expand Up @@ -347,8 +349,8 @@ def _iterate_one_index(

uid_modified: bool = False
title_modified: bool = False
lhs_colored_title_diff: Optional[str] = None
rhs_colored_title_diff: Optional[str] = None
lhs_colored_title_diff: Optional[Markup] = None
rhs_colored_title_diff: Optional[Markup] = None

# If there is another section and the UIDs are not the
# same, consider the UID modified.
Expand All @@ -366,12 +368,12 @@ def _iterate_one_index(
if other_document_or_none is not None:
if document.title != other_document_or_none.title:
title_modified = True
lhs_colored_title_diff = get_colored_diff_string(
lhs_colored_title_diff = get_colored_html_diff_string(
document.title,
other_document_or_none.title,
"left",
)
rhs_colored_title_diff = get_colored_diff_string(
rhs_colored_title_diff = get_colored_html_diff_string(
document.title,
other_document_or_none.title,
"right",
Expand Down Expand Up @@ -461,8 +463,8 @@ def _iterate_one_index(

uid_modified: bool = False
title_modified: bool = False
lhs_colored_title_diff: Optional[str] = None
rhs_colored_title_diff: Optional[str] = None
lhs_colored_title_diff: Optional[Markup] = None
rhs_colored_title_diff: Optional[Markup] = None

# If there is another section and the UIDs are not the
# same, consider the UID modified.
Expand All @@ -481,14 +483,14 @@ def _iterate_one_index(
if node.title != other_section_or_none.title:
title_modified = True
lhs_colored_title_diff = (
get_colored_diff_string(
get_colored_html_diff_string(
haxtibal marked this conversation as resolved.
Show resolved Hide resolved
node.title,
other_section_or_none.title,
"left",
)
)
rhs_colored_title_diff = (
get_colored_diff_string(
get_colored_html_diff_string(
node.title,
other_section_or_none.title,
"right",
Expand Down Expand Up @@ -769,10 +771,10 @@ def create_field_change(
other_requirement_field_value = (
other_requirement_field.get_text_value()
)
left_diff = get_colored_diff_string(
left_diff = get_colored_html_diff_string(
requirement_field_value, other_requirement_field_value, "left"
)
right_diff = get_colored_diff_string(
right_diff = get_colored_html_diff_string(
requirement_field_value, other_requirement_field_value, "right"
)

Expand Down Expand Up @@ -857,12 +859,12 @@ def create_comment_field_changes(
comment_other_value = changed_other_field_.get_text_value()
assert comment_other_value is not None

left_diff = get_colored_diff_string(
left_diff = get_colored_html_diff_string(
comment_value,
comment_other_value,
"left",
)
right_diff = get_colored_diff_string(
right_diff = get_colored_html_diff_string(
comment_value,
comment_other_value,
"right",
Expand Down
12 changes: 7 additions & 5 deletions strictdoc/helpers/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@
import difflib
from difflib import SequenceMatcher

from markupsafe import Markup, escape


def similar(a, b):
return SequenceMatcher(None, a, b).ratio()


red = lambda text: f'<span class="lambda_red">{text}</span>'
green = lambda text: f'<span class="lambda_green">{text}</span>'
white = lambda text: f"<span>{text}</span>"
red = lambda text: f'<span class="lambda_red">{escape(text)}</span>'
green = lambda text: f'<span class="lambda_green">{escape(text)}</span>'
white = lambda text: f"<span>{escape(text)}</span>"


def get_colored_diff_string(old: str, new: str, flag: str):
def get_colored_html_diff_string(old: str, new: str, flag: str) -> Markup:
assert old is not None
assert new is not None
assert flag in ("left", "right")
Expand All @@ -33,4 +35,4 @@ def get_colored_diff_string(old: str, new: str, flag: str):
result += red(old[code[1] : code[2]])
else:
result += green(new[code[3] : code[4]])
return result
return Markup(result)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[DOCUMENT]
TITLE: Doc Title with special characters <>

[SECTION]
TITLE: To be removed section with special characters <>

[REQUIREMENT]
TITLE: To be removed title with special characters <>
STATEMENT: To be removed statement with special characters <>

[/SECTION]

[SECTION]
UID: SECT-1
TITLE: To be changed section with special characters <>

[REQUIREMENT]
UID: REQ-1
TITLE: To be changed title with special characters <>
STATEMENT: To be changed statement with special characters <>

[/SECTION]
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[DOCUMENT]
TITLE: Doc Title with more special characters <>&"'

[SECTION]
TITLE: Added section with more special characters <>&"'

[REQUIREMENT]
TITLE: Added title with more special characters <>&"'
STATEMENT: Added statement with more special characters <>&"'

[/SECTION]

[SECTION]
UID: SECT-1
TITLE: Changed section with more special characters <>&"'

[REQUIREMENT]
UID: REQ-1
TITLE: Changed title with more special characters <>&"'
STATEMENT: Changed statement with more special characters <>&"'

[/SECTION]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[project]
title = "Test Project"

features = [
"DIFF",
]
Loading
Loading