diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..786be571 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + commit-message: + prefix: ⬆️ + schedule: + interval: weekly + - package-ecosystem: pip + directory: / + commit-message: + prefix: ⬆️ + schedule: + interval: weekly diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index ef5780b3..c2b82d33 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -12,12 +12,12 @@ jobs: - uses: actions/checkout@v2 - name: Set up Python 3.8 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.8 - name: install pandoc - uses: r-lib/actions/setup-pandoc@v1 + uses: r-lib/actions/setup-pandoc@v2 with: pandoc-version: '2.6' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e46c0847..64a068e3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,10 +21,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up Python 3.8 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: '3.8' - - uses: pre-commit/action@v2.0.0 + - uses: pre-commit/action@v3.0.0 tests: @@ -36,7 +36,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -48,7 +48,7 @@ jobs: pytest tests/ --cov=markdown_it --cov-report=xml --cov-report=term-missing - name: Upload to Codecov if: matrix.python-version == '3.7' && github.repository == 'executablebooks/markdown-it-py' - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 with: name: markdown-it-py-pytests-py3.7 flags: pytests @@ -64,7 +64,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install markdown-it-py @@ -85,7 +85,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up Python 3.8 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: '3.8' @@ -98,7 +98,7 @@ jobs: run: tox -e py38-bench-core -- --benchmark-json bench-core.json - name: Upload data - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: bench-core path: bench-core.json @@ -114,7 +114,7 @@ jobs: - name: Checkout source uses: actions/checkout@v2 - name: Set up Python 3.8 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: '3.8' - name: install flit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b9b3f0c0..50e8132a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ exclude: > repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.4.0 hooks: - id: check-json - id: check-yaml @@ -24,23 +24,23 @@ repos: - id: trailing-whitespace - repo: https://github.com/pycqa/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 23.1.0 hooks: - id: black - - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.2 + - repo: https://github.com/PyCQA/flake8 + rev: 6.0.0 hooks: - id: flake8 - additional_dependencies: [flake8-bugbear==21.3.1] + additional_dependencies: [flake8-bugbear~=22.7] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.942 + rev: v1.0.1 hooks: - id: mypy - additional_dependencies: [attrs] + additional_dependencies: [mdurl] diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aa4a725..fa8dc6b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.2.0 - 2023-02-22 + +### What's Changed + +* ⬆️ UPGRADE: Allow linkify-it-py v2 by @hukkin in [#218](https://github.com/executablebooks/markdown-it-py/pull/218) +* 🐛 FIX: CVE-2023-26303 by @chrisjsewell in [#246](https://github.com/executablebooks/markdown-it-py/pull/246) +* 🐛 FIX: CLI crash on non-utf8 character by @chrisjsewell in [#247](https://github.com/executablebooks/markdown-it-py/pull/247) +* 📚 DOCS: Update the example by @redstoneleo in [#229](https://github.com/executablebooks/markdown-it-py/pull/229) +* 📚 DOCS: Add section about markdown renderer by @holamgadol in [#227](https://github.com/executablebooks/markdown-it-py/pull/227) +* 🔧 Create SECURITY.md by @chrisjsewell in [#248](https://github.com/executablebooks/markdown-it-py/pull/248) +* 🔧 MAINTAIN: Update mypy's additional dependencies by @hukkin in [#217](https://github.com/executablebooks/markdown-it-py/pull/217) +* Fix typo by @jwilk in [#230](https://github.com/executablebooks/markdown-it-py/pull/230) +* 🔧 Bump GH actions by @chrisjsewell in [#244](https://github.com/executablebooks/markdown-it-py/pull/244) +* 🔧 Update benchmark pkg versions by @chrisjsewell in [#245](https://github.com/executablebooks/markdown-it-py/pull/245) + +### New Contributors + +Thanks to 🎉 + +* @jwilk made their first contribution in [#230](https://github.com/executablebooks/markdown-it-py/pull/230) +* @holamgadol made their first contribution in [#227](https://github.com/executablebooks/markdown-it-py/pull/227) +* @redstoneleo made their first contribution in [#229](https://github.com/executablebooks/markdown-it-py/pull/229) + +**Full Changelog**: + ## 2.1.0 - 2022-04-15 This release is primarily to replace the `attrs` package dependency, diff --git a/README.md b/README.md index 599c1f9f..789588fe 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,9 @@ from mdit_py_plugins.front_matter import front_matter_plugin from mdit_py_plugins.footnote import footnote_plugin md = ( - MarkdownIt() + MarkdownIt('commonmark' ,{'breaks':True,'html':True}) .use(front_matter_plugin) .use(footnote_plugin) - .disable('image') .enable('table') ) text = (""" diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..aaa878f4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +We generally only support the latest major release, +although critical bug fixes can be released for older versions. + +## Reporting a Vulnerability + +To report a security issue, please email with a description of the issue, +the steps you took to create the issue, affected versions, and, if known, mitigations for the issue. +Our team will respond within 3 working days of your email. +If the issue is confirmed as a vulnerability, we will open a Security Advisory. +This project follows a 90 day disclosure timeline. diff --git a/docs/other.md b/docs/other.md index 4d77360f..cfc5ba8c 100644 --- a/docs/other.md +++ b/docs/other.md @@ -21,7 +21,7 @@ for XSS: So, by default `markdown-it` should be safe. We care about it. -If you find a security problem - contact us via tracker or email. +If you find a security problem - contact us via . Such reports are fixed with top priority. ## Plugins diff --git a/docs/using.md b/docs/using.md index 83872037..aa632574 100644 --- a/docs/using.md +++ b/docs/using.md @@ -330,7 +330,7 @@ md = MarkdownIt("commonmark", renderer_cls=MyRenderer) md.render("*a*") ``` -Plugins can support multiple render types, using the `__ouput__` attribute (this is currently a Python only feature). +Plugins can support multiple render types, using the `__output__` attribute (this is currently a Python only feature). ```{code-cell} python from markdown_it.renderer import RendererHTML @@ -397,3 +397,29 @@ md = MarkdownIt("commonmark") md.add_render_rule("link_open", render_blank_link) print(md.render("[a]\n\n[a]: b")) ``` + +### Markdown renderer + +You can also render a token stream directly to markdown via the `MDRenderer` class from [`mdformat`](https://github.com/executablebooks/mdformat): + +```{code-cell} python +from markdown_it import MarkdownIt +from mdformat.renderer import MDRenderer + +md = MarkdownIt("commonmark") + +source_markdown = """ +Here's some *text* + +1. a list + +> a *quote*""" + +tokens = md.parse(source_markdown) + +renderer = MDRenderer() +options = {} +env = {} + +output_markdown = renderer.render(tokens, options, env) +``` diff --git a/markdown_it/__init__.py b/markdown_it/__init__.py index 5cc232a5..882a0c3e 100644 --- a/markdown_it/__init__.py +++ b/markdown_it/__init__.py @@ -1,5 +1,5 @@ """A Python port of Markdown-It""" __all__ = ("MarkdownIt",) -__version__ = "2.1.0" +__version__ = "2.2.0" from .main import MarkdownIt diff --git a/markdown_it/cli/parse.py b/markdown_it/cli/parse.py index 2d74f55a..890d5de3 100644 --- a/markdown_it/cli/parse.py +++ b/markdown_it/cli/parse.py @@ -35,7 +35,7 @@ def convert_file(filename: str) -> None: Parse a Markdown file and dump the output to stdout. """ try: - with open(filename, "r") as fin: + with open(filename, "r", encoding="utf8", errors="ignore") as fin: rendered = MarkdownIt().render(fin.read()) print(rendered, end="") except OSError: diff --git a/markdown_it/common/utils.py b/markdown_it/common/utils.py index edc24ca5..9b7c4aeb 100644 --- a/markdown_it/common/utils.py +++ b/markdown_it/common/utils.py @@ -56,7 +56,6 @@ def arrayReplaceAt(src: list, pos: int, newElements: list) -> list: def isValidEntityCode(c: int) -> bool: - # broken sequence if c >= 0xD800 and c <= 0xDFFF: return False diff --git a/markdown_it/helpers/parse_link_label.py b/markdown_it/helpers/parse_link_label.py index 20e3c148..6ce8daf8 100644 --- a/markdown_it/helpers/parse_link_label.py +++ b/markdown_it/helpers/parse_link_label.py @@ -9,7 +9,6 @@ def parseLinkLabel(state: StateInline, start: int, disableNested: bool = False) -> int: - labelEnd = -1 oldPos = state.pos found = False diff --git a/markdown_it/renderer.py b/markdown_it/renderer.py index b8bfe4da..81d0bc37 100644 --- a/markdown_it/renderer.py +++ b/markdown_it/renderer.py @@ -18,7 +18,7 @@ class Renderer try: from typing import Protocol except ImportError: # Python <3.8 doesn't have `Protocol` in the stdlib - from typing_extensions import Protocol # type: ignore[misc] + from typing_extensions import Protocol # type: ignore class RendererProtocol(Protocol): @@ -82,10 +82,9 @@ def render( result = "" for i, token in enumerate(tokens): - if token.type == "inline": - assert token.children is not None - result += self.renderInline(token.children, options, env) + if token.children: + result += self.renderInline(token.children, options, env) elif token.type in self.rules: result += self.rules[token.type](tokens, i, options, env) else: @@ -207,8 +206,8 @@ def renderInlineAsText( if token.type == "text": result += token.content elif token.type == "image": - assert token.children is not None - result += self.renderInlineAsText(token.children, options, env) + if token.children: + result += self.renderInlineAsText(token.children, options, env) elif token.type == "softbreak": result += "\n" @@ -306,14 +305,10 @@ def image( # "alt" attr MUST be set, even if empty. Because it's mandatory and # should be placed on proper position for tests. - - assert ( - token.attrs and "alt" in token.attrs - ), '"image" token\'s attrs must contain `alt`' - - # Replace content with actual value - - token.attrSet("alt", self.renderInlineAsText(token.children, options, env)) + if token.children: + token.attrSet("alt", self.renderInlineAsText(token.children, options, env)) + else: + token.attrSet("alt", "") return self.renderToken(tokens, idx, options, env) diff --git a/markdown_it/rules_block/blockquote.py b/markdown_it/rules_block/blockquote.py index 6575731d..e00fbf61 100644 --- a/markdown_it/rules_block/blockquote.py +++ b/markdown_it/rules_block/blockquote.py @@ -10,7 +10,6 @@ def blockquote(state: StateBlock, startLine: int, endLine: int, silent: bool): - LOGGER.debug( "entering blockquote: %s, %s, %s, %s", state, startLine, endLine, silent ) @@ -129,7 +128,6 @@ def blockquote(state: StateBlock, startLine: int, endLine: int, silent: bool): # for (nextLine = startLine + 1; nextLine < endLine; nextLine++) { nextLine = startLine + 1 while nextLine < endLine: - # check if it's outdented, i.e. it's inside list item and indented # less than said list item: # diff --git a/markdown_it/rules_block/code.py b/markdown_it/rules_block/code.py index c4fdba33..a796608d 100644 --- a/markdown_it/rules_block/code.py +++ b/markdown_it/rules_block/code.py @@ -7,7 +7,6 @@ def code(state: StateBlock, startLine: int, endLine: int, silent: bool = False): - LOGGER.debug("entering code: %s, %s, %s, %s", state, startLine, endLine, silent) if state.sCount[startLine] - state.blkIndent < 4: diff --git a/markdown_it/rules_block/fence.py b/markdown_it/rules_block/fence.py index c4f5275d..fb3c6847 100644 --- a/markdown_it/rules_block/fence.py +++ b/markdown_it/rules_block/fence.py @@ -7,7 +7,6 @@ def fence(state: StateBlock, startLine: int, endLine: int, silent: bool): - LOGGER.debug("entering fence: %s, %s, %s, %s", state, startLine, endLine, silent) haveEndMarker = False diff --git a/markdown_it/rules_block/heading.py b/markdown_it/rules_block/heading.py index 8d4ef3e2..064d0702 100644 --- a/markdown_it/rules_block/heading.py +++ b/markdown_it/rules_block/heading.py @@ -10,7 +10,6 @@ def heading(state: StateBlock, startLine: int, endLine: int, silent: bool): - LOGGER.debug("entering heading: %s, %s, %s, %s", state, startLine, endLine, silent) pos = state.bMarks[startLine] + state.tShift[startLine] diff --git a/markdown_it/rules_block/hr.py b/markdown_it/rules_block/hr.py index 804cd9db..22c69722 100644 --- a/markdown_it/rules_block/hr.py +++ b/markdown_it/rules_block/hr.py @@ -11,7 +11,6 @@ def hr(state: StateBlock, startLine: int, endLine: int, silent: bool): - LOGGER.debug("entering hr: %s, %s, %s, %s", state, startLine, endLine, silent) pos = state.bMarks[startLine] + state.tShift[startLine] diff --git a/markdown_it/rules_block/lheading.py b/markdown_it/rules_block/lheading.py index f26e2af0..92632acc 100644 --- a/markdown_it/rules_block/lheading.py +++ b/markdown_it/rules_block/lheading.py @@ -8,7 +8,6 @@ def lheading(state: StateBlock, startLine: int, endLine: int, silent: bool): - LOGGER.debug("entering lheading: %s, %s, %s, %s", state, startLine, endLine, silent) level = None diff --git a/markdown_it/rules_block/list.py b/markdown_it/rules_block/list.py index a7617ad2..9cf8c402 100644 --- a/markdown_it/rules_block/list.py +++ b/markdown_it/rules_block/list.py @@ -10,7 +10,6 @@ # Search `[-+*][\n ]`, returns next pos after marker on success # or -1 on fail. def skipBulletListMarker(state: StateBlock, startLine: int): - pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] @@ -33,7 +32,6 @@ def skipBulletListMarker(state: StateBlock, startLine: int): # Search `\d+[.)][\n ]`, returns next pos after marker on success # or -1 on fail. def skipOrderedListMarker(state: StateBlock, startLine: int): - start = state.bMarks[startLine] + state.tShift[startLine] pos = start maximum = state.eMarks[startLine] @@ -59,7 +57,6 @@ def skipOrderedListMarker(state: StateBlock, startLine: int): # /* 0 */ /* 9 */ if ch >= 0x30 and ch <= 0x39: - # List marker should have no more than 9 digits # (prevents integer overflow in browsers) if pos - start >= 10: @@ -97,7 +94,6 @@ def markTightParagraphs(state: StateBlock, idx: int): def list_block(state: StateBlock, startLine: int, endLine: int, silent: bool): - LOGGER.debug("entering list: %s, %s, %s, %s", state, startLine, endLine, silent) isTerminatingParagraph = False diff --git a/markdown_it/rules_block/paragraph.py b/markdown_it/rules_block/paragraph.py index 4fee83e9..fef7edf7 100644 --- a/markdown_it/rules_block/paragraph.py +++ b/markdown_it/rules_block/paragraph.py @@ -8,7 +8,6 @@ def paragraph(state: StateBlock, startLine: int, endLine: int, silent: bool = False): - LOGGER.debug( "entering paragraph: %s, %s, %s, %s", state, startLine, endLine, silent ) diff --git a/markdown_it/rules_block/reference.py b/markdown_it/rules_block/reference.py index 35adde2a..39e21eb6 100644 --- a/markdown_it/rules_block/reference.py +++ b/markdown_it/rules_block/reference.py @@ -7,7 +7,6 @@ def reference(state: StateBlock, startLine, _endLine, silent): - LOGGER.debug( "entering reference: %s, %s, %s, %s", state, startLine, _endLine, silent ) diff --git a/markdown_it/rules_block/state_block.py b/markdown_it/rules_block/state_block.py index 42b8fce3..c5589149 100644 --- a/markdown_it/rules_block/state_block.py +++ b/markdown_it/rules_block/state_block.py @@ -19,7 +19,6 @@ def __init__( tokens: list[Token], srcCharCode: tuple[int, ...] | None = None, ): - if srcCharCode is not None: self._src = src self.srcCharCode = srcCharCode diff --git a/markdown_it/rules_core/block.py b/markdown_it/rules_core/block.py index fa1c52c4..dc756418 100644 --- a/markdown_it/rules_core/block.py +++ b/markdown_it/rules_core/block.py @@ -3,7 +3,6 @@ def block(state: StateCore) -> None: - if state.inlineMode: token = Token("inline", "", 0) token.content = state.src diff --git a/markdown_it/rules_core/normalize.py b/markdown_it/rules_core/normalize.py index bf16fd7a..c9f8d0d5 100644 --- a/markdown_it/rules_core/normalize.py +++ b/markdown_it/rules_core/normalize.py @@ -9,7 +9,6 @@ def normalize(state: StateCore) -> None: - # Normalize newlines string = NEWLINES_RE.sub("\n", state.src) diff --git a/markdown_it/rules_core/replacements.py b/markdown_it/rules_core/replacements.py index 45377d3e..5e9b7ae7 100644 --- a/markdown_it/rules_core/replacements.py +++ b/markdown_it/rules_core/replacements.py @@ -116,7 +116,8 @@ def replace(state: StateCore) -> None: for token in state.tokens: if token.type != "inline": continue - assert token.children is not None + if token.children is None: + continue if SCOPED_ABBR_RE.search(token.content): replace_scoped(token.children) diff --git a/markdown_it/rules_core/smartquotes.py b/markdown_it/rules_core/smartquotes.py index 93f8be28..b11a5739 100644 --- a/markdown_it/rules_core/smartquotes.py +++ b/markdown_it/rules_core/smartquotes.py @@ -195,8 +195,7 @@ def smartquotes(state: StateCore) -> None: return for token in state.tokens: - if token.type != "inline" or not QUOTE_RE.search(token.content): continue - assert token.children is not None - process_inlines(token.children, state) + if token.children is not None: + process_inlines(token.children, state) diff --git a/markdown_it/rules_inline/autolink.py b/markdown_it/rules_inline/autolink.py index a4ee61c3..11ac5905 100644 --- a/markdown_it/rules_inline/autolink.py +++ b/markdown_it/rules_inline/autolink.py @@ -10,7 +10,6 @@ def autolink(state: StateInline, silent: bool) -> bool: - pos = state.pos if state.srcCharCode[pos] != 0x3C: # /* < */ diff --git a/markdown_it/rules_inline/backticks.py b/markdown_it/rules_inline/backticks.py index 7bff12fe..5f1e0552 100644 --- a/markdown_it/rules_inline/backticks.py +++ b/markdown_it/rules_inline/backticks.py @@ -7,7 +7,6 @@ def backtick(state: StateInline, silent: bool) -> bool: - pos = state.pos ch = state.srcCharCode[pos] diff --git a/markdown_it/rules_inline/balance_pairs.py b/markdown_it/rules_inline/balance_pairs.py index db622f07..5423b5d6 100644 --- a/markdown_it/rules_inline/balance_pairs.py +++ b/markdown_it/rules_inline/balance_pairs.py @@ -4,7 +4,6 @@ def processDelimiters(state: StateInline, delimiters, *args): - openersBottom = {} maximum = len(delimiters) @@ -50,7 +49,6 @@ def processDelimiters(state: StateInline, delimiters, *args): continue if opener.open and opener.end < 0: - isOddMatch = False # from spec: diff --git a/markdown_it/rules_inline/emphasis.py b/markdown_it/rules_inline/emphasis.py index 9001b09e..5262430b 100644 --- a/markdown_it/rules_inline/emphasis.py +++ b/markdown_it/rules_inline/emphasis.py @@ -39,7 +39,6 @@ def tokenize(state: StateInline, silent: bool): def _postProcess(state, delimiters): - i = len(delimiters) - 1 while i >= 0: startDelim = delimiters[i] diff --git a/markdown_it/rules_inline/entity.py b/markdown_it/rules_inline/entity.py index 883a9666..08d271ed 100644 --- a/markdown_it/rules_inline/entity.py +++ b/markdown_it/rules_inline/entity.py @@ -10,7 +10,6 @@ def entity(state: StateInline, silent: bool): - pos = state.pos maximum = state.posMax diff --git a/markdown_it/rules_inline/html_inline.py b/markdown_it/rules_inline/html_inline.py index 295cc5c7..b875e884 100644 --- a/markdown_it/rules_inline/html_inline.py +++ b/markdown_it/rules_inline/html_inline.py @@ -10,7 +10,6 @@ def isLetter(ch: int): def html_inline(state: StateInline, silent: bool): - pos = state.pos if not state.md.options.get("html", None): diff --git a/markdown_it/rules_inline/image.py b/markdown_it/rules_inline/image.py index d2a08d47..d7215bdf 100644 --- a/markdown_it/rules_inline/image.py +++ b/markdown_it/rules_inline/image.py @@ -7,7 +7,6 @@ def image(state: StateInline, silent: bool): - label = None href = "" oldPos = state.pos diff --git a/markdown_it/rules_inline/link.py b/markdown_it/rules_inline/link.py index 2394d6c3..a6345152 100644 --- a/markdown_it/rules_inline/link.py +++ b/markdown_it/rules_inline/link.py @@ -5,7 +5,6 @@ def link(state: StateInline, silent: bool): - href = "" title = "" label = None diff --git a/markdown_it/rules_inline/strikethrough.py b/markdown_it/rules_inline/strikethrough.py index 107ea26b..9b062a66 100644 --- a/markdown_it/rules_inline/strikethrough.py +++ b/markdown_it/rules_inline/strikethrough.py @@ -53,7 +53,6 @@ def tokenize(state: StateInline, silent: bool): def _postProcess(state: StateInline, delimiters: list[Delimiter]): - loneMarkers = [] maximum = len(delimiters) @@ -89,7 +88,6 @@ def _postProcess(state: StateInline, delimiters: list[Delimiter]): state.tokens[endDelim.token - 1].type == "text" and state.tokens[endDelim.token - 1].content == "~" ): - loneMarkers.append(endDelim.token - 1) i += 1 diff --git a/markdown_it/token.py b/markdown_it/token.py index b20875b6..7a41a784 100644 --- a/markdown_it/token.py +++ b/markdown_it/token.py @@ -22,7 +22,6 @@ def convert_attrs(value: Any) -> Any: @dc.dataclass(**DATACLASS_KWARGS) class Token: - type: str """Type of the token (string, e.g. "paragraph_open")""" diff --git a/pyproject.toml b/pyproject.toml index e0017185..5ac1ad27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,15 +35,15 @@ Homepage = "https://github.com/executablebooks/markdown-it-py" Documentation = "https://markdown-it-py.readthedocs.io" [project.optional-dependencies] -code_style = ["pre-commit==2.6"] +code_style = ["pre-commit~=3.0"] compare = [ - "commonmark~=0.9.1", - "markdown~=3.3.6", - "mistletoe~=0.8.1", - "mistune~=2.0.2", - "panflute~=2.1.3", + "commonmark~=0.9", + "markdown~=3.4", + "mistletoe~=1.0", + "mistune~=2.0", + "panflute~=2.3", ] -linkify = ["linkify-it-py~=1.0"] +linkify = ["linkify-it-py>=1,<3"] plugins = ["mdit-py-plugins"] rtd = [ "attrs", @@ -63,7 +63,7 @@ testing = [ benchmarking = [ "psutil", "pytest", - "pytest-benchmark~=3.2", + "pytest-benchmark", ] profiling = ["gprof2dot"] diff --git a/tests/test_cli.py b/tests/test_cli.py index 57d6b938..c38e24fd 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -20,6 +20,13 @@ def test_parse_fail(): assert exc_info.value.code == 1 +def test_non_utf8(): + with tempfile.TemporaryDirectory() as tempdir: + path = pathlib.Path(tempdir).joinpath("test.md") + path.write_bytes(b"\x80abc") + assert parse.main([str(path)]) == 0 + + def test_print_heading(): with patch("builtins.print") as patched: parse.print_heading() diff --git a/tests/test_port/fixtures/issue-fixes.md b/tests/test_port/fixtures/issue-fixes.md index 0c693b04..319945af 100644 --- a/tests/test_port/fixtures/issue-fixes.md +++ b/tests/test_port/fixtures/issue-fixes.md @@ -36,3 +36,12 @@ .

💬

. + +Fix CVE-2023-26303 +. +![![]() +]([) +. +


+

+. diff --git a/tests/test_port/test_fixtures.py b/tests/test_port/test_fixtures.py index 5117c5e1..d2199caf 100644 --- a/tests/test_port/test_fixtures.py +++ b/tests/test_port/test_fixtures.py @@ -111,4 +111,5 @@ def test_strikethrough(line, title, input, expected): def test_issue_fixes(line, title, input, expected): md = MarkdownIt() text = md.render(input) + print(text) assert text.rstrip() == expected.rstrip() diff --git a/tests/test_port/test_references.py b/tests/test_port/test_references.py index 32e389de..75bf7130 100644 --- a/tests/test_port/test_references.py +++ b/tests/test_port/test_references.py @@ -2,7 +2,6 @@ def test_ref_definitions(): - md = MarkdownIt() src = "[a]: abc\n\n[b]: xyz\n\n[b]: ijk" env = {}