Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix [b601ce3ab1]: A corrupted image can cause resource exhaustion. Patch from Keith Nash. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-5-branch |
Files: | files | file ages | folders |
SHA1: |
f50a7fcd4ac5f0f51c21fcd55f71bc22 |
User & Date: | fvogel 2017-08-02 11:35:21 |
Context
2017-08-24
| ||
19:37 | Fix [cc42cc18a5]: Prevent the test suite from crashing when running tests imgPhoto-18.* in case the host machine runs out of memory and the memory allocation error is not returned (e.g. on FreeBSD 11.1) check-in: 55aa54e8 user: fvogel tags: core-8-5-branch | |
2017-08-02
| ||
12:00 | Fix [b601ce3ab1]: A corrupted image can cause resource exhaustion. Patch from Keith Nash. check-in: afcc283f user: fvogel tags: core-8-6-branch | |
11:35 | Fix [b601ce3ab1]: A corrupted image can cause resource exhaustion. Patch from Keith Nash. check-in: f50a7fcd user: fvogel tags: core-8-5-branch | |
11:32 | Removed constraint SegfaultOn8.5, this was useful before the fix was in the code, now it can be removed check-in: d8241803 user: fvogel tags: bug-b601ce3ab1 | |
2017-04-13
| ||
12:45 | (cherry-pick): Fixed bug [f0188aca9e] (color names parsing on Windows), by Simon Bachmann check-in: b9014666 user: jan.nijtmans tags: core-8-5-branch | |
Changes
Changes to generic/tkImgGIF.c.
︙ | ︙ | |||
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 | MFile *handle = (MFile *) chan; if (handle->length <= 0 || (size_t) handle->length < hunk*count) { return -1; } memcpy(dst, handle->data, (size_t) (hunk * count)); handle->data += hunk * count; return (int)(hunk * count); } /* * Otherwise we've got a real file to read. */ | > | 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 | MFile *handle = (MFile *) chan; if (handle->length <= 0 || (size_t) handle->length < hunk*count) { return -1; } memcpy(dst, handle->data, (size_t) (hunk * count)); handle->data += hunk * count; handle->length -= hunk * count; return (int)(hunk * count); } /* * Otherwise we've got a real file to read. */ |
︙ | ︙ |
Changes to generic/tkImgPhoto.c.
︙ | ︙ | |||
3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 | if (masterPtr->userWidth > 0) { width = masterPtr->userWidth; } if (masterPtr->userHeight > 0) { height = masterPtr->userHeight; } pitch = width * 4; /* * Test if we're going to (re)allocate the main buffer now, so that any * failures will leave the photo unchanged. */ if ((width != masterPtr->width) || (height != masterPtr->height) || (masterPtr->pix32 == NULL)) { /* * Not a u-long, but should be one. */ unsigned /*long*/ newPixSize = (unsigned /*long*/) (height * pitch); /* * Some mallocs() really hate allocating zero bytes. [Bug 619544] */ if (newPixSize == 0) { newPix32 = NULL; | > > > > > > > > | 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 | if (masterPtr->userWidth > 0) { width = masterPtr->userWidth; } if (masterPtr->userHeight > 0) { height = masterPtr->userHeight; } if (width > INT_MAX / 4) { /* Pitch overflows int */ return TCL_ERROR; } pitch = width * 4; /* * Test if we're going to (re)allocate the main buffer now, so that any * failures will leave the photo unchanged. */ if ((width != masterPtr->width) || (height != masterPtr->height) || (masterPtr->pix32 == NULL)) { /* * Not a u-long, but should be one. */ unsigned /*long*/ newPixSize = (unsigned /*long*/) (height * pitch); if (pitch && height > (int)(UINT_MAX / pitch)) { return TCL_ERROR; } /* * Some mallocs() really hate allocating zero bytes. [Bug 619544] */ if (newPixSize == 0) { newPix32 = NULL; |
︙ | ︙ | |||
3069 3070 3071 3072 3073 3074 3075 | * outside validBox, but they might be copied to another photo image * or written to a file. */ if ((masterPtr->pix32 != NULL) && ((width == masterPtr->width) || (width == validBox.width))) { if (validBox.y > 0) { | | | | | | | 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 | * outside validBox, but they might be copied to another photo image * or written to a file. */ if ((masterPtr->pix32 != NULL) && ((width == masterPtr->width) || (width == validBox.width))) { if (validBox.y > 0) { memset(newPix32, 0, ((size_t) validBox.y * pitch)); } h = validBox.y + validBox.height; if (h < height) { memset(newPix32 + h*pitch, 0, ((size_t) (height - h) * pitch)); } } else { memset(newPix32, 0, ((size_t) height * pitch)); } if (masterPtr->pix32 != NULL) { /* * Copy the common area over to the new array array and free the * old array. */ if (width == masterPtr->width) { /* * The region to be copied is contiguous. */ offset = validBox.y * pitch; memcpy(newPix32 + offset, masterPtr->pix32 + offset, ((size_t) validBox.height * pitch)); } else if ((validBox.width > 0) && (validBox.height > 0)) { /* * Area to be copied is not contiguous - copy line by line. */ destPtr = newPix32 + (validBox.y * width + validBox.x) * 4; srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width + validBox.x) * 4; for (h = validBox.height; h > 0; h--) { memcpy(destPtr, srcPtr, ((size_t) validBox.width * 4)); destPtr += width * 4; srcPtr += masterPtr->width * 4; } } ckfree((char *) masterPtr->pix32); } |
︙ | ︙ | |||
3262 3263 3264 3265 3266 3267 3268 | * Copy the common area over to the new array and free the old * array. */ if (masterPtr->width == instancePtr->width) { offset = validBox.y * masterPtr->width * 3; memcpy(newError + offset, instancePtr->error + offset, | | | 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 | * Copy the common area over to the new array and free the old * array. */ if (masterPtr->width == instancePtr->width) { offset = validBox.y * masterPtr->width * 3; memcpy(newError + offset, instancePtr->error + offset, ((size_t) validBox.height * masterPtr->width * 3 * sizeof(schar))); } else if (validBox.width > 0 && validBox.height > 0) { errDestPtr = newError + (validBox.y * masterPtr->width + validBox.x) * 3; errSrcPtr = instancePtr->error + (validBox.y * instancePtr->width + validBox.x) * 3; |
︙ | ︙ | |||
4415 4416 4417 4418 4419 4420 4421 | if ((blockPtr->pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) && (height <= blockPtr->height) && ((height == 1) || ((x == 0) && (width == masterPtr->width) && (blockPtr->pitch == pitch))) && (compRule == TK_PHOTO_COMPOSITE_SET)) { memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0], | | | 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 | if ((blockPtr->pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) && (height <= blockPtr->height) && ((height == 1) || ((x == 0) && (width == masterPtr->width) && (blockPtr->pitch == pitch))) && (compRule == TK_PHOTO_COMPOSITE_SET)) { memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0], ((size_t) height * width * 4)); /* * We know there's an alpha offset and we're setting the data, so skip * directly to the point when we recompute the photo validity region. */ goto recalculateValidRegion; |
︙ | ︙ | |||
4447 4448 4449 4450 4451 4452 4453 | * much faster. */ if ((pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) && compRuleSet) { | | | 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 | * much faster. */ if ((pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) && compRuleSet) { memcpy(destLinePtr, srcLinePtr, ((size_t) width * 4)); srcLinePtr += blockPtr->pitch; destLinePtr += pitch; continue; } /* * Have to copy the slow way. |
︙ | ︙ | |||
5421 5422 5423 5424 5425 5426 5427 | /* * Clear out the 32-bit pixel storage array. Clear out the dithering error * arrays for each instance. */ memset(masterPtr->pix32, 0, | | | | 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 | /* * Clear out the 32-bit pixel storage array. Clear out the dithering error * arrays for each instance. */ memset(masterPtr->pix32, 0, ((size_t) masterPtr->width * masterPtr->height * 4)); for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; instancePtr = instancePtr->nextPtr) { if (instancePtr->error) { memset(instancePtr->error, 0, ((size_t) masterPtr->width * masterPtr->height * 3 * sizeof(schar))); } } /* * Tell the core image code that this image has changed. */ |
︙ | ︙ |
Added tests/corruptMangled.gif.
> > | 1 2 | GIF89a�33��33�3�3�33����3���!� ,!x��-0Bw��ڥ���J�8U�kir/3Re7 ; |
Added tests/corruptMangled4G.gif.
> > | 1 2 | GIF89a�f3��33�3�3�33����3���!� ,!x��-0Bw��ڥ���J�8U�kir/3Re7 ; |
Added tests/corruptTruncated.gif.
cannot compute difference between binary files
Changes to tests/imgPhoto.test.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 | README -- Tk test suite design document. } README-imgPhoto] # find the teapot.ppm file for use in these tests set teapotPhotoFile [file join [file dirname [info script]] teapot.ppm] testConstraint hasTeapotPhoto [file exists $teapotPhotoFile] test imgPhoto-1.1 {options for photo images} { image create photo p1 -width 79 -height 83 list [lindex [p1 configure -width] 4] [lindex [p1 configure -height] 4] \ [image width p1] [image height p1] } {79 83 79 83} test imgPhoto-1.2 {options for photo images} { list [catch {image create photo p1 -file no.such.file} err] \ | > > > > > > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | README -- Tk test suite design document. } README-imgPhoto] # find the teapot.ppm file for use in these tests set teapotPhotoFile [file join [file dirname [info script]] teapot.ppm] testConstraint hasTeapotPhoto [file exists $teapotPhotoFile] proc base64ok {} { expr { ![catch {package require base64}] } } testConstraint base64PackageNeeded [base64ok] test imgPhoto-1.1 {options for photo images} { image create photo p1 -width 79 -height 83 list [lindex [p1 configure -width] 4] [lindex [p1 configure -height] 4] \ [image width p1] [image height p1] } {79 83 79 83} test imgPhoto-1.2 {options for photo images} { list [catch {image create photo p1 -file no.such.file} err] \ |
︙ | ︙ | |||
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | test imgPhoto-16.1 {copying to self doesn't access freed memory} { # Bug 877950 makes this crash when trying to copy out of a deallocated area set i [image create photo] $i put red -to 0 0 1000 1000 $i copy $i -from 0 0 1000 1000 -to 500 0 image delete $i } {} destroy .c eval image delete [image names] # cleanup removeFile README-imgPhoto cleanupTests return | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | test imgPhoto-16.1 {copying to self doesn't access freed memory} { # Bug 877950 makes this crash when trying to copy out of a deallocated area set i [image create photo] $i put red -to 0 0 1000 1000 $i copy $i -from 0 0 1000 1000 -to 500 0 image delete $i } {} # Reject corrupted or truncated image [Bug b601ce3ab1]. # WARNING - tests 18.1-18.9 will cause a segfault on 8.5.19 and lower, # and on 8.6.6 and lower. test imgPhoto-18.1 {Reject corrupted GIF (binary string)} -constraints { base64PackageNeeded } -setup { package require base64 set data [base64::decode { R0lGODlhwjMz//8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV 5qpraXIvM1JlNyAgOw== }] } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp test imgPhoto-18.2 {Reject corrupted GIF (base 64 string)} -setup { set data { R0lGODlhwjMz//8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV 5qpraXIvM1JlNyAgOw== } } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp test imgPhoto-18.3 {Reject corrupted GIF (file)} -setup { set fileName [file join [file dirname [info script]] corruptMangled.gif] } -body { image create photo gif1 -file $fileName } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp test imgPhoto-18.4 {Reject truncated GIF (binary string)} -constraints { base64PackageNeeded } -setup { package require base64 set data [base64::decode { R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8= }] } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map} test imgPhoto-18.5 {Reject truncated GIF (base 64 string)} -setup { set data { R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8= } } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map} test imgPhoto-18.6 {Reject truncated GIF (file)} -setup { set fileName [file join [file dirname [info script]] corruptTruncated.gif] } -body { image create photo gif1 -file $fileName } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map} test imgPhoto-18.7 {Reject corrupted GIF (> 4Gb) (binary string)} -constraints { base64PackageNeeded } -setup { package require base64 set data [base64::decode { R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw== }] } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp test imgPhoto-18.8 {Reject corrupted GIF (> 4Gb) (base 64 string)} -setup { set data { R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw== } } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp test imgPhoto-18.9 {Reject corrupted GIF (> 4Gb) (file)} -setup { set fileName [file join [file dirname [info script]] corruptMangled4G.gif] } -body { image create photo gif1 -file $fileName } -cleanup { catch {image delete gif1} } -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp test imgPhoto-18.10 {Valid GIF (binary string)} -constraints { base64PackageNeeded } -setup { # Test the binary string reader with a valid GIF. # This is not tested elsewhere. # Tests 18.11, 18.12, with matching data, are included for completeness. package require base64 set data [base64::decode { R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs= }] } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -result gif1 test imgPhoto-18.11 {Valid GIF (base 64 string)} -setup { set data { R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs= } } -body { image create photo gif1 -data $data } -cleanup { catch {image delete gif1} } -result gif1 test imgPhoto-18.12 {Valid GIF (file)} -setup { set fileName [file join [file dirname [info script]] red.gif] } -body { image create photo gif1 -file $fileName } -cleanup { catch {image delete gif1} } -result gif1 destroy .c eval image delete [image names] # cleanup removeFile README-imgPhoto cleanupTests return |
Added tests/red.gif.
cannot compute difference between binary files