oss-fuzz pointed out:
gd_gif_in.c:605:16: runtime error: index 5595 out of bounds for type 'int [4096]'
Add some bounds checking on each code that we read from the file.
oss-fuzz pointed out:
wbmp.c:48:14: runtime error: left shift of 253751679 by 7 places cannot be represented in type 'int'
See previous commit for more details.
oss-fuzz pointed out:
gd_io.c:174:10: runtime error: left shift of 255 by 24 places cannot be represented in type 'int'
See previous commit for more details.
oss-fuzz pointed out:
gd_io.c:139:14: runtime error: left shift of 199 by 24 places cannot be represented in type 'int'
Switch the temp var we use here to unsigned to avoid that. We do an
unsigned int to a signed int at the end which is undefined, but since
compilers don't seem to mind that, we won't care just yet. It also
makes the code match gdGetIntLSB behavior.
The palette headers always consist of 256 palette entries, and if
`\377\377\377\377` is given for the transparency, that means that there
is no transparent color.
The issue is that `gdImagePngCtxEx` (which is called by `gdImagePngPtr`
and the other PNG output functions to do the real work) does not return
whether it succeeded or failed, so this is not checked in
`gdImagePngPtr` and the function wrongly assumes everything is okay,
which is not, in this case, because the palette image contains no
palette entries.
We can't change the signature of `gdImagePngCtxEx` for API
compatibility reasons, so we introduce the static helper
`_gdImagePngCtxEx` which returns success respective failure, so
`gdImagePngPtr` and `gdImagePngPtrEx` can check the return value. We
leave it solely to libpng for now to report warnings regarding the
failing write.
CVE-2017-6362
We have to make sure to avoid alpha-blending issues by explicitly
switching to `gdEffectReplace` and to restore the old value afterwards.
We also document the algorithm used by `gdImageGrayScale()` and note
its limitations regarding palette images.
We have to initialize `trans_col` to the value that guards the call to
`gdImageColorTransparent()`. To avoid confusion, we replace the magic
numbers with a macro.
Although libgd is not really affected by this issue, because contrary
to PHP's bundled libgd it does not allow to read from negative offsets,
we consider it still a bug that `dynamicSeek()` does not behave like
`fileSeek()` with regard to negative positions.
As this behavior cannot be probed from outside, we omit the regression
test.
The stack allocated color map buffers were not zeroed before usage, and
so undefined palette indexes could cause information leakage.
This issue has been reported by Matviy Kotoniy to security@libgd.org in
<CAKm_7a-AO++B6cXYWM_DtycPENG5WNWK7NSEvQ5OmZziMY_JyA@mail.gmail.com>.
The following API functions now accept the font names and the text to be
printed as `const char*` rater than `char*`. This makes the functions
much more `C++` friendly.
gdImageStringFT();
gdImageStringTTF();
gdImageStringFTEx();
Other functions/types affected:
typeed struct fontkey_t;
any2eucjp();
gdTcl_UtfToUniChar();
DetectKanjiCode();
do_convert();
do_check_and_conv();
If the reading of GD2 images fails due to a truncated file, we have to
make sure that all resources are freed. We do so by going to `fail`
instead of bailing out early.
This is a minor issue, though, as GD2 isn't recommended for production
use at all.
Due to #82 the optimized support for reading 1 bps TIFF files (black &
white) had been disabled. Tony Lew already pointed out a fix in #88.
Furthermore, there was the following missing and improper error handling:
* TIFFReadScanline() returns -1 on error, not 0
* the result of TIFFReadTile() hasn't been checked
* in case of failure of these functions, the error had not been
propagated
We fix this, and re-enable direct support for 1 bps TIFFs, which is
more memory efficient than the general RGBA support. We also make sure
not to hit any not yet implemented code path.
GD2 stores the number of horizontal and vertical chunks as words (i.e. 2
byte unsigned). These values are multiplied and assigned to an int when
reading the image, what can cause integer overflows. We have to avoid
that, and also make sure that either chunk count is actually greater
than zero. If illegal chunk counts are detected, we bail out from
reading the image.
gdImageCreate() doesn't check for oversized images and as such is prone
to DoS vulnerabilities. We fix that by applying the same overflow check
that is already in place for gdImageCreateTrueColor().
CVE-2016-9317
It is possible to craft TGA files which will overflow the decompression
buffer, but not the image's bitmap. Therefore we also have to check for
potential decompression buffer overflows.
This issue had been reported by Ibrahim El-Sayed to security@libgd.org;
a modified case exposing an off-by-one error of the first patch had been
provided by Konrad Beckmann.
This commit is an amendment to commit fb0e0cce, so we use CVE-2016-6906
as well.
No need to decrease `u`, so we don't do it. While we're at it, we also factor
out the overflow check of the loop, what improves performance and readability.
This issue has been reported by Stefan Esser to security@libgd.org.
The issue is that gdImageWebpCtx() (which is called by gdImageWebpPtr() and
the other WebP output functions to do the real work) does not return whether
it succeeded or failed, so this is not checked in gdImageWebpPtr() and the
function wrongly assumes everything is okay, which is not, in this case,
because there is a size limitation for WebP, namely that the width and
height must by less than 16383.
We can't change the signature of gdImageWebpCtx() for API compatibility
reasons, so we introduce the static helper _gdImageWebpCtx() which returns
success respective failure, so gdImageWebpPtr() and gdImageWebpPtrEx() can
check the return value. We leave it solely to libwebp for now to report
warnings regarding the failing write.
This issue had been reported by Ibrahim El-Sayed to security@libgd.org.
CVE-2016-6912
tiff_invalid_read.tiff is corrupt, and causes an invalid read in
gdImageCreateFromTiffPtr(), but not in gdImageCreateFromTiff(). The culprit
is dynamicGetbuf(), which doesn't check for out-of-bound reads. In this case,
dynamicGetbuf() is called with a negative dp->pos, but also positive buffer
overflows have to be handled, in which case 0 has to be returned (cf. commit
75e29a9).
Fixing dynamicGetbuf() exhibits that the corrupt TIFF would still create
the image, because the return value of TIFFReadRGBAImage() is not checked.
We do that, and let createFromTiffRgba() fail if TIFFReadRGBAImage() fails.
This issue had been reported by Ibrahim El-Sayed to security@libgd.org.
CVE-2016-6911
It is possible to craft TGA files which will overflow the decompression
buffer, but not the image's bitmap. Therefore we augment the check for the
bitmap's overflow with a check for the buffer's overflow.
This issue had been reported by Ibrahim El-Sayed to security@libgd.org.
CVE-2016-6906
libgd clients need to be able to distinguish between fatal and
"extremely fatal" libjpeg and libpng errors, because in the former case
execution can proceed, but in the latter case libgd calls exit().
Therefore we report fatal errors as GD_WARNING.
Pull out the library versioning info out of configure and into a common
script that both cmake & autotools can run. This way we have a single
source of truth for the versioning info.
The buffer underflow happens at the start of the bitstream and after
each clear code, where the wrap-around is actually unnecessary. To
avoid the buffer underflow we simply initialize scd->last_byte to 2,
instead of adding further control logic to skip the relevant
assignments altogether.
We do not add a regression test, because the buffer underflow could
only be detected with ASAN or a similar memory-checker (or debugging),
and it happens for all proper GIFs anyway, so other tests (such as
tests/gif/gif_im2im) already exhibited the behavior.
We're passing `pixel1` as default color to `getPixelOverflow*()` for
pixels which may be outside the valid bounds. `pixel1` is supposed to
be always valid due to the fixed arithmetic's round towards zero
behavior.
Lossless WebP is a rather interesting alternative to PNG, and already
supported by `gdImageCreateFromWebp*()`, so we add support for
`gdImageWebp*()`, too.
We can stick with the existing API, using the quality parameter to
request lossless encoding if it is set to `gdWebpLossless`, which we
define to `PHP_INT` (to avoid adding a new dependency to gd.h, we hard-
code the value – we're assuming `sizeof(int)==4` anyway).
Before we copy the quantized palette image onto the original image, we have
to mark the latter as palette image. We also have to free the allocated
truecolor pixels; free_truecolor_image_data() does all that for us.
This is obviously a relict of PHP's bundled libgd, which we should remove.
And actually, the #ifdef isn't necessary anymore for PHP's bundled libgd
either, because it supports gdImageAlphaBlending().
We remove the special casing for "point" rectangles with thick!=1 altogether,
and restrict the special casing for "line" rectangles to thick==1. We move
this necessary special casing (it fixes issue #172) towards the bottom of the
function like it is in PHP's bundled libgd.
Integer overflow can be happened in expression gdImageSX(im) * 4 *
gdImageSY(im). It could lead to heap buffer overflow in the following
code. This issue has been reported to the PHP Bug Tracking System. The
proof-of-concept file will be supplied some days later. This issue was
discovered by Ke Liu of Tencent's Xuanwu LAB.
gdImageTrueColorToPalette() is sometimes wasteful by putting multiple white
color entries into the palette. This is caused by an obvious typo, where
to avoid a division by zero when `total` is zero, `count` is checked instead
of `total`.
We fix this issue, to improve the quality of the color quantization.
If fontconfig support is disabled, the static functions font_pattern() and
useFontConfig() are never used. This can lead to build errors, and does so
with the current default settings `-Wall -Werror`. Therefore we ensure that
these functions are not compiled when they are not needed.
This makes the code better readable in the sources, and we get syntax
highlighting in the generated HTML wherever we want it (i.e. not necessarily
always as with `-hl all`).
We make it work only, for now. Actually, it doesn't make sense that
`oTga::bitmap` is an `int *` as we're storing only bytes there. If this
will be changed, we can even get rid of the `conversion_buffer` in
`read_image_tga` altogether, and read the image data into the
`decompression_buffer` (if RLE'd) or the `tga->bitmap` (if uncompressed)
directly.
In file included from gdft.c:20:0:
entities.h:17:4: error: 'entities' defined but not used [-Werror=unused-variable]
gdft.c:1741:15: error: 'font_path' defined but not used [-Werror=unused-function]
static char * font_path(char **fontpath, char *name_list)
That happens only when RLE is applied. The culprit is in compress_row(),
where the rightmost pixels which wouldn't be run-length encoded were
ignored; instead we now add them uncompressed to the `row`.
That happens only when RLE is applied. The culprit is in compress_row(),
where the rightmost pixels which wouldn't be run-length encoded were
ignored; instead we now add them uncompressed to the `row`.
The cmake build was missing gd_color_match.c which meant the library
didn't export the gdImageColorMatch function. Sync the two lists in
the autotools and cmake files to make this easier to check. Listing
header files in autotools source lists isn't a problem.
This makes sure we don't export symbols in libgd.so that we shouldn't.
We now assume that, if you're using gcc, you're using at least version
3.3 as that's the first to support the visibility attribute. We can
wait to see if anyone complains before worrying about older ones.
The standard behavior in distros nowadays is to build shared libs and
omit static libs. Split the build knobs in cmake to support this. It
also matches what's available with the autotools build.
We fix the unintended sign extension issue #150385 by declaring encoded_pixels
as int, and the logical vs. bitwise operator issue #150382 by using the
proper operator.
Otherwise we get artifacts regarding transparency. That happens with the
current implementation of gdImageFilledArc() unless gdChord or gdNoFill
are set. When gdPie is set, however, the filled arc is drawn in wedges,
which are polygons of three points, and so some overlap is natural.
To resolve the issue, we stick with the current algorithm of calculating the
wedges, but instead of drawing each polygon separately, we put the *relevant*
points in a large array, and draw a single polygon. That also is supposed to
improve the performance considerably.
Note that this modification will change the results when gdImageSetStyle()
or gdImageSetBrush() are used, but we believe that this modification is
also an improvement in this regard, even though it still might not make much
sense to use these functions with gdImageFilledArc().
Currently gd_error() forwards to gd_error_ex(). However, both functions
accept a variable number of arguments, and simply forwarding the va_list
isn't portable, see <http://c-faq.com/varargs/handoff.html>. This article
also describes the usual workaround, namely to let the second function
accept a va_list instead of variable number of arguments.
We do so by introducing a static helper, what does not affect API/ABI
compatibility.
This pull request (based on Asma's works) adds support for languages that require [complex text
layout](https://en.wikipedia.org/wiki/Complex_text_layout).
We are using [libraqm](https://github.com/HOST-Oman/libraqm), a small source
code-only library that wraps FriBidi (for bidirectional text support) and
HarfBuzz (for text shaping), and does proper BiDi and script itemization.
The CTL support is enabled by default but can be disabled at compiling time,
and we provide a fallback function that uses your original code without CTL
support.
As reported in <https://bugs.php.net/64641> 1-dimensional horizontal
filled polygons are not drawn at all. That is caused by the scanline
algorithm used for drawing filled polygons which skips the drawing of
horizontal edges, because that is normally not necessary. If, however,
the polygon consists of horizontal edges only, that obviously doesn't
work, so we add a special case handling.
(cherry picked from commit f9f10fa9d4)
As reported in <https://bugs.php.net/64641> 1-dimensional horizontal
filled polygons are not drawn at all. That is caused by the scanline
algorithm used for drawing filled polygons which skips the drawing of
horizontal edges, because that is normally not necessary. If, however,
the polygon consists of horizontal edges only, that obviously doesn't
work, so we add a special case handling.
* GD-2.2:
fix coverity 95857, given the underlying functions, risks to actually have a string overflow seems not possible. However this little safety check costs nothing and puts us on a 100% side.
* GD-2.2:
use unsigned int for index
fix memory leak
add email and quotes (just to be sure)
use 2.2 for now
add key for travis-coverity
Fix 228: gdAssertImageEquals() can't be used
Conflicts:
.travis.yml
Thick lines are drawn by gdImageFilledRectangle(), which iterates over
the x ordinate first (Z order) to apply the style pattern. While this works
fine for vertical and diagonal lines, it obviously fails for horizontal
lines, which have to be iterated over in N order.
To fix this bug, we introduce the helpers gdImageFilled(H|V)Rectangle(),
which may be reused for other purposes as well.
* GD-2.2:
fix#227 drop usage of GD_BILINEAR_FIXED and GD_BICUBIC_FIXED for gdImageRotateInterpolated, the quality does not match expectation. It is also trickier to maintain for little gain. The generic method is used and will be optimized for 2.3 to match fixed pt performance, if necessary. Also use png for comparison to avoid jpeg artifact, making impossible to exactly compare results
fix#227 drop usage of GD_BILINEAR_FIXED and GD_BICUBIC_FIXED for gdImageRotateInterpolated, the quality does not match expectation. It is also trickier to maintain for little gain. The generic method is used and will be optimized for 2.3 to match fixed pt performance, if necessary. Also use png for comparison to avoid jpeg artifact, making impossible to exactly compare results
fix#227 drop usage of GD_BILINEAR_FIXED and GD_BICUBIC_FIXED for gdImageRotateInterpolated, the quality does not match expectation. It is also trickier to maintain for little gain. The generic method is used and will be optimized for 2.3 to match fixed pt performance, if necessary. Also use png for comparison to avoid jpeg artifact, making impossible to exactly compare results
WS
#230 fix crash on fail
gdTestAssert should not accept any message. Also crashes if assert failed
Conflicts:
tests/gdimagerotate/bug00067.c
tests/gdtest/gdtest.c
* GD-2.2:
fix#223 pass coordiates as double to interpolated pixel, simplify edges and bg color checks and correct the calc of the delta between virtual pixels and pixels used for the interpolation. Summary: better quality
gitignore: add missing entries #172#218
clean up new gdTransformAffineBoundingBox tests #221
* GD-2.2:
fix#215 gdImageFillToBorder stack-overflow when invalid color is used
tests: add bug_github_18 to gitignore #18
tests: fix typo in test name #18
These don't seem to ever have been used, but since they follow API
patterns seen by other funcs in here, let's just #if 0 them out for
now. This fixes unused func -Werror failures.
Contrary to gdImageFilledRectangle(), gdImageRectangle() has the
documented limitation that the given points have to be the upper
left and the lower right corner, respectively. However, libgd
already caters to upper right / lower left pairs, and not
catering to the other two combinations seems to be an oversight.
Fixes#177.
The symbol was being set up in cmake but not on the autotools side.
Clean this up to be like other external libraries.
We need to pull in some openmp logic as it's not uncommon for the lib
to be built with openmp support. When we test for it, we need to do
so with openmp flags.
Fixes#137.
We are using GDLIB_REVISION to refer to the gd version string (the "z"
in "x.y.z"), and we are using it to control the libtool revision field.
This leads to problems where the version increases (e.g. "2.1.1") but
the libtool revision doesn't (e.g. "0"). So scripts end up seeing a
revision of "0" in their output instead of "1".
Namespace the libtool version variables with "_LT_" to avoid any more
collisions.
Fixes#140.
Try to standardize the internals a little bit and simplify the read
paths to abort early on when we know we won't actually handle the
input format. Avoid resetting pointers that are on the stack or we
release as it's a waste of code.
First, if the tga input had an ID set, we'd read this into the pointer
itself (and the memory after it in the struct/heap) instead of the memory
allocated to hold it. This bug has been around since the tga code was
first added. We'd basically corrupt memory all the time since most tga
files out there have an ID set up (like a datestamp).
Second, make sure we reject invalid images that would cause overflows in
the allocation path. We tried to check for this already, but we used the
wrong type (we checked uint8_t but allocated int).
Fixes#159.
The use of setjmp in this function was slightly incorrect: we store
pointers to allocated memory in stack variables, but we didn't call
setjmp again afterwards. Optimization might place those in registers
which would clobber their values on the next longjmp. Make sure we
call setjmp after every allocation to update the state.
As part of the cleanup, unify all the error code paths so we don't
have to worry about every if statement being fully correct.
When given invalid inputs, we might be fed the EOF marker before it is
actually the EOF. The gif logic assumes once it sees the EOF marker,
there won't be any more data, so it leaves the cur_bits index possibly
negative. So when we get more data, we underflow the masks array.
Flag it so we don't try to output anything more. The image is invalid,
so we shouldn't be truncating any valid inputs.
This fixes#209.
We use the name passed in to printf into a local stack buffer which is
limited to 4000 bytes. So given a large enough value, lots of stack
data is leaked. Rewrite the code to do simple memory copies with most
of the strings to avoid that issue, and only use stack buffer for small
numbers of constant size.
This closes#211.
Clean up redundant header logic and focus on what we actually care about:
whether specific headers exist.
Update the program list to omit programs when required libs are not found.
The filedata & temp pointers are assigned the same return value, so
trying to free both of them at the end makes no sense and results in
a double free error. Drop one of them.
The Makefile.am has no changes other than sorting & unwrapping the files
to make it a bit more readable (and dropping duplicate entries).
The CMakeLists.txt gains a few files that were added recently but left
out of the cmake build.
Closes#183.
Make sure we do some range checking on corrupted chunks.
Thanks to Hans Jerry Illikainen <hji@dyntopia.com> for indepth report
and reproducer information. Made for easy test case writing :).
We use ceill and ceil in this code, but it's not clear we need the long
double variant of ceill here. The input multiply is already done with
double precision (the 0.1 literal is a double), and not all C libraries
offer long double variants. Change to ceil and see if anyone notices.
Closes issue #123.
* For VS2013 and below, it will compile and additional file `src/snprintf.c`, which contains the fallback implementation. The
function is included with `extern` in other files where required.
* In `src/CMakeLists.txt`, `snprintf.c` is included in sources conditionally; only for
VS2013 and below.
* Note that I have also guarded it with condition inside the `snprintf.c` file, so if any consumer/downstream is not using `cmake` but their own build system (say gyp), this will still prevent them redefining snprintf for VS2015 even if they add `/src/snprintf.c` in to-be-compiled sources unconditionally.
It is the responsibility of the build infrastructure or user to set or
not set NDEBUG. For the time being this is a workaround in the case
where NDEBUG is set by the build infrastructure or user which prevents
the compiler from generating macro redefiniton warnings/errors. A longer
term fix will require changes to booststrap (aka configure) as well as
cmake (aka CMakeLists.txt).
The interpolation_id is an enum that contains only positive
values. As a result, checking if it less than 0 generates a
compiler warning since the conditional check is always false.
Fixing memory leak in gdImageScaleTwoPass, as reported by @cmb69 and
confirmed by @vapier. This bug actually bit me in production and I'm
very thankful that it was reported with an easy fix.
Fixes#173.