From 0bafdf1a04920fd3bbcbe1a40f3455ea194831d9 Mon Sep 17 00:00:00 2001 From: oehhar Date: Mon, 16 Nov 2020 13:27:13 +0000 Subject: Ticket [d6e9b4db4]: Image format SVG: memory overflow on big files: Alternate solution from Androwish: : http://www.androwish.org/index.html/vinfo/a9be9dd0259e47f0?diff=1 --- generic/tkImgSVGnano.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/generic/tkImgSVGnano.c b/generic/tkImgSVGnano.c index 4cdb648..61db86b 100644 --- a/generic/tkImgSVGnano.c +++ b/generic/tkImgSVGnano.c @@ -52,6 +52,8 @@ typedef struct { RastOpts ropts; } NSVGcache; +static const void * MemMem(const void *haystack, size_t haysize, + const void *needle, size_t needlen); static int FileMatchSVG(Tcl_Channel chan, const char *fileName, Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp); @@ -101,6 +103,46 @@ Tk_PhotoImageFormat tkImgFmtSVGnano = { /* *---------------------------------------------------------------------- * + * MemMem -- + * + * Like strstr() but operating on memory buffers with sizes. + * + *---------------------------------------------------------------------- + */ + +static const void * +MemMem(const void *haystack, size_t haylen, + const void *needle, size_t needlen) +{ + const void *hayend, *second, *p; + unsigned char first; + + if ((needlen <= 0) || (haylen < needlen)) { + return NULL; + } + hayend = (const void *) ((char *) haystack + haylen - needlen); + first = ((char *) needle)[0]; + second = (const void *) ((char *) needle + 1); + needlen -= 1; + while (haystack < hayend) { + p = memchr(haystack, first, (char *) hayend - (char *) haystack); + if (p == NULL) { + break; + } + if (needlen == 0) { + return p; + } + haystack = (const void *) ((char *) p + 1); + if (memcmp(second, haystack, needlen) == 0) { + return p; + } + } + return NULL; +} + +/* + *---------------------------------------------------------------------- + * * FileMatchSVG -- * * This function is invoked by the photo image type to see if a file @@ -132,12 +174,24 @@ FileMatchSVG( (void)fileName; CleanCache(interp); - if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) { + if (Tcl_ReadChars(chan, dataObj, 4096, 0) == TCL_IO_FAILURE) { /* in case of an error reading the file */ Tcl_DecrRefCount(dataObj); return 0; } data = TkGetStringFromObj(dataObj, &length); + /* should have a '' in the first 4k */ + if ((memchr(data, '>', length) == NULL) || + (MemMem(data, length, "' in the first 4k */ + testLength = (length > 4096) ? 4096 : length; + if ((memchr(data, '>', testLength) == NULL) || + (MemMem(data, testLength, " Date: Sat, 21 Nov 2020 09:51:21 +0000 Subject: Add test imgSVGnano-5.2 (and do some reformatting of the test file since we are here) - The important thing this test is ckecking is that image data not containing now return an error upon reading as svg images. The expected result of the test matches the current output but is not adequate. The returned error text should be improved. --- tests/imgSVGnano.test | 54 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/tests/imgSVGnano.test b/tests/imgSVGnano.test index e2789c2..797ff69 100644 --- a/tests/imgSVGnano.test +++ b/tests/imgSVGnano.test @@ -12,20 +12,23 @@ tcltest::loadTestedCommands imageInit namespace eval svgnano { + variable data - set data(plus) { - - - - - - - - -} - set data(bad) { -} + + set data(plus) {\ + + + + + + + + + + } + set data(bad) { + \ + } tcltest::makeFile $data(plus) plus.svg set data(plusFilePath) [file join [tcltest::configure -tmpdir] plus.svg] @@ -33,6 +36,7 @@ namespace eval svgnano { tcltest::makeFile $data(bad) bad.svg set data(badFilePath) [file join [tcltest::configure -tmpdir] bad.svg] + test imgSVGnano-1.1 {reading simple image} -setup { catch {rename foo ""} } -body { @@ -72,6 +76,7 @@ test imgSVGnano-1.4 {image options} -setup { } -cleanup { rename foo "" } -result {100 100} + test imgSVGnano-1.5 {reading simple image from file} -setup { catch {rename foo ""} } -body { @@ -80,8 +85,7 @@ test imgSVGnano-1.5 {reading simple image from file} -setup { } -cleanup { rename foo "" } -result {100 100} - -test imgSVGnano-1.6 {simple image with options} -setup { +test imgSVGnano-1.6 {simple image from file with options} -setup { catch {rename foo ""} } -body { image create photo foo -file $data(plusFilePath) -format {svg -dpi 100 -scale 3} @@ -89,14 +93,15 @@ test imgSVGnano-1.6 {simple image with options} -setup { } -cleanup { rename foo "" } -result {300 300} -test imgSVGnano-1.7 {Very small scale gives 1x1 image} -body { + +test imgSVGnano-1.7 {very small scale gives 1x1 image} -body { image create photo foo -format "svg -scale 0.000001"\ -data $data(plus) list [image width foo] [image height foo] } -cleanup { rename foo "" } -result {1 1} -test imgSVGnano-1.8 {Very small scale gives 1x1 image from file} -body { +test imgSVGnano-1.8 {very small scale gives 1x1 image, from file} -body { image create photo foo -format "svg -scale 0.000001"\ -file $data(plusFilePath) list [image width foo] [image height foo] @@ -152,7 +157,7 @@ test imgSVGnano-3.6 {no number parameter to -scaletoheight} -body { -data $data(plus) } -returnCodes error -result {expected integer but got "invalid"} -test imgSVGnano-3.7 {Option -scaletowidth} -body { +test imgSVGnano-3.7 {option -scaletowidth} -body { image create photo foo -format "svg -scaletowidth 20"\ -data $data(plus) image width foo @@ -160,7 +165,7 @@ test imgSVGnano-3.7 {Option -scaletowidth} -body { rename foo "" } -result 20 -test imgSVGnano-3.8 {Option -scaletoheight} -body { +test imgSVGnano-3.8 {option -scaletoheight} -body { image create photo foo -format "svg -scaletoheight 20"\ -data $data(plus) image height foo @@ -194,7 +199,6 @@ test imgSVGnano-4.1 {reread file on configure -scale} -setup { unset res } -result {100 100 200 200} - test imgSVGnano-4.2 {error on file not accessible on reread due to configure} -setup { catch {rename foo ""} tcltest::makeFile $data(plus) tmpplus.svg @@ -235,6 +239,16 @@ test imgSVGnano-5.1 {bug ea665e08f3 - too many values in parameters of the trans rename foo "" } -result {foo} +test imgSVGnano-5.2 {bug d6e9b4db40 - "" must be present} -body { + image create photo foo -data\ + {\ + \ + \ + } +} -returnCodes error -result {list element in quotes followed by "http://www.w3.org/TR" instead of space} + };# end of namespace svgnano namespace delete svgnano -- cgit v0.12 From e1794e48e6de8014d805235dfcbb20867fe7457f Mon Sep 17 00:00:00 2001 From: fvogel Date: Sat, 21 Nov 2020 13:02:42 +0000 Subject: Specify the format in test imgSVGnano-5.2, so that the error message does not stem from the default image format stringMatchProc and is now correct. --- tests/imgSVGnano.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/imgSVGnano.test b/tests/imgSVGnano.test index 797ff69..1dad3a5 100644 --- a/tests/imgSVGnano.test +++ b/tests/imgSVGnano.test @@ -240,14 +240,14 @@ test imgSVGnano-5.1 {bug ea665e08f3 - too many values in parameters of the trans } -result {foo} test imgSVGnano-5.2 {bug d6e9b4db40 - "" must be present} -body { - image create photo foo -data\ + image create photo foo -format svg -data\ {\ \ \ } -} -returnCodes error -result {list element in quotes followed by "http://www.w3.org/TR" instead of space} +} -returnCodes error -result {couldn't recognize image data} };# end of namespace svgnano -- cgit v0.12