importer: convert different file encodings to UTF-8

Files that aren't in the UTF-8 encoding were breaking the import dialog.
This tries to guess the encoding of the file before processing it, based
on the Byte Order Mark (BOM), and converts it to UTF-8.

Fixes #1243
This commit is contained in:
Otávio Silva
2024-11-05 21:10:29 +00:00
committed by Georges Basile Stavracas Neto
parent 0936b498e2
commit 98ced271ef
+45
View File
@@ -19,6 +19,7 @@
*/
#include "gcal-importer.h"
#include "gcal-debug.h"
#include <glib/gi18n.h>
@@ -57,6 +58,22 @@ i_cal_error_enum_to_string (ICalErrorEnum ical_error)
}
}
static const gchar*
guess_file_encoding (const gchar *contents,
gsize length)
{
if (length > 4 && contents[0] == '\xFF' && contents[1] == '\xFE' && contents[2] == '\x00' && contents[3] == '\x00') /* UTF-32LE case */
return "UTF-32LE";
else if (length > 4 && contents[0] == '\x00' && contents[1] == '\x00' && contents[2] == '\xFE' && contents[3] == '\xFF') /* UTF-32BE case */
return "UTF-32BE";
else if (length > 2 && contents[0] == '\xFF' && contents[1] == '\xFE') /* UTF-16LE case */
return "UTF-16LE";
else if (length > 2 && contents[0] == '\xFE' && contents[1] == '\xFF') /* UTF-16BE case */
return "UTF-16BE";
return "UTF-8";
}
static void
read_file_in_thread (GTask *task,
gpointer source_object,
@@ -67,6 +84,7 @@ read_file_in_thread (GTask *task,
g_autoptr (GError) error = NULL;
g_autofree gchar *contents = NULL;
g_autofree gchar *path = NULL;
g_autofree gchar *encoding = NULL;
ICalComponent *component;
ICalErrorEnum ical_error;
gsize length;
@@ -104,6 +122,33 @@ read_file_in_thread (GTask *task,
return;
}
encoding = g_strdup (guess_file_encoding (contents, length));
if (g_strcmp0 (encoding, "UTF-8") != 0)
{
g_autofree gchar *content_converted = NULL;
gsize new_length;
GCAL_TRACE_MSG ("Converting file from %s to UTF-8", encoding);
content_converted = g_convert (contents, length, "UTF-8", encoding, NULL, &new_length, &error);
if (error)
{
g_task_return_error (task, g_steal_pointer (&error));
return;
}
g_clear_pointer (&contents, g_free);
contents = g_steal_pointer (&content_converted);
length = new_length;
}
if (!g_utf8_validate (contents, length, NULL)) /* validate UTF-8 */
{
GCAL_TRACE_MSG ("File encoding cannot be validated as UTF-8");
}
component = i_cal_parser_parse_string (contents);
ical_error = i_cal_errno_return ();