Skip to content

Commit 5cef75c

Browse files
committed
apply changes from upstream
1 parent 49bcb1e commit 5cef75c

2 files changed

Lines changed: 142 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

@@ -2326,53 +2327,16 @@ void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int
23262327
_gdImageFilledVRectangle(im, x1, y1, x2, y2, color);
23272328
}
23282329

2329-
static int _gdValidateCopyRectBounds(
2330-
const gdImagePtr dst,
2331-
const gdImagePtr src,
2332-
int dstX, int dstY,
2333-
int srcX, int srcY,
2334-
int w, int h
2335-
) {
2336-
/* Check for null pointers */
2337-
if (!dst || !src) {
2338-
return 0;
2339-
}
2340-
2341-
/* Check for overflow in dstX + w */
2342-
if (w > 0 && dstX > INT_MAX - w) {
2343-
return 0;
2344-
}
2345-
2346-
/* Check for overflow in dstY + h */
2347-
if (h > 0 && dstY > INT_MAX - h) {
2348-
return 0;
2349-
}
2350-
2351-
/* Check for overflow in srcX + w */
2352-
if (w > 0 && srcX > INT_MAX - w) {
2353-
return 0;
2354-
}
2355-
2356-
/* Check for overflow in srcY + h */
2357-
if (h > 0 && srcY > INT_MAX - h) {
2358-
return 0;
2359-
}
2360-
2361-
return 1;
2362-
}
2363-
23642330
void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
23652331
{
2366-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, w, h)) {
2367-
return;
2368-
}
2369-
23702332
int c;
23712333
int x, y;
23722334
int tox, toy;
23732335
int i;
23742336
int colorMap[gdMaxColors];
2375-
2337+
if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) {
2338+
return;
2339+
}
23762340
if (dst->trueColor) {
23772341
/* 2.0: much easier when the destination is truecolor. */
23782342
/* 2.0.10: needs a transparent-index check that is still valid if
@@ -2448,14 +2412,13 @@ void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
24482412
so it doesn't pay attention to the alpha channel. */
24492413
void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct)
24502414
{
2451-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, w, h)) {
2452-
return;
2453-
}
2454-
24552415
int c, dc;
24562416
int x, y;
24572417
int tox, toy;
24582418
int ncR, ncG, ncB;
2419+
if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) {
2420+
return;
2421+
}
24592422
toy = dstY;
24602423

24612424
for (y = srcY; y < (srcY + h); y++) {
@@ -2492,15 +2455,16 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s
24922455
so it doesn't pay attention to the alpha channel. */
24932456
void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct)
24942457
{
2495-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, w, h)) {
2496-
return;
2497-
}
2498-
24992458
int c, dc;
25002459
int x, y;
25012460
int tox, toy;
25022461
int ncR, ncG, ncB;
25032462
float g;
2463+
2464+
if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) {
2465+
return;
2466+
}
2467+
25042468
toy = dstY;
25052469

25062470
for (y = srcY; (y < (srcY + h)); y++) {
@@ -2550,14 +2514,6 @@ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i
25502514

25512515
void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
25522516
{
2553-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, dstW, dstH)) {
2554-
return;
2555-
}
2556-
2557-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, srcW, srcH)) {
2558-
return;
2559-
}
2560-
25612517
int c;
25622518
int x, y;
25632519
int tox, toy;
@@ -2573,7 +2529,9 @@ void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
25732529
if (overflow2(sizeof(int), srcH)) {
25742530
return;
25752531
}
2576-
2532+
if (!gdImageClipCopyResized(dst, &dstX, &dstY, &dstW, &dstH, &srcX, &srcY, &srcW, &srcH)) {
2533+
return;
2534+
}
25772535
stx = (int *) gdMalloc (sizeof (int) * srcW);
25782536
sty = (int *) gdMalloc (sizeof (int) * srcH);
25792537

@@ -2668,21 +2626,16 @@ void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
26682626

26692627
void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
26702628
{
2671-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, dstW, dstH)) {
2672-
return;
2673-
}
2674-
2675-
if (!_gdValidateCopyRectBounds(dst, src, dstX, dstY, srcX, srcY, srcW, srcH)) {
2676-
return;
2677-
}
2678-
26792629
int x, y;
26802630
double sy1, sy2, sx1, sx2;
26812631

26822632
if (!dst->trueColor) {
26832633
gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
26842634
return;
26852635
}
2636+
if (!gdImageClipCopyResized(dst, &dstX, &dstY, &dstW, &dstH, &srcX, &srcY, &srcW, &srcH)) {
2637+
return;
2638+
}
26862639
for (y = dstY; (y < dstY + dstH); y++) {
26872640
sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH;
26882641
sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / (double) dstH;

ext/gd/libgd/gd_intern.h

Lines changed: 124 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
@@ -17,4 +20,124 @@ gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent);
1720
gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
1821
gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
1922

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

0 commit comments

Comments
 (0)