Currently if your image history includes an
image with a long name, the Welcome
Dialog will stretch out to match its width.
If the color profile name is long, then the
color scales will also stretch out due to
the profile label.
This patch adds ellipses to the Welcome
Dialog and a scrollwindow to the
ColorScales to prevent this.
Ported from ca5688bf6d
Just to note, we are already not using Assembly code
in 10bit and 12bit libraries. So, no feature dropped.
---
Also, little fixes to some dev docs regarding Clang.
Unlike GIMP, Photoshop does not support indexed images with
multiple layers. We have been silently merging layers down when
exporting to PSD, but this may be confusing to users.
This patch adds a label that notifies the user if they export an
indexed image with more than one layer.
...based on icon size preferences.
Inspired by Mark Sweeney's work.
Since the icon size is based on a formula,
the CSS value determines the maximum
size rather than being used directly.
Needs backport to 2.10
gimp_dock_windows_constructed creates a GimpDockColumns, a child widget,
and keeps a private reference to it at dock_window->p->dock_columns.
Then it connects the signal dock_columns.doc_removed to two callbacks:
gimp_dock_window_dock_removed() and gimp_dock_window_update_title().
gimp_dock_window_dock_removed() callback is called first and can
destroy the GimpDockWindow widget and its child widget GimpDockColumns.
Then gimp_dock_window_update_title is called
and tries to call dock_window->p->dock_columns.get_docks()
but it is already destroyed.
The fix is to nullify the internal pointer to dock_columns when destroyed,
and encapsulate access to dock_columns.get_docks so that it
returns a valid but empty list when dock_columns has already been destroyed.
Alternatively, you might be able to fix it by rearranging the order
of connections to dock-removed signal, but then the title would be wrong.
Another alternative might be to rethink the whole destruction sequence.
The ARTIFACTS_SUFFIX is being dropped on building scripts because:
1) This will make possible to further simplify Installer scripts in other commit
2) There is no script that uses multi-arch _build/_install at same time on CI
However, there are two use cases: to build Debian and flatpak; and, on Win,
to build on CLANGARM64 and CLANG64 (?). But probably they are pretty niche.
I suppose that people who build on Debian (or other dev-oriented distro)
willn't want to mantain deps in two sys prefixes (pkg and GNOME runtime)
+ two gimp prefixes (out of sandbox and sandbox) due to huge storage use.
Why someone would want to build with emulation on Win ARM64 I don't know.
Anyway, people that know how to do this stuff probably can change the .sh.
3) When building locally, the contributor doesn't need to know the arch at all.
Indeed, without this suffix, the scripts are inline with gimp-web-devel and
prevent some first-sight confusion when reading them that I've seen on IRC.
4) These arch suffixes can be understood as '_install-*' being distributable
which is not true. So, without this suffix we could make more clear
what is a package (when GitLab fix the glob bug in 'expose_as' someday).
---
Despite .gitlab-ci.yml not being a script, it needed to be touched too
because cross scripts depends on Debian jobs due to gimp-data MR.
If a given layer's properties contain multiple PROP_ACTIVE_LAYER entries, we
could add multiple entries for the same layer in info->selected_layers.
However, xcf_load_layer_props and xcf_load_layer both contain logic that
overwrites the layer pointer - they do take care of updating
info->selected_layers and and info->floating_sel (both of which could contain
or point to the current layer). Crucially, they both assume that
info->selected_layers can only contain this layer once - hence they only
remove it from the list once. This logic also frees the old layer because it
thinks that it's no longer in use.
But if we've added the original layer to selected_layers multiple times,
and then use the logic that overwrites layer, selected_layers will still
contain an invalid pointer to the now-freed original layer. Any later
code that tries to read info->selected_layers will hit a user-after-free.
Therefore we need to check if the current layer is already in the
selected_layers list, and avoid adding it again if it's already there.
(It also seems illogical to say that a layer is selected twice, but I'm
focusing on the code-correctness aspect in my analysis.)
Adjustment by Jacob Boerema: the correct way to test that a value does
not exist in a list is to check for the value being negative. Also add
a message to warn users.
ASAN output:
==21241==ERROR: AddressSanitizer: heap-use-after-free on address 0x615000012150 at pc 0x000000d54dbf bp 0x7ffcf813bb60 sp 0x7ffcf813bb58
READ of size 8 at 0x615000012150 thread T0
#0 0xd54dbe in gimp_image_set_selected_layers /home/ahunt/git/gimp/app/core/gimpimage.c:4743:7
#1 0xb146c6 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:690:7
#2 0xb1199b in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19
#3 0x619cad in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:35:17
#4 0x51d2e4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#5 0x506f62 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6
#6 0x50d2d0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:856:9
#7 0x537322 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#8 0x7f064a594349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#9 0x4e06f9 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
0x615000012150 is located 336 bytes inside of 504-byte region [0x615000012000,0x6150000121f8)
freed by thread T0 here:
#0 0x5e84e2 in free /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:127:3
#1 0x7f064b3f81c8 in g_free (/usr/lib64/libglib-2.0.so.0+0x581c8)
#2 0x7f064b41133f in g_slice_free1 (/usr/lib64/libglib-2.0.so.0+0x7133f)
#3 0x7f064b7015c0 in g_type_free_instance /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gtype.c:1946
#4 0xb187d8 in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2146:3
#5 0xb13997 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:504:15
#6 0xb1199b in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19
#7 0x619cad in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:35:17
#8 0x51d2e4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#9 0x506f62 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6
#10 0x50d2d0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:856:9
#11 0x537322 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#12 0x7f064a594349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#13 0x4e06f9 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
previously allocated by thread T0 here:
#0 0x5e874d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7f064b3f80c8 in g_malloc (/usr/lib64/libglib-2.0.so.0+0x580c8)
#2 0x7f064b410da5 in g_slice_alloc (/usr/lib64/libglib-2.0.so.0+0x70da5)
#3 0x7f064b411258 in g_slice_alloc0 (/usr/lib64/libglib-2.0.so.0+0x71258)
#4 0x7f064b7011d5 in g_type_create_instance /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gtype.c:1849
#5 0x7f064b6e164f in g_object_new_internal /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gobject.c:1827
#6 0x7f064b6e354d in g_object_new_valist /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gobject.c:2152
#7 0x7f064b6e38c8 in g_object_new /usr/src/debug/glib2-2.62.6-lp152.2.3.1.x86_64/build/../gobject/gobject.c:1670
#8 0xdb5b90 in gimp_item_new /home/ahunt/git/gimp/app/core/gimpitem.c:723:10
#9 0xce0358 in gimp_drawable_new /home/ahunt/git/gimp/app/core/gimpdrawable.c:1067:14
#10 0xddd8db in gimp_layer_new /home/ahunt/git/gimp/app/core/gimplayer-new.c:65:11
#11 0xb182a6 in xcf_load_layer /home/ahunt/git/gimp/app/xcf/xcf-load.c:2027:11
#12 0xb13997 in xcf_load_image /home/ahunt/git/gimp/app/xcf/xcf-load.c:504:15
#13 0xb1199b in xcf_load_stream /home/ahunt/git/gimp/app/xcf/xcf.c:305:19
#14 0x619cad in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/app/fuzzers/xcf_fuzzer.c:35:17
#15 0x51d2e4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#16 0x506f62 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:323:6
#17 0x50d2d0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:856:9
#18 0x537322 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#19 0x7f064a594349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#20 0x4e06f9 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
SUMMARY: AddressSanitizer: heap-use-after-free /home/ahunt/git/gimp/app/core/gimpimage.c:4743:7 in gimp_image_set_selected_layers
Shadow bytes around the buggy address:
0x0c2a7fffa3d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fffa3e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fffa3f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2a7fffa400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fffa410: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c2a7fffa420: fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd
0x0c2a7fffa430: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
0x0c2a7fffa440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2a7fffa450: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fffa460: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fffa470: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==21241==ABORTING
( crash-f37f84bd7072e65348ca0e2c920d1e08165356fd )
Inspired by Mark Sweeney's work.
GimpToolPresetEditor has an icon next to its title which does
not react to icon size changes.
GimpToolPresetEditor's parent_instance, GimpEditor, already
has a "button-icon-size" CSS style which can be accessed in
its children. This patch adds signals to listen for icon size
changes and update the icon size accordingly.
Resolves#9105
The XCF compression setting is initially
set to FALSE. It was only updated from the
Save Dialog, so if the user exports then
compression is reset if they save the XCF
again.
This patch adds a condition on export
where we get the image's compression
setting, instead of always defaulting to
FALSE. This allows you to save and export
the same image without having to
re-enable the compression setting each
time.
A follow-up to the previous commits, that address the tga issues from
issue #11822.
On Windows, when using the error console for messages, a huge amount
of error messages, that can be generated with special fuzzed images,
like crash-f65fd5404bff32c1d9d10ee049d9c98d02bbbdc2.tga from
the above mentioned issue, can cause GIMP to crash.
Although this is most likely caused in the error console or its
dependencies, we should not let it cause problems here until that is
fixed. There is also no real need to generate a huge amount of similar
repeated error messages, so let's limit it to 10 per read line of input.
We are trying to copy all bytes in the current row, which is the width times
the number of bytes per pixel (stored in info->bytes), not width times bits
per pixel.
Copying too much data allows certain inputs to induce a heap-buffer-buffer
overflow read, and probably also a write, see ASAN output below:
ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61d000008088 at pc 0x00000052be17 bp 0x7ffd8bbe8e20 sp 0x7ffd8bbe85e8
READ of size 16448 at 0x61d000008088 thread T0
#0 0x52be16 in __asan_memcpy /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
#1 0x5641ca in read_line /home/ahunt/git/gimp/plug-ins/common/file-tga.c:982:7
#2 0x560218 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1147:15
#3 0x55f526 in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:646:11
#4 0x56519b in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17
#5 0x461624 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#6 0x460b2a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#7 0x462ec4 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:814:7
#8 0x4630d9 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:845:3
#9 0x451686 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#11 0x7fdbd277c349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#12 0x424a39 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
0x61d000008088 is located 0 bytes to the right of 2056-byte region [0x61d000007880,0x61d000008088)
allocated by thread T0 here:
#0 0x52ca8d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7fdbd37fccf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13
#2 0x56009b in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1134:10
#3 0x55f526 in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:646:11
#4 0x56519b in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17
#5 0x461624 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#6 0x460b2a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#7 0x462ec4 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:814:7
#8 0x4630d9 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:845:3
#9 0x451686 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#11 0x7fdbd277c349 in __libc_start_main (/lib64/libc.so.6+0x24349)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
Shadow bytes around the buggy address:
0x0c3a7fff8fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3a7fff8fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3a7fff8fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3a7fff8ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3a7fff9000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c3a7fff9010: 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3a7fff9020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3a7fff9030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3a7fff9040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3a7fff9050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3a7fff9060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==26560==ABORTING
crash-4b13aca1db7bb795a815431b86cc20284f3aa6da
A malformed colourmapped tga file could specify color IDs that are not
contained in the colourmap. Therefore we add some bounds checking to
ensure that we only use entries that actually exist.
We could completely give up on such files, but it's just as easy to fall
back to the first colour in the map in this case. However we can only
fall back to the first colour in the map IF the colourmap contains
at least one entry. Therefore we add an up-front check to verify that
colourmapped images actually do contain at least one entry.
Without this bounds-checking, it's possible to induce a heap-buffer-overflow
read in apply-colormap(), see ASAN output below:
ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61900002257c at pc 0x000000564f99 bp 0x7ffe65fdb040 sp 0x7ffe65fdb038
READ of size 1 at 0x61900002257c thread T0
#0 0x564f98 in apply_colormap /home/ahunt/git/gimp/plug-ins/common/file-tga.c:901:23
#1 0x56411a in read_line /home/ahunt/git/gimp/plug-ins/common/file-tga.c:975:7
#2 0x560648 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1202:15
#3 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11
#4 0x5653ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17
#5 0x461624 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#6 0x460b2a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#7 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
#8 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
#9 0x451686 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#11 0x7fe76a5dc349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#12 0x424a39 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
0x61900002257c is located 0 bytes to the right of 1020-byte region [0x619000022180,0x61900002257c)
allocated by thread T0 here:
#0 0x52ca8d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7fe76b65ccf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13
#2 0x55fdc6 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1049:26
#3 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11
#4 0x5653ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17
#5 0x461624 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#6 0x460b2a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#7 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
#8 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
#9 0x451686 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#11 0x7fe76a5dc349 in __libc_start_main (/lib64/libc.so.6+0x24349)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ahunt/git/gimp/plug-ins/common/file-tga.c:901:23 in apply_colormap
Shadow bytes around the buggy address:
0x0c327fffc450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fffc460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fffc470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fffc480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fffc490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c327fffc4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[04]
0x0c327fffc4b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fffc4c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fffc4d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fffc4e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fffc4f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==16309==ABORTING
( crash-f70628d4df7a65babc8e57d890425771a1d67e06 )
If the colourmap contains more than 256 items AND has alpha, it should always
be promoted to RGBA. Therefore we move the "if (info->alphaBits)" check into
the first if clause, to avoid accidentally demoting to RGB in this scenario.
Other parts of the tga parser assume that the destination array is RGBA
when alphaBits is not zero. For example, upsample() will always write 4 bytes
per pixel when alpha is set - (even if we only allocated 3 because we thought
we should use RGB). Erronously allocating only 3 bytes makes it easy to induce
a heap-buffer-overflow write, see ASAN output below. (apply_colormap makes the
same assumption and would probably do the same thing, but upsample is the
first location that we'd hit this issue.)
ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61700002ae00 at pc 0x000000563d97 bp 0x7ffde8677890 sp 0x7ffde8677888
WRITE of size 1 at 0x61700002ae00 thread T0
#0 0x563d96 in upsample /home/ahunt/git/gimp/plug-ins/common/file-tga.c:830:15
#1 0x560b59 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c
#2 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11
#3 0x5652ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17
#4 0x461624 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#5 0x460b2a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#6 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
#7 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
#8 0x451686 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#9 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#10 0x7fd894a94349 in __libc_start_main (/lib64/libc.so.6+0x24349)
#11 0x424a39 in _start /home/abuild/rpmbuild/BUILD/glibc-2.26/csu/../sysdeps/x86_64/start.S:120
0x61700002ae00 is located 0 bytes to the right of 768-byte region [0x61700002ab00,0x61700002ae00)
allocated by thread T0 here:
#0 0x52ca8d in malloc /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7fd895b14cf2 in g_malloc /home/ahunt/git/glib/_build/../glib/gmem.c:106:13
#2 0x55fce9 in ReadImage /home/ahunt/git/gimp/plug-ins/common/file-tga.c:1039:26
#3 0x55f4ee in load_image /home/ahunt/git/gimp/plug-ins/common/file-tga.c:647:11
#4 0x5652ab in LLVMFuzzerTestOneInput /home/ahunt/git/gimp/plug-ins/common/file-tga_fuzzer.c:69:17
#5 0x461624 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
#6 0x460b2a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
#7 0x462847 in fuzzer::Fuzzer::MutateAndTestOne() /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
#8 0x4633d5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
#9 0x451686 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
#10 0x47b662 in main /home/abuild/rpmbuild/BUILD/llvm-12.0.0.src/build/../projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#11 0x7fd894a94349 in __libc_start_main (/lib64/libc.so.6+0x24349)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ahunt/git/gimp/plug-ins/common/file-tga.c:830:15 in upsample
Shadow bytes around the buggy address:
0x0c2e7fffd570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c2e7fffd580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c2e7fffd590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c2e7fffd5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c2e7fffd5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c2e7fffd5c0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2e7fffd5d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e7fffd5e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e7fffd5f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e7fffd600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e7fffd610: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==12179==ABORTING
( crash-f65fd5404bff32c1d9d10ee049d9c98d02bbbdc2 )
We allow passing NULL gvalue for an empty GimpObjectArray, for convenience.
For example to plugin sel2path which doesn't use drawables.
But crossing the wire, create an empty GimpObjectArray
having an arbitrary type for elements.
Note that the widgets are still made
with GTK directly. The primary goal of this
initial port is to remove the last usage of
gimp_export_dialog_new (). Future work
will be needed as currently we can not
automatically generate widgets from
array parameters.
The visibility lock icon and help ID was accidentally
left off the PathsTreeView set-up.
The Path Attributes also used the wrong icon to indicate
the paths were locked (compared to the one shown in the
Path Attributes dialogue).
Revise the tests that can't default the args.
Actual args default to the min value formal declared in the PDB.
The declared min value must correspond with declaration in GEGL.
As of fcdddad2, the requirement for layers
to be attached before NDE filters can be
applied has been removed on app/core.
This patch removes the restriction from
the PDB call for filters as well.
* file-sunras, sparkle, and fractal-explorer
were converted to use GimpChoice with
the RadioFrame setting
* Unnecessary store variables were
removed from hot and file-psp
The description promises that we return
NULL if the image is not in indexed mode,
but we didn't actually verify that it was
before continuing with the colormap
code. This patch adds that verification step.