diff options
author | Miika Turkia <miika.turkia@gmail.com> | 2020-02-04 09:18:37 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2020-02-06 08:46:52 -0800 |
commit | 90b0e38ed801e2bab49746a2a961c6012f2906e1 (patch) | |
tree | be2078db9307170706c50ed84f4ffe6dfd8059c1 /core | |
parent | 550ec3410147aac77a67cff4644c088d9c4fa132 (diff) | |
download | subsurface-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 & 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.c | 22 |
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 "&" => "&" */ - 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__); |