diff options
author | rofl0r <retnyg@gmx.net> | 2012-12-25 06:03:24 +0100 |
---|---|---|
committer | rofl0r <retnyg@gmx.net> | 2012-12-25 06:03:48 +0100 |
commit | 92e039f526ef7988a9b8cf500fd45a3a5b045ced (patch) | |
tree | eb6f9945eec57d64c0eaf0c2cc885e5acf4311c2 /src/msgmerge.c | |
parent | ddf6dfea27f4a7d57ed73a4f5a146b6b704e9103 (diff) | |
download | gettext-tiny-92e039f526ef7988a9b8cf500fd45a3a5b045ced.tar.gz |
fix assertion error on huge string found in gnumericv0.0.2
the culprit is:
gnumeric-1.10.17/po-functions/dz.po
basically the code was wrongly checking for the end of the convert
buffer, instead of the line buffer.
this is no problem per se because the line buffer gets reset more
often, but when the convertbuffer is bigger (like after this change)
it wouldnt work correctly.
i put the convert_buf functions into a separate translation unit
and renamed them to escape and unescape to make it more clear
what they're doing. also new: size checks for the escape functions.
currently it will silently truncate the strings when the buffer
runs out of space. this is sufficient for no-op style, but should
be fixed at some point.
Diffstat (limited to 'src/msgmerge.c')
-rw-r--r-- | src/msgmerge.c | 60 |
1 files changed, 3 insertions, 57 deletions
diff --git a/src/msgmerge.c b/src/msgmerge.c index 15a3e2e..977f168 100644 --- a/src/msgmerge.c +++ b/src/msgmerge.c @@ -6,6 +6,7 @@ #include <ctype.h> #include <assert.h> #include "poparser.h" +#include "StringEscape.h" __attribute__((noreturn)) static void syntax(void) { @@ -37,61 +38,6 @@ struct fiLes { FILE *compend; }; -size_t convert_buf(char* in, char* out) { - size_t l = 0; - while(*in) { - switch(*in) { - case '\n': - *out++ = '\\'; - l++; - *out = 'n'; - break; - case '\r': - *out++ = '\\'; - l++; - *out = 'r'; - break; - case '\t': - *out++ = '\\'; - l++; - *out = 't'; - break; - case '\\': - *out++ = '\\'; - l++; - *out = '\\'; - break; - case '"': - *out++ = '\\'; - l++; - *out = '"'; - break; - case '\v': - *out++ = '\\'; - l++; - *out = '\v'; - break; - case '\?': - *out++ = '\\'; - l++; - *out = '\?'; - break; - case '\f': - *out++ = '\\'; - l++; - *out = '\f'; - break; - default: - *out = *in; - } - in++; - out++; - l++; - } - *out = 0; - return l; -} - /* currently we only output input strings as output strings * i.e. there is no translation lookup at all */ int process_line_callback(struct po_info* info, void* user) { @@ -99,7 +45,7 @@ int process_line_callback(struct po_info* info, void* user) { FILE* out = (FILE*) user; size_t l; if(info->type == pe_msgid) { - l = convert_buf(info->text, convbuf); + l = escape(info->text, convbuf, sizeof(convbuf)); fprintf(out, "msgid \"%s\"\nmsgstr \"%s\"\n", convbuf, convbuf); } return 0; @@ -108,7 +54,7 @@ int process_line_callback(struct po_info* info, void* user) { int process(struct fiLes *files, int update, int backup) { (void) update; (void) backup; struct po_parser pb, *p = &pb; - char line[4096], conv[4096], *lb; + char line[4096], conv[8192], *lb; poparser_init(p, conv, sizeof(conv), process_line_callback, files->out); while((lb = fgets(line, sizeof(line), files->pot))) { poparser_feed_line(p, lb, sizeof(line) - (size_t)(lb - line)); |