mirror of
https://github.com/janeczku/calibre-web
synced 2026-10-14 12:01:41 +00:00
Replaced bleach with nh3
Fix for format check during conversion
This commit is contained in:
+27
-14
@@ -18,32 +18,45 @@
|
||||
|
||||
from . import logger
|
||||
from lxml.etree import ParserError
|
||||
import re
|
||||
|
||||
log = logger.create()
|
||||
|
||||
CONTROL_CHAR_RE = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]")
|
||||
|
||||
try:
|
||||
# at least bleach 6.0 is needed -> incomplatible change from list arguments to set arguments
|
||||
from bleach import clean as clean_html
|
||||
from bleach.sanitizer import ALLOWED_TAGS
|
||||
bleach = True
|
||||
except ImportError:
|
||||
import nh3
|
||||
from nh3 import clean as clean_html
|
||||
bleach = False
|
||||
BASE_ALLOWED_TAGS = nh3.ALLOWED_TAGS
|
||||
BASE_ALLOWED_ATTRIBUTES = nh3.ALLOWED_ATTRIBUTES
|
||||
except ImportError:
|
||||
# at least bleach 6.0 is needed -> incomplatible change from list arguments to set arguments
|
||||
from bleach import clean as clean_html
|
||||
from bleach.sanitizer import ALLOWED_ATTRIBUTES as BASE_ALLOWED_ATTRIBUTES
|
||||
from bleach.sanitizer import ALLOWED_TAGS as BASE_ALLOWED_TAGS
|
||||
bleach = True
|
||||
|
||||
ALLOWED_TAGS = set(BASE_ALLOWED_TAGS) | {"p", "span", "div", "pre", "br", "h1", "h2", "h3", "h4", "h5", "h6", "img"}
|
||||
ALLOWED_ATTRIBUTES = {
|
||||
key: set(value) for key, value in BASE_ALLOWED_ATTRIBUTES.items()
|
||||
}
|
||||
ALLOWED_ATTRIBUTES["*"] = set(ALLOWED_ATTRIBUTES.get("*", set())) | {"class", "style"}
|
||||
ALLOWED_ATTRIBUTES["a"] = set(ALLOWED_ATTRIBUTES.get("a", set())) | {"href", "title", "rel"}
|
||||
ALLOWED_ATTRIBUTES["img"] = set(ALLOWED_ATTRIBUTES.get("img", set())) | {"src", "alt", "title", "width", "height"}
|
||||
|
||||
|
||||
def _normalize_html_input(unsafe_text):
|
||||
return CONTROL_CHAR_RE.sub("", unsafe_text)
|
||||
|
||||
|
||||
def clean_string(unsafe_text, book_id=0):
|
||||
try:
|
||||
unsafe_text = _normalize_html_input(unsafe_text)
|
||||
if bleach:
|
||||
allowed_tags = list(ALLOWED_TAGS)
|
||||
allowed_tags.extend(["p", "span", "div", "pre", "br", "h1", "h2", "h3", "h4", "h5", "h6", "img"])
|
||||
allowed_attributes = {
|
||||
"*": ["class", "style"],
|
||||
"a": ["href", "title", "rel"],
|
||||
"img": ["src", "alt", "title", "width", "height"],
|
||||
}
|
||||
safe_text = clean_html(unsafe_text, tags=set(allowed_tags), attributes=allowed_attributes)
|
||||
safe_text = clean_html(unsafe_text, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES)
|
||||
else:
|
||||
safe_text = clean_html(unsafe_text)
|
||||
safe_text = clean_html(unsafe_text, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, link_rel=None)
|
||||
except ParserError as e:
|
||||
log.error("Comments of book {} are corrupted: {}".format(book_id, e))
|
||||
safe_text = ""
|
||||
|
||||
+9
-1
@@ -189,7 +189,15 @@ def convert_bookformat(book_id):
|
||||
flash(_("Source format for conversion not supported"), category="error")
|
||||
return redirect(url_for('edit-book.show_edit_book', book_id=book_id))
|
||||
|
||||
if book_format_to.lower() not in constants.EXTENSIONS_CONVERT_TO:
|
||||
allowed_destination_formats = set(constants.EXTENSIONS_CONVERT_TO)
|
||||
if config.config_kepubifypath:
|
||||
allowed_destination_formats.add('kepub')
|
||||
|
||||
if book_format_to.lower() == 'kepub' and book_format_from.lower() != 'epub':
|
||||
flash(_("Source format for conversion not supported"), category="error")
|
||||
return redirect(url_for('edit-book.show_edit_book', book_id=book_id))
|
||||
|
||||
if book_format_to.lower() not in allowed_destination_formats:
|
||||
flash(_("Destination format for conversion not supported"), category="error")
|
||||
return redirect(url_for('edit-book.show_edit_book', book_id=book_id))
|
||||
|
||||
|
||||
+2
-1
@@ -24,7 +24,7 @@ import mimetypes
|
||||
import hashlib
|
||||
from io import BytesIO
|
||||
|
||||
from . import logger, config
|
||||
from . import logger
|
||||
|
||||
log = logger.create()
|
||||
|
||||
@@ -46,6 +46,7 @@ def get_mimetype(ext):
|
||||
|
||||
def get_temp_dir():
|
||||
base_tmp_dir = os.path.join(gettempdir(), 'calibre_web')
|
||||
from . import config
|
||||
instance_value = "{}|{}".format(config.config_calibre_dir or "", config.config_port or "")
|
||||
instance_key = hashlib.md5(instance_value.encode('utf-8')).hexdigest() # nosec
|
||||
tmp_dir = os.path.join(base_tmp_dir, "instance_{}".format(instance_key[:12]))
|
||||
|
||||
+7
-1
@@ -1262,7 +1262,13 @@ def download_link(book_id, book_format, anyname):
|
||||
@login_required_if_no_ano
|
||||
@download_required
|
||||
def send_to_ereader(book_id, book_format, convert):
|
||||
if book_format.lower() not in constants.EXTENSIONS_UPLOAD:
|
||||
book = calibre_db.get_book(book_id)
|
||||
allowed_formats = check_send_to_ereader(book) if book else []
|
||||
is_allowed = any(
|
||||
option.get('format', '').lower() == book_format.lower() and int(option.get('convert', -1)) == convert
|
||||
for option in allowed_formats
|
||||
)
|
||||
if not is_allowed:
|
||||
return make_response(jsonify(type="danger", message=_("Book format not supported")))
|
||||
if not config.get_mail_server_configured():
|
||||
return make_response(jsonify(type="danger", message=_("Please configure the SMTP mail settings first...")))
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ dependencies = [
|
||||
"urllib3>=1.22,<3.0",
|
||||
"Flask-Limiter>=2.3.0,<4.2.0",
|
||||
"regex>=2022.3.2,<2026.1.16",
|
||||
"bleach>=6.0.0,<6.4.0",
|
||||
"nh3>=0.3.0,<0.4.0",
|
||||
"python-magic>=0.4.27,<0.5.0",
|
||||
"python-magic-bin>=0.4.0,<0.5.0;sys_platform=='win32'",
|
||||
"flask-httpAuth>=4.4.0,<5.0.0",
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ netifaces-plus>=0.12.0,<0.13.0
|
||||
urllib3>=1.22,<3.0
|
||||
Flask-Limiter>=2.3.0,<4.2.0
|
||||
regex>=2022.3.2,<2026.1.16
|
||||
bleach>=6.0.0,<6.4.0
|
||||
nh3>=0.3.0,<0.4.0
|
||||
python-magic>=0.4.27,<0.5.0
|
||||
python-magic-bin>=0.4.0,<0.5.0;sys_platform=='win32'
|
||||
flask-httpAuth>=4.4.0,<5.0.0
|
||||
|
||||
+1839
-41396
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user