summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Miika Turkia <miika.turkia@gmail.com>2020-02-04 09:18:37 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2020-02-06 08:46:52 -0800
commit90b0e38ed801e2bab49746a2a961c6012f2906e1 (patch)
treebe2078db9307170706c50ed84f4ffe6dfd8059c1 /core
parent550ec3410147aac77a67cff4644c088d9c4fa132 (diff)
downloadsubsurface-90b0e38ed801e2bab49746a2a961c6012f2906e1.tar.gz
CSV import: fix importing ampersand character
As we do XSLT parsing for the CSV import, ampersand characters need to be encoded with &amp; for the parsing to succeed. Fixes #2037 Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
Diffstat (limited to 'core')
-rw-r--r--core/import-csv.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/core/import-csv.c b/core/import-csv.c
index 0255b4f7d..83229331c 100644
--- a/core/import-csv.c
+++ b/core/import-csv.c
@@ -351,16 +351,26 @@ int parse_csv_file(const char *filename, char **params, int pnr, const char *csv
static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, const char *tag)
{
char *buf;
+ size_t i, amp = 0, rest = 0;
if (mem->size == 0 && readfile(filename, mem) < 0)
return report_error(translate("gettextFromC", "Failed to read '%s'"), filename);
+ /* Count ampersand characters */
+ for (i = 0; i < mem->size; ++i) {
+ if (((char *)mem->buffer)[i] == '&') {
+ ++amp;
+ }
+ }
+
+
/* Surround the CSV file content with XML tags to enable XSLT
* parsing
*
* Tag markers take: strlen("<></>") = 5
+ * Reserve also room for encoding ampersands "&" => "&amp;"
*/
- buf = realloc(mem->buffer, mem->size + 7 + strlen(tag) * 2);
+ buf = realloc(mem->buffer, mem->size + 7 + strlen(tag) * 2 + amp * 4);
if (buf != NULL) {
char *starttag = NULL;
char *endtag = NULL;
@@ -389,6 +399,16 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, cons
free(starttag);
free(endtag);
+
+ /* Expand ampersands to encoded version */
+ for (i = mem->size, rest = 0; i > 0; --i, ++rest) {
+ if (((char *)mem->buffer)[i] == '&') {
+ memmove(((char *)mem->buffer) + i + 4 + 1, ((char *)mem->buffer) + i + 1, rest);
+ memcpy(((char *)mem->buffer) + i + 1, "amp;", 4);
+ rest += 4;
+ mem->size += 4;
+ }
+ }
} else {
free(mem->buffer);
return report_error("realloc failed in %s", __func__);