feat: Improve EPUB path normalization by deduplicating segments and handling backslashes

This commit is contained in:
JB
2025-10-13 16:07:00 -07:00
parent 0922ad4727
commit 62d4acc4d6
2 changed files with 34 additions and 2 deletions
+19 -1
View File
@@ -155,7 +155,12 @@ def _normalize_epub_path(base_dir: str, href: str) -> str:
sanitized_lower = sanitized.lower()
if normalized_base:
base_lower = normalized_base.lower()
if sanitized_lower.startswith(base_lower + "/"):
prefix = base_lower + "/"
if sanitized_lower.startswith(prefix):
remainder = sanitized[len(prefix):]
if remainder.lower().startswith(prefix):
sanitized = remainder
sanitized_lower = sanitized.lower()
base_dir = ""
elif sanitized_lower == base_lower:
base_dir = ""
@@ -164,6 +169,19 @@ def _normalize_epub_path(base_dir: str, href: str) -> str:
normalized = posixpath.normpath(combined)
if normalized in {"", "."}:
return ""
normalized = normalized.replace("\\", "/")
segments = [segment for segment in normalized.split("/") if segment and segment != "."]
if not segments:
return ""
deduped: List[str] = []
last_lower: Optional[str] = None
for segment in segments:
segment_lower = segment.lower()
if last_lower == segment_lower:
continue
deduped.append(segment)
last_lower = segment_lower
normalized = "/".join(deduped)
if normalized.startswith("../") or normalized == "..":
return ""
return normalized
+15 -1
View File
@@ -216,7 +216,21 @@
if (typeof value !== 'string') {
return value;
}
return value.replace(/^[\/]+/, '');
const normalized = value.replace(/\\/g, '/').replace(/^[\/]+/, '');
if (!normalized) {
return '';
}
const segments = normalized.split('/').filter((segment) => segment && segment !== '.');
if (!segments.length) {
return '';
}
const deduped = [];
segments.forEach((segment) => {
if (!deduped.length || deduped[deduped.length - 1].toLowerCase() !== segment.toLowerCase()) {
deduped.push(segment);
}
});
return deduped.join('/');
};
const normalizeHref = (value) => {