1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-12-18 14:10:30 +00:00

Merge branch 'master' into Develop

This commit is contained in:
Ozzie Isaacs 2024-08-11 19:56:20 +02:00
commit acd3c8d103
58 changed files with 8041 additions and 7296 deletions

View File

@ -11,7 +11,7 @@ To receive fixes for security vulnerabilities it is required to always upgrade t
## History ## History
| Fixed in | Description |CVE number | | Fixed in | Description |CVE number |
|---------------|--------------------------------------------------------------------------------------------------------------------|---------| |---------------|--------------------------------------------------------------------------------------------------------------------------------|---------|
| 3rd July 2018 | Guest access acts as a backdoor || | 3rd July 2018 | Guest access acts as a backdoor ||
| V 0.6.7 | Hardcoded secret key for sessions |CVE-2020-12627 | | V 0.6.7 | Hardcoded secret key for sessions |CVE-2020-12627 |
| V 0.6.13 | Calibre-Web Metadata cross site scripting |CVE-2021-25964| | V 0.6.13 | Calibre-Web Metadata cross site scripting |CVE-2021-25964|
@ -45,6 +45,11 @@ To receive fixes for security vulnerabilities it is required to always upgrade t
| V 0.6.21 | Cross-site scripting (XSS) stored in href bypasses filter using data wrapper no longer possible || | V 0.6.21 | Cross-site scripting (XSS) stored in href bypasses filter using data wrapper no longer possible ||
| V 0.6.21 | Cross-site scripting (XSS) is no longer possible via pathchooser || | V 0.6.21 | Cross-site scripting (XSS) is no longer possible via pathchooser ||
| V 0.6.21 | Error Handling at non existent rating, language, and user downloaded books was fixed || | V 0.6.21 | Error Handling at non existent rating, language, and user downloaded books was fixed ||
| V 0.6.22 | Upload mimetype is checked to prevent malicious file content in the books library ||
| V 0.6.22 | Cross-site scripting (XSS) stored in comments section is prevented better (switching from lxml to bleach for sanitizing strings) ||
| V 0.6.23 | Cookies are no longer stored for opds basic authentication and proxy authentication ||
## Statement regarding Log4j (CVE-2021-44228 and related) ## Statement regarding Log4j (CVE-2021-44228 and related)

View File

