Merge pull request #25 from mebeim/master

Sanitize EPUB paths and skip invalid ones
This commit is contained in:
Kevin Boone
2024-09-14 19:07:08 +01:00
committed by GitHub
3 changed files with 49 additions and 4 deletions

View File

@@ -479,7 +479,7 @@ void epub2txt_do_file (const char *file, const Epub2TxtOptions *options,
run_command((const char *[]){"chmod", "-R", "744", tempdir, NULL}, FALSE);
log_debug ("Permissions fixed");
char *opf;
char *opf, *tmp;
asprintf (&opf, "%s/META-INF/container.xml", tempdir);
log_debug ("OPF path is: %s", opf);
String *rootfile = epub2txt_get_root_file (opf, error);
@@ -488,7 +488,20 @@ void epub2txt_do_file (const char *file, const Epub2TxtOptions *options,
log_debug ("OPF rootfile is: %s", string_cstr(rootfile));
free (opf);
asprintf (&opf, "%s/%s", tempdir, string_cstr (rootfile));
asprintf (&tmp, "%s/%s", tempdir, string_cstr (rootfile));
opf = canonicalize_file_name (tmp);
free (tmp);
if (opf == NULL || !is_subpath (tempdir, opf))
{
if (opf == NULL)
asprintf (error, "Bad OPF rootfile path: %s", strerror (errno));
else
asprintf (error, "Bad OPF rootfile path \"%s\": outside EPUB "
"container", opf);
free (tempdir);
return;
}
char *content_dir = strdup (opf);
char *p = strrchr (content_dir, '/');
@@ -519,7 +532,21 @@ void epub2txt_do_file (const char *file, const Epub2TxtOptions *options,
{
const char *item = (const char *)list_get (list, i);
free (opf);
asprintf (&opf, "%s/%s", content_dir, item);
asprintf (&tmp, "%s/%s", content_dir, item);
opf = canonicalize_file_name (tmp);
free (tmp);
if (opf == NULL || !is_subpath (content_dir, opf))
{
if (opf == NULL)
log_warning ("Skipping EPUB file \"%s\": invalid path (%s)",
item, strerror (errno));
else
log_warning ("Skipping EPUB file \"%s\": outside EPUB content "
"directory", item);
continue;
}
xhtml_file_to_stdout (opf, options, error);
}
list_destroy (list);

View File

@@ -80,4 +80,18 @@ char *decode_url (const char *url)
return ret;
}
/*==========================================================================
is_subpath
Determine whether path is a subpath of root; or in other words, whether path
points to a file/directory inside root. Both root and path are assumed to be
in canonical form, therefore the caller should make sure of this using e.g.
canonicalize_file_name().
(Marco Bonelli)
*==========================================================================*/
BOOL is_subpath (const char *root, const char *path)
{
size_t root_len = strlen (root);
size_t path_len = strlen (path);
return path_len > root_len && !strncmp (root, path, root_len)
&& path[root_len] == '/';
}

View File

@@ -13,3 +13,7 @@ int run_command (const char *const argv[], BOOL abort_on_error);
/** Decode %xx in URL-type strings. The caller must free the resulting
string, which will be no longer than the input. */
char *decode_url (const char *url);
/** Determine whether path is a subpath of root, assuming both paths are in
canonical form. */
BOOL is_subpath (const char *root, const char *path);