Skip to content

Commit 6db4292

Browse files
committed
apply changes from upstream
1 parent 59a4db5 commit 6db4292

2 files changed

Lines changed: 141 additions & 66 deletions

File tree

ext/gd/libgd/gd.c

Lines changed: 18 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <string.h>
44
#include <stdlib.h>
55
#include "gd.h"
6+
#include "gd_intern.h"
67
#include "gdhelpers.h"
78
#include "gd_errors.h"
89

@@ -2307,53 +2308,16 @@ void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int
23072308
_gdImageFilledVRectangle(im, x1, y1, x2, y2, color);
23082309
}
23092310

2310-
static int _gdValidateCopyRectBounds(
2311-
const gdImagePtr dst,
2312-
const gdImagePtr src,
2313-
int dstX, int dstY,
2314-
int srcX, int srcY,
2315-
int w, int h
2316-
) {
2317-
/* Check for null pointers */
2318-
if (!dst || !src) {
2319-
return 0;
2320-
}
2321-
2322-
/* Check for overflow in dstX + w */
2323-
if (w > 0 && dstX > INT_MAX - w) {
2324-
return 0;
2325-
}
2326-
2327-
/* Check for overflow in dstY + h */
2328-
if (h > 0 && dstY > INT_MAX - h) {
2329-
return 0;
2330-
}
2331-
2332-
/* Check for overflow in srcX + w */
2333-
if (w > 0 && srcX > INT_MAX - w) {
2334-
return 0;
2335-
}
2336-
2337-
/* Check for overflow in srcY + h */
2338-
if (h > 0 && srcY > INT_MAX - h) {
2339-
return 0;
2340-
}
2341-
2342-
return 1;
2343-
}
2344-
23452311
void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
23462312
{
2347-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, w, h)) {
2348-
return;
2349-
}
2350-
23512313
int c;
23522314
int x, y;
23532315
int tox, toy;
23542316
int i;
23552317
int colorMap[gdMaxColors];
2356-
2318+
if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) {
2319+
return;
2320+
}
23572321
if (dst->trueColor) {
23582322
/* 2.0: much easier when the destination is truecolor. */
23592323
/* 2.0.10: needs a transparent-index check that is still valid if
@@ -2429,14 +2393,13 @@ void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
24292393
so it doesn't pay attention to the alpha channel. */
24302394
void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct)
24312395
{
2432-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, w, h)) {
2433-
return;
2434-
}
2435-
24362396
int c, dc;
24372397
int x, y;
24382398
int tox, toy;
24392399
int ncR, ncG, ncB;
2400+
if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) {
2401+
return;
2402+
}
24402403
toy = dstY;
24412404

24422405
for (y = srcY; y < (srcY + h); y++) {
@@ -2473,15 +2436,16 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s
24732436
so it doesn't pay attention to the alpha channel. */
24742437
void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct)
24752438
{
2476-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, w, h)) {
2477-
return;
2478-
}
2479-
24802439
int c, dc;
24812440
int x, y;
24822441
int tox, toy;
24832442
int ncR, ncG, ncB;
24842443
float g;
2444+
2445+
if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) {
2446+
return;
2447+
}
2448+
24852449
toy = dstY;
24862450

24872451
for (y = srcY; (y < (srcY + h)); y++) {
@@ -2531,14 +2495,6 @@ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i
25312495

25322496
void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
25332497
{
2534-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, dstW, dstH)) {
2535-
return;
2536-
}
2537-
2538-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, srcW, srcH)) {
2539-
return;
2540-
}
2541-
25422498
int c;
25432499
int x, y;
25442500
int tox, toy;
@@ -2554,7 +2510,9 @@ void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
25542510
if (overflow2(sizeof(int), srcH)) {
25552511
return;
25562512
}
2557-
2513+
if (!gdImageClipCopyResized(dst, &dstX, &dstY, &dstW, &dstH, &srcX, &srcY, &srcW, &srcH)) {
2514+
return;
2515+
}
25582516
stx = (int *) gdMalloc (sizeof (int) * srcW);
25592517
sty = (int *) gdMalloc (sizeof (int) * srcH);
25602518

@@ -2649,21 +2607,16 @@ void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
26492607

26502608
void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
26512609
{
2652-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, dstW, dstH)) {
2653-
return;
2654-
}
2655-
2656-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, srcW, srcH)) {
2657-
return;
2658-
}
2659-
26602610
int x, y;
26612611
double sy1, sy2, sx1, sx2;
26622612