@ -20,10 +20,11 @@ import os
import mutagen import mutagen
import base64 import base64
from . import cover from . import cover, logger
from cps.constants import BookMeta from cps.constants import BookMeta
log = logger.create()
def get_audio_file_info(tmp_file_path, original_file_extension, original_file_name): def get_audio_file_info(tmp_file_path, original_file_extension, original_file_name):
tmp_cover_name = None tmp_cover_name = None
@ -57,7 +58,7 @@ def get_audio_file_info(tmp_file_path, original_file_extension, original_file_na
cover_info = dat cover_info = dat
break break
cover.cover_processing(tmp_file_path, cover_info.data, "." + cover_info.mime[-3:]) cover.cover_processing(tmp_file_path, cover_info.data, "." + cover_info.mime[-3:])
elif original_file_extension in [".ogg", ".flac"]: elif original_file_extension in [".ogg", ".flac", ".opus", ".ogv"]:
title = audio_file.tags.get('TITLE')[0] if "TITLE" in audio_file else None title = audio_file.tags.get('TITLE')[0] if "TITLE" in audio_file else None
author = audio_file.tags.get('ARTIST')[0] if "ARTIST" in audio_file else None author = audio_file.tags.get('ARTIST')[0] if "ARTIST" in audio_file else None
comments = audio_file.tags.get('COMMENTS')[0] if "COMMENTS" in audio_file else None comments = audio_file.tags.get('COMMENTS')[0] if "COMMENTS" in audio_file else None
@ -80,10 +81,10 @@ def get_audio_file_info(tmp_file_path, original_file_extension, original_file_na
tmp_cover_name = os.path.join(os.path.dirname(tmp_file_path), 'cover.jpg') tmp_cover_name = os.path.join(os.path.dirname(tmp_file_path), 'cover.jpg')
cover.cover_processing(tmp_file_path, cover_info.data, "." + cover_info.mime[-3:]) cover.cover_processing(tmp_file_path, cover_info.data, "." + cover_info.mime[-3:])
elif original_file_extension in [".aac"]: elif original_file_extension in [".aac"]:
title = audio_file.tags.get('Title').value if "title" in audio_file else None title = audio_file.tags.get('Title').value if "Title" in audio_file else None
author = audio_file.tags.get('Artist').value if "artist" in audio_file else None author = audio_file.tags.get('Artist').value if "Artist" in audio_file else None
comments = None # audio_file.tags.get('COMM', None) comments = audio_file.tags.get('Comment').value if "Comment" in audio_file else None
tags = "" tags = audio_file.tags.get('Genre').value if "Genre" in audio_file else None
series = audio_file.tags.get('Album').value if "Album" in audio_file else None series = audio_file.tags.get('Album').value if "Album" in audio_file else None
series_id = audio_file.tags.get('Track').value if "Track" in audio_file else None series_id = audio_file.tags.get('Track').value if "Track" in audio_file else None
publisher = audio_file.tags.get('Label').value if "Label" in audio_file else None publisher = audio_file.tags.get('Label').value if "Label" in audio_file else None
@ -94,21 +95,45 @@ def get_audio_file_info(tmp_file_path, original_file_extension, original_file_na
with open(tmp_cover_name, "wb") as cover_file: with open(tmp_cover_name, "wb") as cover_file:
cover_file.write(cover_data.value.split(b"\x00",1)[1]) cover_file.write(cover_data.value.split(b"\x00",1)[1])
elif original_file_extension in [".asf"]: elif original_file_extension in [".asf"]:
title = audio_file.tags.get('Title')[0].value if "title" in audio_file else None title = audio_file.tags.get('Title')[0].value if "Title" in audio_file else None
author = audio_file.tags.get('Artist')[0].value if "artist" in audio_file else None author = audio_file.tags.get('Artist')[0].value if "Artist" in audio_file else None
comments = None # audio_file.tags.get('COMM', None) comments = audio_file.tags.get('Comments')[0].value if "Comments" in audio_file else None
tags = "" tags = audio_file.tags.get('Genre')[0].value if "Genre" in audio_file else None
series = audio_file.tags.get('Album')[0].value if "Album" in audio_file else None series = audio_file.tags.get('Album')[0].value if "Album" in audio_file else None
series_id = audio_file.tags.get('Track')[0].value if "Track" in audio_file else None series_id = audio_file.tags.get('Track')[0].value if "Track" in audio_file else None
publisher = audio_file.tags.get('Label')[0].value if "Label" in audio_file else None publisher = audio_file.tags.get('Label')[0].value if "Label" in audio_file else None
pubdate = audio_file.tags.get('Year')[0].value if "Year" in audio_file else None pubdate = audio_file.tags.get('Year')[0].value if "Year" in audio_file else None
cover_data = audio_file.tags['WM/Picture'] cover_data = audio_file.tags.get('WM/Picture', None)
if cover_data: if cover_data:
tmp_cover_name = os.path.join(os.path.dirname(tmp_file_path), 'cover.jpg') tmp_cover_name = os.path.join(os.path.dirname(tmp_file_path), 'cover.jpg')
with open(tmp_cover_name, "wb") as cover_file: with open(tmp_cover_name, "wb") as cover_file:
cover_file.write(cover_data[0].value) cover_file.write(cover_data[0].value)
elif original_file_extension in [".mp4", ".m4a", ".m4b"]:
title = audio_file.tags.get('©nam')[0] if "©nam" in audio_file.tags else None
author = audio_file.tags.get('©ART')[0] if "©ART" in audio_file.tags else None
comments = audio_file.tags.get('©cmt')[0] if "©cmt" in audio_file.tags else None
tags = audio_file.tags.get('©gen')[0] if "©gen" in audio_file.tags else None
series = audio_file.tags.get('©alb')[0] if "©alb" in audio_file.tags else None
series_id = str(audio_file.tags.get('trkn')[0][0]) if "trkn" in audio_file.tags else None
publisher = ""
pubdate = audio_file.tags.get('©day')[0] if "©day" in audio_file.tags else None
cover_data = audio_file.tags.get('covr', None)
if cover_data:
tmp_cover_name = os.path.join(os.path.dirname(tmp_file_path), 'cover.jpg')
cover_type = None
for c in cover_data:
if c.imageformat == mutagen.mp4.AtomDataType.JPEG:
cover_type =".jpg"
cover_bin = c
break
elif c.imageformat == mutagen.mp4.AtomDataType.PNG:
cover_type = ".png"
cover_bin = c
break
if cover_type:
cover.cover_processing(tmp_file_path, cover_bin, cover_type)
else:
logger.error("Unknown covertype in file {} ".format(original_file_name))
return BookMeta( return BookMeta(
file_path=tmp_file_path, file_path=tmp_file_path,

View File

@ -175,7 +175,7 @@ BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, d
'series_id, languages, publisher, pubdate, identifiers') 'series_id, languages, publisher, pubdate, identifiers')
# python build process likes to have x.y.zbw -> b for beta and w a counting number # python build process likes to have x.y.zbw -> b for beta and w a counting number
STABLE_VERSION = {'version': '0.6.23b'} STABLE_VERSION = {'version': '0.6.24b'}
NIGHTLY_VERSION = dict() NIGHTLY_VERSION = dict()
NIGHTLY_VERSION[0] = '$Format:%H$' NIGHTLY_VERSION[0] = '$Format:%H$'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@ from flask_babel import gettext as _
from . import logger, comic, isoLanguages from . import logger, comic, isoLanguages
from .constants import BookMeta from .constants import BookMeta
from .helper import split_authors from .helper import split_authors
from .file_helper import get_temp_dir, validate_mime_type from .file_helper import get_temp_dir
log = logger.create() log = logger.create()
@ -91,7 +91,8 @@ def process(tmp_file_path, original_file_name, original_file_extension, rar_exec
original_file_name, original_file_name,
original_file_extension, original_file_extension,
rar_executable) rar_executable)
elif extension_upper in [".MP3", ".OGG", ".FLAC", ".WAV", ".AAC", ".AIFF", ".ASF", ".MP4"] and use_audio_meta: elif extension_upper in [".MP3", ".OGG", ".FLAC", ".WAV", ".AAC", ".AIFF", ".ASF", ".MP4",
".M4A", ".M4B", ".OGV", ".OPUS"] and use_audio_meta:
meta = audio.get_audio_file_info(tmp_file_path, original_file_extension, original_file_name) meta = audio.get_audio_file_info(tmp_file_path, original_file_extension, original_file_name)
except Exception as ex: except Exception as ex:
log.warning('cannot parse metadata, using default: %s', ex) log.warning('cannot parse metadata, using default: %s', ex)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff