[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Mon, 30 Sep 2024 18:29:11 -0400 (EDT) |
branch: master
commit 10e2d3332a98285807d876f2b430336a99ec9a85
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Jul 24 00:27:59 2024 +0200
* tp/Texinfo/Convert/HTML.pm (_do_jslicenses_file): check path before
gathering the output.
* tp/Texinfo/XS/convert/convert_html.c (file_error_or_write_close)
(do_jslicenses_file, do_js_files, html_convert_output): add
file_error_or_write_close with code from html_convert_output.
Implement do_jslicenses_file and do_js_files in C.
---
ChangeLog | 10 +
tp/Texinfo/Convert/HTML.pm | 11 +-
tp/Texinfo/XS/convert/convert_html.c | 441 +++++++++++++++++++++++++++++++----
3 files changed, 408 insertions(+), 54 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index abc914de3e..7f9b4a0829 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,16 @@
* tp/Texinfo/XS:
Run "gnulib-tool --add-import copy-file"
+2024-07-23 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/Convert/HTML.pm (_do_jslicenses_file): check path before
+ gathering the output.
+
+ * tp/Texinfo/XS/convert/convert_html.c (file_error_or_write_close)
+ (do_jslicenses_file, do_js_files, html_convert_output): add
+ file_error_or_write_close with code from html_convert_output.
+ Implement do_jslicenses_file and do_js_files in C.
+
2024-07-23 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/Common.pm (output_files_open_out),
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index a3fb2bdf25..494b6f739e 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -12107,6 +12107,12 @@ sub _do_jslicenses_file {
return if (!$setting or $setting ne 'generate' or !defined($path)
or $path eq '');
+ if (File::Spec->file_name_is_absolute($path) or $path =~ /^[A-Za-z]*:/) {
+ $self->converter_document_warn(sprintf(
+ __("cannot use absolute path or URL `%s' for JS_WEBLABELS_FILE when
generating web labels file"), $path));
+ return;
+ }
+
my $doctype = $self->get_conf('DOCTYPE');
$doctype = '' if (!defined($doctype));
my $root_html_element_attributes =
$self->_root_html_element_attributes_string();
@@ -12133,11 +12139,6 @@ sub _do_jslicenses_file {
$a .= "</table>\n</body></html>\n";
- if (File::Spec->file_name_is_absolute($path) or $path =~ /^[A-Za-z]*:/) {
- $self->converter_document_warn(sprintf(
- __("cannot use absolute path or URL `%s' for JS_WEBLABELS_FILE when
generating web labels file"), $path));
- return;
- }
my $license_file;
if ($destination_directory ne '') {
$license_file = File::Spec->catdir($destination_directory, $path);
diff --git a/tp/Texinfo/XS/convert/convert_html.c
b/tp/Texinfo/XS/convert/convert_html.c
index 09c31150da..25b10b3e43 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -25,6 +25,8 @@
#include <unistr.h>
#include <unictype.h>
+#include "copy-file_but_owner.h"
+
#include "text.h"
#include "element_types.h"
#include "tree_types.h"
@@ -20536,6 +20538,7 @@ convert_output_output_unit_internal (CONVERTER *self,
message_list_document_error (&self->error_messages, self->conf, 0,
"could not open %s for writing: %s",
out_filepath, open_error_message);
+ free (open_error_message);
free (encoded_out_filepath);
return 0;
}
@@ -20631,6 +20634,383 @@ html_prepare_title_titlepage (CONVERTER *self, const
char *output_file,
memset (&self->current_filename, 0, sizeof (FILE_NUMBER_NAME));
}
+static int
+file_error_or_write_close (CONVERTER *self, const char *out_filepath,
+ const char *encoded_out_filepath,
+ FILE *file_fh,
+ const ENCODING_CONVERSION *conversion,
+ char *page,
+ const char *open_error_message)
+{
+ if (!file_fh)
+ {
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "could not open %s for writing: %s",
+ out_filepath, open_error_message);
+ }
+ else
+ {
+ char *result;
+ size_t res_len;
+ size_t write_len;
+
+ if (conversion)
+ {
+ result = encode_with_iconv (conversion->iconv,
+ page, 0);
+ res_len = strlen (result);
+ }
+ else
+ {
+ result = page;
+ res_len = strlen (page);
+ }
+ write_len = fwrite (result, sizeof (char),
+ res_len, file_fh);
+ if (conversion)
+ free (result);
+ if (write_len != res_len)
+ { /* register error message instead? */
+ fprintf (stderr,
+ "ERROR: write to %s failed (%zu/%zu)\n",
+ encoded_out_filepath, write_len, res_len);
+ return -1;
+ }
+ output_files_register_closed
+ (&self->output_files_information,
+ encoded_out_filepath);
+ if (fclose (file_fh))
+ {
+ message_list_document_error (
+ &self->error_messages, self->conf, 0,
+ "error on closing %s: %s",
+ out_filepath, strerror (errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void
+do_jslicenses_file (CONVERTER *self)
+{
+ const char *destination_directory = self->destination_directory;
+ const char *setting = self->conf->JS_WEBLABELS.o.string;
+ const char *path = self->conf->JS_WEBLABELS_FILE.o.string;
+ TEXT result;
+ char *root_html_element_attributes;
+ size_t i;
+ int path_not_ok = 0;
+ char *license_file;
+ char *path_encoding;
+ char *open_error_message;
+ int overwritten_file;
+ char *encoded_out_filepath;
+ FILE *file_fh;
+ const ENCODING_CONVERSION *conversion = 0;
+
+ /* Possible settings:
+ 'generate' - create file at JS_WEBLABELS_FILE
+ 'reference' - reference file at JS_WEBLABELS_FILE but do not create it
+ 'omit' - do nothing */
+ if (!setting || strcmp (setting, "generate") || !path || !strlen (path))
+ return;
+
+ if (!memcmp (path, "/", 1))
+ path_not_ok = 1;
+ else
+ {
+ const char *p = path;
+ while (isascii_alpha (*p))
+ p++;
+ if (*p == ':')
+ path_not_ok = 1;
+ }
+
+ if (path_not_ok)
+ {
+ message_list_document_warn (&self->error_messages, self->conf, 0,
+ "cannot use absolute path or URL `%s' for JS_WEBLABELS_FILE when generating
web labels file",
+ path);
+ return;
+ }
+
+ text_init (&result);
+ if (self->conf->DOCTYPE.o.string)
+ text_append (&result, self->conf->DOCTYPE.o.string);
+ text_append_n (&result, "\n", 1);
+ root_html_element_attributes
+ = root_html_element_attributes_string (self);
+ if (!root_html_element_attributes)
+ root_html_element_attributes = strdup ("");
+ text_printf (&result, "<html%s>\n", root_html_element_attributes);
+ free (root_html_element_attributes);
+ text_append (&result, "<head><title>jslicense labels</title></head>\n"
+ "<body>\n"
+ "<table id=\"jslicense-labels1\">\n");
+
+ for (i = 0; i < self->jslicenses.number; i++)
+ {
+ size_t j;
+ JSLICENSE_FILE_INFO_LIST *jlicense_file_info_list
+ = &self->jslicenses.list[i];
+
+ for (j = 0; j < jlicense_file_info_list->number; j++)
+ {
+ JSLICENSE_FILE_INFO *jlicense_file_info
+ = &jlicense_file_info_list->list[j];
+ char *p_file
+ = url_protect_url_text (self, jlicense_file_info->filename);
+ char *p_url
+ = url_protect_url_text (self, jlicense_file_info->url);
+ char *p_source
+ = url_protect_url_text (self, jlicense_file_info->source);
+ text_append_n (&result, "<tr>\n", 5);
+ text_append_n (&result, "<td><a href=\"", 13);
+ text_append (&result, p_file);
+ text_append_n (&result, "\">", 2);
+ text_append (&result, jlicense_file_info->filename);
+ text_append_n (&result, "</a></td>\n", 10);
+ text_append_n (&result, "<td><a href=\"", 13);
+ text_append (&result, p_url);
+ text_append_n (&result, "\">", 2);
+ text_append (&result, jlicense_file_info->license);
+ text_append_n (&result, "</a></td>\n", 10);
+ text_append_n (&result, "<td><a href=\"", 13);
+ text_append (&result, p_source);
+ text_append_n (&result, "\">", 2);
+ text_append (&result, jlicense_file_info->source);
+ text_append_n (&result, "</a></td>\n", 10);
+ text_append_n (&result, "</tr>\n", 6);
+ free (p_file);
+ free (p_url);
+ free (p_source);
+ }
+ }
+ text_append_n (&result, "</table>\n</body></html>\n", 24);
+
+ if (destination_directory && strlen (destination_directory))
+ xasprintf (&license_file, "%s/%s", destination_directory, path);
+ else
+ license_file = strdup (path);
+
+ encoded_out_filepath = encoded_output_file_name (self->conf,
+ &self->document->global_info, license_file,
+ &path_encoding, 0);
+ file_fh = output_files_open_out (&self->output_files_information,
+ encoded_out_filepath, &open_error_message,
+ &overwritten_file, 0);
+ free (path_encoding);
+ if (overwritten_file)
+ {
+ message_list_document_warn (&self->error_messages, self->conf, 0,
+ "overwritting output file with js licences: %s",
+ license_file);
+ }
+
+ if (file_fh)
+ {
+ if (self->conf->OUTPUT_ENCODING_NAME.o.string
+ && strcmp (self->conf->OUTPUT_ENCODING_NAME.o.string, "utf-8"))
+ {
+ conversion
+ = get_encoding_conversion (
+ self->conf->OUTPUT_ENCODING_NAME.o.string,
+ &output_conversions);
+ }
+ }
+
+ file_error_or_write_close (self, license_file,
+ encoded_out_filepath, file_fh,
+ conversion, result.text,
+ open_error_message);
+ free (open_error_message);
+ free (encoded_out_filepath);
+ free (license_file);
+ free (result.text);
+}
+
+static const char *js_files[4] = {"info.js", "modernizr.js", "info.css", 0};
+
+void
+do_js_files (CONVERTER *self)
+{
+ const char *destination_directory = self->destination_directory;
+
+ if (self->conf->INFO_JS_DIR.o.string)
+ {
+ const char *info_js_dir = self->conf->INFO_JS_DIR.o.string;
+ char *jsdir;
+ char *dir_encoding;
+ int succeeded;
+ char *encoded_jsdir;
+
+ if (destination_directory && strlen (destination_directory))
+ {
+ xasprintf (&jsdir, "%s/%s", destination_directory, info_js_dir);
+ }
+ else
+ jsdir = strdup (info_js_dir);
+
+ encoded_jsdir = encoded_output_file_name (self->conf,
+ &self->document->global_info,
+ jsdir, &dir_encoding, 0);
+
+ free (dir_encoding);
+
+ succeeded = create_destination_directory (self, encoded_jsdir, jsdir);
+
+ if (succeeded)
+ {
+ int i;
+ if (self->conf->TEST.o.integer <= 0)
+ {
+ /* conversion_paths_info paths are byte strings */
+ char *jssrcdir;
+ if (!conversion_paths_info.texinfo_uninstalled)
+ {
+ xasprintf (&jssrcdir, "%s/%s",
+ conversion_paths_info.p.installed.pkgdatadir,
+ "js");
+ }
+ else
+ {
+ if (conversion_paths_info.p.uninstalled.top_srcdir)
+ xasprintf (&jssrcdir, "%s/%s",
+ conversion_paths_info.p.uninstalled.top_srcdir,
+ "js");
+ else
+ jssrcdir = strdup ("js");
+ }
+ for (i = 0; js_files[i]; i++)
+ {
+ char *from;
+ char *to;
+ int status;
+
+ xasprintf (&from, "%s/%s", jssrcdir, js_files[i]);
+ xasprintf (&to, "%s/%s", encoded_jsdir, js_files[i]);
+ status = qcopy_file_preserving_but_owner (from, to);
+
+ if (status != 0)
+ {
+ char *to_file_name;
+ char *from_file_name;
+
+ xasprintf (&to_file_name, "%s/%s", jsdir, js_files[i]);
+ xasprintf (&from_file_name, "%s/%s", jsdir, js_files[i]);
+
+ switch (status)
+ {
+ case GL_COPY_ERR_OPEN_READ:
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "error while opening %s for reading: %s",
+ from_file_name, strerror (errno));
+ break;
+
+ case GL_COPY_ERR_OPEN_BACKUP_WRITE:
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "cannot open %s for writing: %s",
+ to_file_name, strerror (errno));
+ break;
+
+ case GL_COPY_ERR_READ:
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "error reading %s: %s",
+ from_file_name, strerror (errno));
+ break;
+
+ case GL_COPY_ERR_WRITE:
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "error writing %s: %s",
+ to_file_name, strerror (errno));
+ break;
+
+ case GL_COPY_ERR_AFTER_READ:
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "error after reading %s: %s",
+ from_file_name, strerror (errno));
+ break;
+
+ case GL_COPY_ERR_GET_ACL:
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0,
+ "%s: %s",
+ from_file_name, strerror (errno));
+ break;
+
+ case GL_COPY_ERR_SET_ACL:
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0,
+ "preserving permissions for %s: %s",
+ to_file_name, strerror (errno));
+ break;
+
+ default:
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0,
+ "unexpected error on copying %s into %s",
+ from_file_name, to_file_name);
+ break;
+ }
+ free (to_file_name);
+ free (from_file_name);
+ }
+ free (to);
+ free (from);
+ }
+ free (jssrcdir);
+ }
+ else
+ {
+ /* create empty files for tests to keep results stable. */
+ for (i = 0; js_files[i]; i++)
+ {
+ char *to;
+ FILE *FH;
+
+ xasprintf (&to, "%s/%s", encoded_jsdir, js_files[i]);
+ FH = fopen (to, "w");
+ if (!FH)
+ {
+ char *to_file_name;
+ xasprintf (&to_file_name, "%s/%s", jsdir, js_files[i]);
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "error on creating empty %s: %s",
+ to_file_name, strerror (errno));
+ free (to_file_name);
+ }
+ else
+ {
+ if (fclose (FH) == EOF)
+ {
+ char *to_file_name;
+ xasprintf (&to_file_name, "%s/%s", jsdir,
js_files[i]);
+ message_list_document_error (&self->error_messages,
+ self->conf, 0,
+ "error on closing empty %s: %s",
+ to_file_name, strerror (errno));
+ free (to_file_name);
+ }
+ }
+ free (to);
+ }
+ }
+ }
+ free (encoded_jsdir);
+ }
+
+ if (self->jslicenses.number > 0)
+ do_jslicenses_file (self);
+}
+
char *
html_convert_output (CONVERTER *self, const ELEMENT *root,
const char *output_file, const char
*destination_directory,
@@ -20955,6 +21335,7 @@ html_node_redirections (CONVERTER *self,
char *path_encoding;
char *open_error_message;
int overwritten_file;
+ int status;
add_to_files_source_info (files_source_info,
redirection_filename, "redirection", 0,
@@ -20981,59 +21362,21 @@ html_node_redirections (CONVERTER *self,
encoded_out_filepath, &open_error_message,
&overwritten_file, 0);
free (path_encoding);
- if (!file_fh)
- {
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "could not open %s for writing: %s",
- out_filepath, open_error_message);
- }
- else
- {
- char *result;
- size_t res_len;
- size_t write_len;
- if (conversion)
- {
- result = encode_with_iconv (conversion->iconv,
- redirection_page, 0);
- res_len = strlen (result);
- }
- else
- {
- result = redirection_page;
- res_len = strlen (redirection_page);
- }
- write_len = fwrite (result, sizeof (char),
- res_len, file_fh);
- if (conversion)
- free (result);
- if (write_len != res_len)
- { /* register error message instead? */
- fprintf (stderr,
- "ERROR: write to %s failed (%zu/%zu)\n",
- encoded_out_filepath, write_len, res_len);
- free (encoded_out_filepath);
- return -1;
- }
- output_files_register_closed
- (&self->output_files_information,
- encoded_out_filepath);
- if (fclose (file_fh))
- {
- message_list_document_error (
- &self->error_messages, self->conf, 0,
- "error on closing %s: %s",
- out_filepath, strerror (errno));
- free (encoded_out_filepath);
- return -1;
- }
- redirection_files_done++;
- }
+ status
+ = file_error_or_write_close (self, out_filepath,
+ encoded_out_filepath, file_fh,
+ conversion, redirection_page,
+ open_error_message);
+
free (encoded_out_filepath);
free (out_filepath);
free (redirection_page);
+ free (open_error_message);
+ if (status < 0)
+ return -1;
+ else
+ redirection_files_done++;
}
}
}