26632613
if (!dst->trueColor) {
26642614
gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
26652615
return;
26662616
}
2617+
if (!gdImageClipCopyResized(dst, &dstX, &dstY, &dstW, &dstH, &srcX, &srcY, &srcW, &srcH)) {
2618+
return;
2619+
}
26672620
for (y = dstY; (y < dstY + dstH); y++) {
26682621
sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH;
26692622
sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / (double) dstH;

ext/gd/libgd/gd_intern.h

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#ifndef GD_INTERN_H
22
#define GD_INTERN_H
3+
4+
#include <limits.h>
5+
36
#ifndef MIN
47
#define MIN(a,b) ((a)<(b)?(a):(b))
58
#endif
@@ -10,5 +13,124 @@
1013
#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))
1114
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
1215

13-
#endif
16+
/**
17+
* Clip a copy operation to the destination image bounds.
18+
* Adjusts srcX/srcY to match any clipping applied to dstX/dstY.
19+
* Returns 0 if the operation is entirely outside dst (nothing to do),
20+
* 1 if there is work to do.
21+
*/
22+
static inline int gdImageClipCopy(
23+
gdImagePtr dst,
24+
int *dstX, int *dstY,
25+
int *srcX, int *srcY,
26+
int *w, int *h)
27+
{
28+
int x1, y1, x2, y2;
29+
30+
/* overflow-safe dst rect: [dstX, dstY] to [dstX+w, dstY+h] */
31+
x1 = *dstX;
32+
y1 = *dstY;
33+
34+
/* check w/h are positive */
35+
if (*w <= 0 || *h <= 0) {
36+
return 0;
37+
}
38+
39+
/* overflow check for dstX+w and dstY+h */
40+
if (*dstX > 0 && *w > INT_MAX - *dstX) {
41+
x2 = INT_MAX;
42+
} else {
43+
x2 = *dstX + *w;
44+
}
45+
if (*dstY > 0 && *h > INT_MAX - *dstY) {
46+
y2 = INT_MAX;
47+
} else {
48+
y2 = *dstY + *h;
49+
}
50+
51+
/* entirely outside dst? */
52+
if (x1 >= gdImageSX(dst) || y1 >= gdImageSY(dst) ||
53+
x2 <= 0 || y2 <= 0) {
54+
return 0;
55+
}
56+
57+
/* clip left */
58+
if (x1 < 0) {
59+
*srcX -= x1; /* advance srcX by the same amount */
60+
*w += x1; /* reduce width */
61+
*dstX = 0;
62+
}
63+
64+
/* clip top */
65+
if (y1 < 0) {
66+
*srcY -= y1;
67+
*h += y1;
68+
*dstY = 0;
69+
}
70+
71+
/* clip right */
72+
if (*dstX + *w > gdImageSX(dst)) {
73+
*w = gdImageSX(dst) - *dstX;
74+
}
75+
76+
/* clip bottom */
77+
if (*dstY + *h > gdImageSY(dst)) {
78+
*h = gdImageSY(dst) - *dstY;
79+
}
80+
81+
/* sanity: clipping may have reduced w/h to zero */
82+
if (*w <= 0 || *h <= 0) {
83+
return 0;
84+
}
85+
86+
return 1;
87+
}
88+
static inline int gdImageClipCopyResized(
89+
gdImagePtr dst,
90+
int *dstX, int *dstY,
91+
int *dstW, int *dstH,
92+
int *srcX, int *srcY,
93+
int *srcW, int *srcH)
94+
{
95+
int orig_dstW = *dstW;
96+
int orig_dstH = *dstH;
97+
98+
if (*dstW <= 0 || *dstH <= 0 || *srcW <= 0 || *srcH <= 0) {
99+
return 0;
100+
}
101+
if (*dstX >= gdImageSX(dst) || *dstY >= gdImageSY(dst) ||
102+
*dstX + *dstW <= 0 || *dstY + *dstH <= 0) {
103+
return 0;
104+
}
105+
106+
/* clip left — adjust srcX proportionally */
107+
if (*dstX < 0) {
108+
*srcX += (-*dstX) * *srcW / orig_dstW;
109+
*srcW -= (-*dstX) * *srcW / orig_dstW;
110+
*dstW += *dstX;
111+
*dstX = 0;
112+
}
113+
/* clip top */
114+
if (*dstY < 0) {
115+
*srcY += (-*dstY) * *srcH / orig_dstH;
116+
*srcH -= (-*dstY) * *srcH / orig_dstH;
117+
*dstH += *dstY;
118+
*dstY = 0;
119+
}
120+
/* clip right */
121+
if (*dstX + *dstW > gdImageSX(dst)) {
122+
int clip = *dstX + *dstW - gdImageSX(dst);
123+
*srcW -= clip * *srcW / orig_dstW;
124+
*dstW = gdImageSX(dst) - *dstX;
125+
}
126+
/* clip bottom */
127+
if (*dstY + *dstH > gdImageSY(dst)) {
128+
int clip = *dstY + *dstH - gdImageSY(dst);
129+
*srcH -= clip * *srcH / orig_dstH;
130+
*dstH = gdImageSY(dst) - *dstY;
131+
}
14132

133+
if (*dstW <= 0 || *dstH <= 0) return 0;
134+
return 1;
135+
}
136+
#endif /* GD_INTERN_H */

0 commit comments

Comments
 (0)