From: David Kahurani k.kahurani@gmail.com
Serves to strictly allocate the requested size to a path unlike lengthen_path whose algorithm allocates more than strictly required
Signed-off-by: David Kahurani k.kahurani@gmail.com --- dlls/gdiplus/gdiplus.c | 24 ++++++++++++++++++++++++ dlls/gdiplus/gdiplus_private.h | 1 + dlls/gdiplus/graphicspath.c | 28 +++------------------------- dlls/gdiplus/metafile.c | 15 +++------------ 4 files changed, 31 insertions(+), 37 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c index 32e287b0409..8e7b291f6a6 100644 --- a/dlls/gdiplus/gdiplus.c +++ b/dlls/gdiplus/gdiplus.c @@ -442,6 +442,30 @@ BOOL lengthen_path(GpPath *path, INT len) return TRUE; }
+BOOL lengthen_path_strict(GpPath **path, INT len) +{ + /* Has to be a new unallocated path */ + *path = calloc(1, sizeof(GpPath)); + + if (!*path) return FALSE; + + /* Strictly allocate the requested memory size */ + (*path)->pathdata.Points = calloc(len, sizeof(PointF)); + (*path)->pathdata.Types = calloc(1, len); + + if (!(*path)->pathdata.Points || !(*path)->pathdata.Types) + { + free((*path)->pathdata.Points); + free((*path)->pathdata.Types); + free(*path); + return FALSE; + } + + (*path)->datalen = len; + + return TRUE; +} + void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height, BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride) { diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 6f7e72124c2..2cfb93c62e5 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -130,6 +130,7 @@ extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj, extern void free_installed_fonts(void);
extern BOOL lengthen_path(GpPath *path, INT len); +extern BOOL lengthen_path_strict(GpPath **path, INT len);
extern DWORD write_region_data(const GpRegion *region, void *data); extern DWORD write_path_data(GpPath *path, void *data); diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 9e186aa43d1..cbf2d074b20 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1185,19 +1185,9 @@ GpStatus WINGDIPAPI GdipClonePath(GpPath* path, GpPath **clone) if(!path || !clone) return InvalidParameter;
- *clone = malloc(sizeof(GpPath)); - if(!*clone) return OutOfMemory; + if (!lengthen_path_strict(clone, path->datalen)) return OutOfMemory;
- **clone = *path; - - (*clone)->pathdata.Points = malloc(path->datalen * sizeof(PointF)); - (*clone)->pathdata.Types = malloc(path->datalen); - if(!(*clone)->pathdata.Points || !(*clone)->pathdata.Types){ - free((*clone)->pathdata.Points); - free((*clone)->pathdata.Types); - free(*clone); - return OutOfMemory; - } + (*clone)->pathdata.Count = path->pathdata.Count;
memcpy((*clone)->pathdata.Points, path->pathdata.Points, path->datalen * sizeof(PointF)); @@ -1271,9 +1261,6 @@ GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF* points, return OutOfMemory; }
- *path = calloc(1, sizeof(GpPath)); - if(!*path) return OutOfMemory; - if(count > 1 && (types[count-1] & PathPointTypePathTypeMask) == PathPointTypeStart) count = 0;
@@ -1290,22 +1277,13 @@ GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF* points, } }
- (*path)->pathdata.Points = malloc(count * sizeof(PointF)); - (*path)->pathdata.Types = malloc(count); - - if(!(*path)->pathdata.Points || !(*path)->pathdata.Types){ - free((*path)->pathdata.Points); - free((*path)->pathdata.Types); - free(*path); - return OutOfMemory; - } + if (!lengthen_path_strict(path, count)) return OutOfMemory;
memcpy((*path)->pathdata.Points, points, count * sizeof(PointF)); memcpy((*path)->pathdata.Types, types, count); if(count > 0) (*path)->pathdata.Types[0] = PathPointTypeStart; (*path)->pathdata.Count = count; - (*path)->datalen = count;
(*path)->fill = fill; (*path)->newfigure = TRUE; diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 5c50d0d1d37..6e253842d4d 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -2035,20 +2035,11 @@ static GpStatus metafile_deserialize_path(const BYTE *record_data, UINT data_siz if (data_size < size) return InvalidParameter;
- status = GdipCreatePath(FillModeAlternate, path); - if (status != Ok) - return status; + if (!lengthen_path_strict(path, data->PathPointCount)) return OutOfMemory;
+ (*path)->fill = FillModeAlternate; + (*path)->newfigure = TRUE; (*path)->pathdata.Count = data->PathPointCount; - (*path)->pathdata.Points = malloc(data->PathPointCount * sizeof(*(*path)->pathdata.Points)); - (*path)->pathdata.Types = malloc(data->PathPointCount * sizeof(*(*path)->pathdata.Types)); - (*path)->datalen = (*path)->pathdata.Count; - - if (!(*path)->pathdata.Points || !(*path)->pathdata.Types) - { - GdipDeletePath(*path); - return OutOfMemory; - }
if (data->PathPointFlags & 0x4000) /* C */ {