Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Markdown for openSUSE:Factory
checked in at 2026-02-11 18:47:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Markdown (Old)
and /work/SRC/openSUSE:Factory/.python-Markdown.new.1670 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Markdown"
Wed Feb 11 18:47:35 2026 rev:60 rq:1332278 version:3.10.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Markdown/python-Markdown.changes
2026-01-27 16:06:58.444653917 +0100
+++
/work/SRC/openSUSE:Factory/.python-Markdown.new.1670/python-Markdown.changes
2026-02-11 18:48:03.607393387 +0100
@@ -1,0 +2,7 @@
+Mon Feb 9 19:12:02 UTC 2026 - BenoƮt Monin <[email protected]>
+
+- update to version 3.10.2:
+ * Fix a regression related to comment handling (#1590).
+ * More reliable fix for </ (#1593).
+
+-------------------------------------------------------------------
Old:
----
markdown-3.10.1.tar.gz
New:
----
markdown-3.10.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Markdown.spec ++++++
--- /var/tmp/diff_new_pack.MLzgOD/_old 2026-02-11 18:48:04.547432863 +0100
+++ /var/tmp/diff_new_pack.MLzgOD/_new 2026-02-11 18:48:04.551433031 +0100
@@ -32,7 +32,7 @@
%endif
%{?sle15_python_module_pythons}
Name: python-Markdown%{psuffix}
-Version: 3.10.1
+Version: 3.10.2
Release: 0
Summary: Python implementation of Markdown
License: BSD-3-Clause
++++++ markdown-3.10.1.tar.gz -> markdown-3.10.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/Markdown.egg-info/PKG-INFO
new/markdown-3.10.2/Markdown.egg-info/PKG-INFO
--- old/markdown-3.10.1/Markdown.egg-info/PKG-INFO 2026-01-21
19:09:17.000000000 +0100
+++ new/markdown-3.10.2/Markdown.egg-info/PKG-INFO 2026-02-09
15:57:16.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: Markdown
-Version: 3.10.1
+Version: 3.10.2
Summary: Python implementation of John Gruber's Markdown.
Author: Manfred Stienstra, Yuri Takhteyev
Author-email: Waylan limberg <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/Markdown.egg-info/SOURCES.txt
new/markdown-3.10.2/Markdown.egg-info/SOURCES.txt
--- old/markdown-3.10.1/Markdown.egg-info/SOURCES.txt 2026-01-21
19:09:17.000000000 +0100
+++ new/markdown-3.10.2/Markdown.egg-info/SOURCES.txt 2026-02-09
15:57:16.000000000 +0100
@@ -23,6 +23,7 @@
docs/mkdocstrings.css
docs/py.png
docs/reference.md
+docs/sanitization.md
docs/test_tools.md
docs/change_log/index.md
docs/change_log/release-2.0.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/PKG-INFO new/markdown-3.10.2/PKG-INFO
--- old/markdown-3.10.1/PKG-INFO 2026-01-21 19:09:17.219820000 +0100
+++ new/markdown-3.10.2/PKG-INFO 2026-02-09 15:57:16.674457600 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: Markdown
-Version: 3.10.1
+Version: 3.10.2
Summary: Python implementation of John Gruber's Markdown.
Author: Manfred Stienstra, Yuri Takhteyev
Author-email: Waylan limberg <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/docs/changelog.md
new/markdown-3.10.2/docs/changelog.md
--- old/markdown-3.10.1/docs/changelog.md 2026-01-21 19:09:10.000000000
+0100
+++ new/markdown-3.10.2/docs/changelog.md 2026-02-09 15:57:10.000000000
+0100
@@ -10,6 +10,13 @@
[Python Version
Specification](https://packaging.python.org/en/latest/specifications/version-specifiers/).
See the [Contributing Guide](contributing.md) for details.
+## [3.10.2] - 2026-02-09
+
+### Fixed
+
+* Fix a regression related to comment handling (#1590).
+* More reliable fix for `</` (#1593).
+
## [3.10.1] - 2026-01-21
### Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/docs/cli.md
new/markdown-3.10.2/docs/cli.md
--- old/markdown-3.10.1/docs/cli.md 2026-01-21 19:09:10.000000000 +0100
+++ new/markdown-3.10.2/docs/cli.md 2026-02-09 15:57:10.000000000 +0100
@@ -12,6 +12,8 @@
system to run the command line script. See the
[Installation instructions](install.md) for details.
+## Basic Usage
+
Python-Markdown's command line script takes advantage of Python's `-m` flag.
Therefore, assuming the python executable is on your system path, use the
following format:
@@ -28,92 +30,62 @@
python -m markdown input_file.txt
```
-Piping input and output (on `STDIN` and `STDOUT`) is fully supported as well.
-For example:
-
-```bash
-echo "Some **Markdown** text." | python -m markdown > output.html
-```
-
-Use the `--help` option for a list all available options and arguments:
+Use the `--help` option for a list of all available options and arguments:
```bash
python -m markdown --help
```
-If you don't want to call the python executable directly (using the `-m` flag),
-follow the instructions below to use a wrapper script:
-
-Setup
------
-
-Upon installation, the `markdown_py` script will have been copied to
-your Python "Scripts" directory. Different systems require different methods to
-ensure that any files in the Python "Scripts" directory are on your system
-path.
-
-* **Windows**:
-
- Assuming a default install of Python on Windows, your "Scripts" directory
- is most likely something like `C:\\Python37\Scripts`. Verify the location
- of your "Scripts" directory and add it to you system path.
+!!! warning
- Calling `markdown_py` from the command line will call the wrapper batch
- file `markdown_py.bat` in the `"Scripts"` directory created during install.
-
-* __*nix__ (Linux, OSX, BSD, Unix, etc.):
+ The Python-Markdown library does ***not*** sanitize its HTML output. If
+ you are processing Markdown input from an untrusted source, it is your
+ responsibility to ensure that it is properly sanitized. For more
+ information see [Sanitizing HTML Output](sanitization.md).
- As each \*nix distribution is different and we can't possibly document all
- of them here, we'll provide a few helpful pointers:
-
- * Some systems will automatically install the script on your path. Try it
- and see if it works. Just run `markdown_py` from the command line.
-
- * Other systems may maintain a separate "Scripts" ("bin") directory which
- you need to add to your path. Find it (check with your distribution) and
- either add it to your path or make a symbolic link to it from your path.
+## Piping Input and Output
- * If you are sure `markdown_py` is on your path, but it still is not being
- found, check the permissions of the file and make sure it is executable.
-
- As an alternative, you could just `cd` into the directory which contains
- the source distribution, and run it from there. However, remember that your
- markdown text files will not likely be in that directory, so it is much
- more convenient to have `markdown_py` on your path.
-
-!!!Note
- Python-Markdown uses `"markdown_py"` as a script name because the Perl
- implementation has already taken the more obvious name "markdown".
- Additionally, the default Python configuration on some systems would cause
a
- script named `"markdown.py"` to fail by importing itself rather than the
- markdown library. Therefore, the script has been named `"markdown_py"` as a
- compromise. If you prefer a different name for the script on your system,
it
- is suggested that you create a symbolic link to `markdown_py` with your
- preferred name.
-
-Usage
------
-
-To use `markdown_py` from the command line, run it as
+Piping input and output (on `STDIN` and `STDOUT`) is fully supported.
+For example:
```bash
-markdown_py input_file.txt
+echo "Some **Markdown** text." | python -m markdown > output.html
```
-or
+The above command would generate a file named `output.html` with the following
content:
+```html
+<p>Some <strong>Markdown</strong> Text.</p>
+```
+
+As Python-Markdown only ever outputs HTML fragments (no `<html>`, `<head>`,
+and `<body>` tags), it is generally expected that the command line interface
+will always be used to pipe output to a templating engine. In the event that
+no additional content is needed and the output only needs to be wrapped in
+otherwise empty `<html>`, `<head>`, and `<body>` tags,
+[JustHTML](https://emilstenstrom.github.io/justhtml/) can do that with with
+a single command:
```bash
-markdown_py input_file.txt > output_file.html
+echo "Some **Markdown** text." | python -m markdown | justhtml - --fragment >
output.html
```
-For a complete list of options, run
+The above command would generate a file named `output.html` with the following
content:
-```bash
-markdown_py --help
+```html
+<html>
+ <head></head>
+ <body>
+ <p>Some <strong>Markdown</strong> Text.</p>
+ </body>
+</html>
```
-Using Extensions
-----------------
+If you don't need or want JustHTML's HTML sanitation, you can disable it with
the
+`--unsafe` flag, although that is not recommended. See JustHTML's
+[Command Line Interface](https://emilstenstrom.github.io/justhtml/cli.html)
+documentation for details.
+
+## Using Extensions
To load a Python-Markdown extension from the command line use the `-x`
(or `--extension`) option. The extension module must be on your `PYTHONPATH`
@@ -187,3 +159,74 @@
[JSON]: https://json.org/
[PyYAML]: https://pyyaml.org/
[2.5 release notes]: change_log/release-2.5.md
+
+## Using the `markdown_py` Command
+
+If you don't want to call the python executable directly (using the `-m` flag),
+follow the instructions below to use a wrapper script:
+
+### Setup `markdown_py`
+
+Upon installation, the `markdown_py` script will have been copied to
+your Python "Scripts" directory. Different systems require different methods to
+ensure that any files in the Python "Scripts" directory are on your system
+path.
+
+* **Windows**:
+
+ Assuming a default install of Python on Windows, your "Scripts" directory
+ is most likely something like `C:\\Python37\Scripts`. Verify the location
+ of your "Scripts" directory and add it to you system path.
+
+ Calling `markdown_py` from the command line will call the wrapper batch
+ file `markdown_py.bat` in the `"Scripts"` directory created during install.
+
+* __*nix__ (Linux, OSX, BSD, Unix, etc.):
+
+ As each \*nix distribution is different and we can't possibly document all
+ of them here, we'll provide a few helpful pointers:
+
+ * Some systems will automatically install the script on your path. Try it
+ and see if it works. Just run `markdown_py` from the command line.
+
+ * Other systems may maintain a separate "Scripts" ("bin") directory which
+ you need to add to your path. Find it (check with your distribution) and
+ either add it to your path or make a symbolic link to it from your path.
+
+ * If you are sure `markdown_py` is on your path, but it still is not being
+ found, check the permissions of the file and make sure it is executable.
+
+ As an alternative, you could just `cd` into the directory which contains
+ the source distribution, and run it from there. However, remember that your
+ markdown text files will not likely be in that directory, so it is much
+ more convenient to have `markdown_py` on your path.
+
+!!!Note
+ Python-Markdown uses `"markdown_py"` as a script name because the Perl
+ implementation has already taken the more obvious name "markdown".
+ Additionally, the default Python configuration on some systems would cause
a
+ script named `"markdown.py"` to fail by importing itself rather than the
+ markdown library. Therefore, the script has been named `"markdown_py"` as a
+ compromise. If you prefer a different name for the script on your system,
it
+ is suggested that you create a symbolic link to `markdown_py` with your
+ preferred name.
+
+### Using `markdown_py`
+
+To use `markdown_py` from the command line, run it as
+
+```bash
+markdown_py input_file.txt
+```
+
+or
+
+```bash
+markdown_py input_file.txt > output_file.html
+```
+
+For a complete list of options, run
+
+```bash
+markdown_py --help
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/docs/reference.md
new/markdown-3.10.2/docs/reference.md
--- old/markdown-3.10.1/docs/reference.md 2026-01-21 19:09:10.000000000
+0100
+++ new/markdown-3.10.2/docs/reference.md 2026-02-09 15:57:10.000000000
+0100
@@ -25,7 +25,16 @@
it. If you do use a single instance though, make sure to call the `reset`
method appropriately ([see below](#convert)).
-### markdown.markdown(text [, **kwargs]) {: #markdown
data-toc-label='markdown.markdown' }
+### `markdown.markdown(text [, **kwargs])` {: #markdown
data-toc-label='markdown.markdown' }
+
+!!! warning
+
+ The Python-Markdown library does ***not*** sanitize its HTML output. If
+ you are processing Markdown input from an untrusted source, it is your
+ responsibility to ensure that it is properly sanitized. For more
+ information see [Sanitizing HTML Output].
+
+[Sanitizing HTML Output]: sanitization.md
The following options are available on the `markdown.markdown` function:
@@ -179,6 +188,15 @@
### `markdown.markdownFromFile (**kwargs)` {: #markdownFromFile
data-toc-label='markdown.markdownFromFile' }
+!!! warning
+
+ The Python-Markdown library does ***not*** sanitize its HTML output. As
+ `markdown.markdownFromFile` writes directly to the file system, there is
+ no easy way to sanitize the output from Python code. Therefore, it is
+ recommended that the `markdown.markdownFromFile` function not be used on
+ input from an untrusted source. For more information see [Sanitizing HTML
+ Output].
+
With a few exceptions, `markdown.markdownFromFile` accepts the same options as
`markdown.markdown`. It does **not** accept a `text` (or Unicode) string.
Instead, it accepts the following required options:
@@ -216,7 +234,7 @@
meet your specific needs, it is suggested that you write your own code
to handle your encoding/decoding needs.
-### markdown.Markdown([**kwargs]) {: #Markdown
data-toc-label='markdown.Markdown' }
+### `markdown.Markdown([**kwargs])` {: #Markdown
data-toc-label='markdown.Markdown' }
The same options are available when initializing the `markdown.Markdown` class
as on the [`markdown.markdown`](#markdown) function, except that the class does
@@ -229,7 +247,14 @@
the thread they were created in. A single instance should not be accessed
from multiple threads.
-#### Markdown.convert(source) {: #convert data-toc-label='Markdown.convert' }
+#### `Markdown.convert(source)` {: #convert data-toc-label='Markdown.convert' }
+
+!!! warning
+
+ The Python-Markdown library does ***not*** sanitize its HTML output. If
+ you are processing Markdown input from an untrusted source, it is your
+ responsibility to ensure that it is properly sanitized. For more
+ information see [Sanitizing HTML Output].
The `source` text must meet the same requirements as the [`text`](#text)
argument of the [`markdown.markdown`](#markdown) function.
@@ -258,7 +283,16 @@
html3 = md.reset().convert(text3)
```
-#### Markdown.convertFile(**kwargs) {: #convertFile
data-toc-label='Markdown.convertFile' }
+#### `Markdown.convertFile(**kwargs)` {: #convertFile
data-toc-label='Markdown.convertFile' }
+
+!!! warning
+
+ The Python-Markdown library does ***not*** sanitize its HTML output. As
+ `Markdown.convertFile` writes directly to the file system, there is no
+ easy way to sanitize the output from Python code. Therefore, it is
+ recommended that the `Markdown.convertFile` method not be used on input
+ from an untrusted source. For more information see [Sanitizing HTML
+ Output].
The arguments of this method are identical to the arguments of the same
name on the `markdown.markdownFromFile` function ([`input`](#input),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/docs/sanitization.md
new/markdown-3.10.2/docs/sanitization.md
--- old/markdown-3.10.1/docs/sanitization.md 1970-01-01 01:00:00.000000000
+0100
+++ new/markdown-3.10.2/docs/sanitization.md 2026-02-09 15:57:10.000000000
+0100
@@ -0,0 +1,76 @@
+title: Sanitization and Security
+
+# Sanitizing HTML Output
+
+The Python-Markdown library does ***not*** sanitize its HTML output. If you
+are processing Markdown input from an untrusted source, it is your
+responsibility to ensure that it is properly sanitized. See _[Markdown and
+XSS]_ for an overview of some of the dangers and _[Improper markup sanitization
+in popular software]_ for notes on best practices to ensure HTML is properly
+sanitized. With those concerns in mind, some recommendations are provided
+below to ensure that any input from an untrusted source is properly
+sanitized.
+
+That said, if you fully trust the source of your input, you may choose to do
+nothing. Conversely, you may find solutions other than those suggested here.
+However, you do so at your own risk.
+
+## Using `JustHTML`
+
+[`JustHTML`][JustHTML] is recommended as a sanitizer on the output of
`markdown.markdown`
+or `Markdown.convert`. When you pass HTML output through `JustHTML`, it is
+sanitized by default according to a strict [allow list policy]. The policy
+can be [customized] if necessary.
+
+``` python
+import markdown
+from justhtml import JustHTML
+
+html = markdown.markdown(text)
+safe_html = JustHTML(html, fragment=True).to_html()
+```
+
+## Using `nh3` or `bleach`
+
+If you cannot use `JustHTML` for some reason, some alternatives include
[`nh3`][nh3] or
+[`bleach`][bleach][^1]. However, be aware that these libraries will not be
sufficient
+in themselves and will require customization. Some useful lists of allowed
+tags and attributes can be found in the [`bleach-allowlist`]
+[bleach-allowlist] library, which should work with both `nh3` and `bleach` as
`nh3`
+mirrors `bleach`'s API.
+
+``` python
+import markdown
+import bleach
+from bleach_allowlist import markdown_tags, markdown_attrs
+
+html = markdown.markdown(text)
+safe_html = bleach.clean(html, markdown_tags, markdown_attrs)
+```
+
+[^1]: The [`bleach`][bleach] project has been
[deprecated](https://github.com/mozilla/bleach/issues/698).
+However, it may be the only option for some users as `nh3` is a set of Python
bindings to a Rust library.
+
+## Sanitizing on the Command Line
+
+Both Python-Markdown and `JustHTML` provide command line interfaces which read
+from `STDIN` and write to `STDOUT`. Therefore, they can be used together to
+ensure that the output from untrusted input is properly sanitized.
+
+```sh
+echo "Some **Markdown** text." | python -m markdown | justhtml - --fragment >
safe_output.html
+```
+
+For more information on `JustHTML`'s Command Line Interface, see the
+[documentation][JustHTML_CLI]. Use the `--help` option for a list of all
available
+options and arguments to the `markdown` command.
+
+[Markdown and XSS]: https://michelf.ca/blog/2010/markdown-and-xss/
+[Improper markup sanitization in popular software]:
https://github.com/ChALkeR/notes/blob/master/Improper-markup-sanitization.md
+[JustHTML]: https://emilstenstrom.github.io/justhtml/
+[allow list policy]:
https://emilstenstrom.github.io/justhtml/html-cleaning.html#default-sanitization-policy
+[customized]:
https://emilstenstrom.github.io/justhtml/html-cleaning.html#use-a-custom-sanitization-policy
+[nh3]: https://nh3.readthedocs.io/en/latest/
+[bleach]: http://bleach.readthedocs.org/en/latest/
+[bleach-allowlist]: https://github.com/yourcelf/bleach-allowlist
+[JustHTML_CLI]: https://emilstenstrom.github.io/justhtml/cli.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/markdown/__main__.py
new/markdown-3.10.2/markdown/__main__.py
--- old/markdown-3.10.1/markdown/__main__.py 2026-01-21 19:09:10.000000000
+0100
+++ new/markdown-3.10.2/markdown/__main__.py 2026-02-09 15:57:10.000000000
+0100
@@ -49,10 +49,14 @@
usage = """%prog [options] [INPUTFILE]
(STDIN is assumed if no INPUTFILE is given)"""
desc = "A Python implementation of John Gruber's Markdown. " \
- "https://Python-Markdown.github.io/"
+ "https://python-markdown.github.io/"
ver = "%%prog %s" % markdown.__version__
+ epilog = "WARNING: The Python-Markdown library does NOT sanitize its HTML
output. If " \
+ "you are processing Markdown input from an untrusted source, it
is your " \
+ "responsibility to ensure that it is properly sanitized. For more
" \
+ "information see
<https://python-markdown.github.io/sanitization/>."
- parser = optparse.OptionParser(usage=usage, description=desc, version=ver)
+ parser = optparse.OptionParser(usage=usage, description=desc, version=ver,
epilog=epilog)
parser.add_option("-f", "--file", dest="filename", default=None,
help="Write output to OUTPUT_FILE. Defaults to STDOUT.",
metavar="OUTPUT_FILE")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/markdown/__meta__.py
new/markdown-3.10.2/markdown/__meta__.py
--- old/markdown-3.10.1/markdown/__meta__.py 2026-01-21 19:09:10.000000000
+0100
+++ new/markdown-3.10.2/markdown/__meta__.py 2026-02-09 15:57:10.000000000
+0100
@@ -28,7 +28,7 @@
from __future__ import annotations
-__version_info__ = (3, 10, 1, 'final', 0)
+__version_info__ = (3, 10, 2, 'final', 0)
def _get_version(version_info):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/markdown/core.py
new/markdown-3.10.2/markdown/core.py
--- old/markdown-3.10.1/markdown/core.py 2026-01-21 19:09:10.000000000
+0100
+++ new/markdown-3.10.2/markdown/core.py 2026-02-09 15:57:10.000000000
+0100
@@ -335,6 +335,12 @@
[`ElementTree`][xml.etree.ElementTree.ElementTree] object has been
serialized into text.
5. The output is returned as a string.
+ !!! warning
+ The Python-Markdown library does ***not*** sanitize its HTML
output.
+ If you are processing Markdown input from an untrusted source, it
is your
+ responsibility to ensure that it is properly sanitized. For more
+ information see [Sanitizing HTML Output](../../sanitization.md).
+
"""
# Fix up the source text
@@ -392,9 +398,9 @@
encoding: str | None = None,
) -> Markdown:
"""
- Converts a Markdown file and returns the HTML as a Unicode string.
+ Read Markdown text from a file or stream and write HTML output to a
file or stream.
- Decodes the file using the provided encoding (defaults to `utf-8`),
+ Decodes the input file using the provided encoding (defaults to
`utf-8`),
passes the file content to markdown, and outputs the HTML to either
the provided stream or the file with provided name, using the same
encoding as the source file. The
@@ -410,6 +416,14 @@
output: File object or path. Writes to `stdout` if `None`.
encoding: Encoding of input and output files. Defaults to `utf-8`.
+ !!! warning
+ The Python-Markdown library does ***not*** sanitize its HTML
output.
+ As `Markdown.convertFile` writes directly to the file system,
there is no
+ easy way to sanitize the output from Python code. Therefore, it is
+ recommended that the `Markdown.convertFile` method not be used on
input
+ from an untrusted source. For more information see [Sanitizing
HTML
+ Output](../../sanitization.md).
+
"""
encoding = encoding or "utf-8"
@@ -477,6 +491,12 @@
Returns:
A string in the specified output format.
+ !!! warning
+ The Python-Markdown library does ***not*** sanitize its HTML output.
+ If you are processing Markdown input from an untrusted source, it is
your
+ responsibility to ensure that it is properly sanitized. For more
+ information see [Sanitizing HTML Output](../../sanitization.md).
+
"""
md = Markdown(**kwargs)
return md.convert(text)
@@ -484,7 +504,7 @@
def markdownFromFile(**kwargs: Any):
"""
- Read Markdown text from a file and write output to a file or a stream.
+ Read Markdown text from a file or stream and write HTML output to a file
or stream.
This is a shortcut function which initializes an instance of
[`Markdown`][markdown.Markdown],
and calls the [`convertFile`][markdown.Markdown.convertFile] method rather
than
@@ -496,6 +516,14 @@
encoding (str): Encoding of input and output.
**kwargs: Any arguments accepted by the `Markdown` class.
+ !!! warning
+ The Python-Markdown library does ***not*** sanitize its HTML output.
+ As `markdown.markdownFromFile` writes directly to the file system,
there is no
+ easy way to sanitize the output from Python code. Therefore, it is
+ recommended that the `markdown.markdownFromFile` function not be used
on input
+ from an untrusted source. For more information see [Sanitizing HTML
+ Output](../../sanitization.md).
+
"""
md = Markdown(**kwargs)
md.convertFile(kwargs.get('input', None),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/markdown/htmlparser.py
new/markdown-3.10.2/markdown/htmlparser.py
--- old/markdown-3.10.1/markdown/htmlparser.py 2026-01-21 19:09:10.000000000
+0100
+++ new/markdown-3.10.2/markdown/htmlparser.py 2026-02-09 15:57:10.000000000
+0100
@@ -35,7 +35,6 @@
# Included for versions which do not have current comment fix
commentclose = re.compile(r'--!?>')
-commentabruptclose = re.compile(r'-?>')
# Import a copy of the html.parser lib as `htmlparser` so we can monkeypatch
it.
# Users can still do `from html import parser` and get the default behavior.
@@ -48,6 +47,8 @@
# throwing it away. When we see it, we will process it as data.
htmlparser.starttagopen = re.compile('<[a-zA-Z]|</>')
+htmlparser.endtagopen = re.compile('</[a-zA-Z]?')
+
# Monkeypatch `HTMLParser` to only accept `?>` to close Processing
Instructions.
htmlparser.piclose = re.compile(r'\?>')
# Monkeypatch `HTMLParser` to only recognize entity references with a closing
semicolon.
@@ -92,6 +93,30 @@
blank_line_re = re.compile(r'^([ ]*\n){2}')
+class _HTMLParser(htmlparser.HTMLParser):
+ """Handle special start and end tags."""
+
+ def parse_endtag(self, i):
+ start = self.rawdata[i:i+3]
+ c = ord(start[-1])
+ if len(start) < 3 or not (65 <= c <= 90 or 97 <= c <= 122):
+ self.handle_data(self.rawdata[i:i + 2])
+ return i + 2
+ return super().parse_endtag(i)
+
+ def parse_starttag(self, i: int) -> int: # pragma: no cover
+ # Treat `</>` as normal data as it is not a real tag.
+ if self.rawdata[i:i + 3] == '</>':
+ self.handle_data(self.rawdata[i:i + 3])
+ return i + 3
+
+ return super().parse_starttag(i)
+
+
+# Overwrite our custom one for people like MkDocs that pull it in
+htmlparser.HTMLParser = _HTMLParser
+
+
class HTMLExtractor(htmlparser.HTMLParser):
"""
Extract raw HTML from text.
@@ -110,9 +135,6 @@
self.lineno_start_cache = [0]
- self.override_comment_update = False
- self.override_comment_start = 0
-
# This calls self.reset
super().__init__(*args, **kwargs)
self.md = md
@@ -125,8 +147,6 @@
self._cache: list[str] = []
self.cleandoc: list[str] = []
self.lineno_start_cache = [0]
- self.override_comment_start = 0
- self.override_comment_update = False
super().reset()
@@ -276,22 +296,8 @@
def handle_comment(self, data: str):
# Check if the comment is unclosed, if so, we need to override position
- j = len(self.rawdata) - len(data)
- i = j - 2
- if self.rawdata[i:j] == '</':
- self.handle_data('<')
- self.override_comment_start = i
- self.override_comment_update = True
- return
self.handle_empty_tag('<!--{}-->'.format(data), is_block=True)
- def updatepos(self, i: int, j: int) -> int:
- if self.override_comment_update:
- self.override_comment_update = False
- i = self.override_comment_start
- j = self.override_comment_start + 1
- return super().updatepos(i, j)
-
def handle_decl(self, data: str):
self.handle_empty_tag('<!{}>'.format(data), is_block=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/markdown-3.10.1/mkdocs.yml
new/markdown-3.10.2/mkdocs.yml
--- old/markdown-3.10.1/mkdocs.yml 2026-01-21 19:09:10.000000000 +0100
+++ new/markdown-3.10.2/mkdocs.yml 2026-02-09 15:57:10.000000000 +0100
@@ -22,6 +22,7 @@
- Installation: install.md
- Library Reference: reference.md
- Command Line: cli.md
+ - Sanitization and Security: sanitization.md
- Extensions: extensions/index.md
- Officially Supported Extensions:
- Abbreviations: extensions/abbreviations.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/markdown-3.10.1/tests/test_syntax/blocks/test_html_blocks.py
new/markdown-3.10.2/tests/test_syntax/blocks/test_html_blocks.py
--- old/markdown-3.10.1/tests/test_syntax/blocks/test_html_blocks.py
2026-01-21 19:09:10.000000000 +0100
+++ new/markdown-3.10.2/tests/test_syntax/blocks/test_html_blocks.py
2026-02-09 15:57:10.000000000 +0100
@@ -1706,3 +1706,84 @@
'Test `<!--[if mso]>` and `<!--[if !mso]>`',
'<p>Test <code><!--[if mso]></code> and <code><!--[if
!mso]></code></p>'
)
+
+ def test_issue_1590(self):
+ """Test case with comments in table for issue #1590."""
+
+ self.assertMarkdownRenders(
+ self.dedent(
+ '''
+ <table>
+ <!--[if mso]>-->
+ <td>foo</td>
+ <!--<!endif]-->
+ <td>bar</td>
+ </table>
+ '''
+ ),
+ self.dedent(
+ '''
+ <table>
+ <!--[if mso]>-->
+ <td>foo</td>
+ <!--<!endif]-->
+ <td>bar</td>
+ </table>
+ '''
+ )
+ )
+
+ def test_stress_comment_handling(self):
+ """Stress test the comment handling."""
+
+ self.assertMarkdownRenders(
+ self.dedent(
+ '''
+ `</` <!-- `<!--[if mso]>` and <!-- </> and `<!--[if mso]>`
+
+ <!-- and <!-- `<!--[if mso]>` and </> `</` and `<!--[if mso]>`
+
+ <!-- Real comment -->
+
+ `<!--[if mso]>` `</` `<!--[if mso]>` and </> <!-- and <!--
+
+ </> `<!--[if mso]>` `</` <!-- and <!-- and `<!--[if mso]>`
+ '''
+ ),
+ self.dedent(
+ '''
+ <p><code></</code> <!-- <code><!--[if mso]></code>
and <!-- </> and <code><!--[if mso]></code></p>
+ <p><!-- and <!-- <code><!--[if mso]></code> and
</> <code></</code> and <code><!--[if mso]></code></p>
+ <!-- Real comment -->
+ <p><code><!--[if mso]></code> <code></</code>
<code><!--[if mso]></code> and </> <!-- and <!--</p>
+ <p></> <code><!--[if mso]></code>
<code></</code> <!-- and <!-- and <code><!--[if
mso]></code></p>
+ ''' # noqa: E501
+ )
+ )
+
+ def test_unclosed_endtag(self):
+ """Ensure unclosed end tag does not have side effects."""
+
+ self.assertMarkdownRenders(
+ self.dedent(
+ '''
+ `</`
+
+ <div>
+ <!--[if mso]>-->
+ <p>foo</p>
+ <!--<!endif]-->
+ </div>
+ '''
+ ),
+ self.dedent(
+ '''
+ <p><code></</code></p>
+ <div>
+ <!--[if mso]>-->
+ <p>foo</p>
+ <!--<!endif]-->
+ </div>
+ '''
+ )
+ )