Tk Source Code

Check-in [0101cd3f]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a bug also present in standard Tk: Trailing segments of image data are not skipped, final 0 byte is not skipped, -index over 1 should not work IMHO.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-529-image-metadata
Files: files | file ages | folders
SHA3-256: 0101cd3f328259414c920f9af83dfa7c681103ead91ef3898065238b80d784bc
User & Date: oehhar 2019-02-01 18:15:55
Context
2019-02-01
18:27
Correct metadata ref counting to be cleared in the error case. check-in: fbbe3b6e user: oehhar tags: tip-529-image-metadata
18:15
Fix a bug also present in standard Tk: Trailing segments of image data are not skipped, final 0 byte is not skipped, -index over 1 should not work IMHO. check-in: 0101cd3f user: oehhar tags: tip-529-image-metadata
2018-12-19
11:18
TIP529: option -metadata is now dict. Test crash apparently fixed by trunk merge check-in: 9f5d05d9 user: oehhar tags: tip-529-image-metadata
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkImgGIF.c.

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
....
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
....
1373
1374
1375
1376
1377
1378
1379


















1380
1381
1382
1383
1384
1385
1386
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */

    /*
     * Read final zero
     */
    if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {
        goto error;
    }
    if (gifLabel != '\0') {
	/*
	 * Premature end of image.
	 */

	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no image data termination", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END",
		NULL);
	goto error;
    }
    while (1) {
	if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {
	    goto error;
	}
	switch (gifLabel) {
	case GIF_TERMINATOR:
	    break;
................................................................................
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    int srcX, int srcY,
    int interlace,
    int transparent)
{
    unsigned char initialCodeSize;
    int xpos = 0, ypos = 0, pass = 0, i;
    register unsigned char *pixelPtr;
    static const int interlaceStep[] = { 8, 8, 4, 2 };
    static const int interlaceStart[] = { 0, 4, 2, 1 };
    unsigned short prefix[(1 << MAX_LWZ_BITS)];
    unsigned char append[(1 << MAX_LWZ_BITS)];
    unsigned char stack[(1 << MAX_LWZ_BITS)*2];
    register unsigned char *top;
................................................................................
		}
		ypos = interlaceStart[pass];
	    }
	} else {
	    ypos++;
	}
	pixelPtr = imagePtr + (ypos) * len * ((transparent>=0)?4:3);


















    }
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







714
715
716
717
718
719
720

















721
722
723
724
725
726
727
....
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
....
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */


















    while (1) {
	if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {
	    goto error;
	}
	switch (gifLabel) {
	case GIF_TERMINATOR:
	    break;
................................................................................
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    int srcX, int srcY,
    int interlace,
    int transparent)
{
    unsigned char initialCodeSize;
    int xpos = 0, ypos = 0, pass = 0, i, count;
    register unsigned char *pixelPtr;
    static const int interlaceStep[] = { 8, 8, 4, 2 };
    static const int interlaceStart[] = { 0, 4, 2, 1 };
    unsigned short prefix[(1 << MAX_LWZ_BITS)];
    unsigned char append[(1 << MAX_LWZ_BITS)];
    unsigned char stack[(1 << MAX_LWZ_BITS)*2];
    register unsigned char *top;
................................................................................
		}
		ypos = interlaceStart[pass];
	    }
	} else {
	    ypos++;
	}
	pixelPtr = imagePtr + (ypos) * len * ((transparent>=0)?4:3);
    }
    /*
     * Now read until the final zero byte.
     * It was observed that there might be 1 length blocks
     * (test imgPhoto-14.1) which are not read.
     *
     * The field "stack" is abused for temporary buffer. it has 4096 bytes
     * and we need 256.
     * 
     * Loop until we hit a 0 length block which is the end sign.
     */
    while ( 0 < (count = GetDataBlock(gifConfPtr, chan, stack)))
    {
	if (-1 == count ) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading GIF image: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkImgPhoto.c.

2207
2208
2209
2210
2211
2212
2213



2214
2215
2216
2217
2218
2219
2220
    }
    if (masterPtr->dataString != NULL) {
	Tcl_DecrRefCount(masterPtr->dataString);
    }
    if (masterPtr->format != NULL) {
	Tcl_DecrRefCount(masterPtr->format);
    }



    Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
    ckfree(masterPtr);
}
 
/*
 *----------------------------------------------------------------------
 *






>
>
>







2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
    }
    if (masterPtr->dataString != NULL) {
	Tcl_DecrRefCount(masterPtr->dataString);
    }
    if (masterPtr->format != NULL) {
	Tcl_DecrRefCount(masterPtr->format);
    }
    if (masterPtr->metadata != NULL) {
	Tcl_DecrRefCount(masterPtr->metadata);
    }
    Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
    ckfree(masterPtr);
}
 
/*
 *----------------------------------------------------------------------
 *