From ca970328d613d35cb400825835de6c7fdb9ea51d Mon Sep 17 00:00:00 2001 From: anthony Date: Thu, 18 Apr 2013 13:52:38 +0100 Subject: [PATCH] 8009071: Improve shape handling Reviewed-by: art, mschoene --- src/macosx/native/sun/awt/CRobot.m | 3 +- src/macosx/native/sun/awt/LWCToolkit.m | 4 +- .../sun/awt/splashscreen/splashscreen_sys.m | 6 +- src/share/native/common/sizecalc.h | 118 ++++++++++++++++++ .../awt/splashscreen/java_awt_SplashScreen.c | 3 +- .../sun/awt/splashscreen/splashscreen_gif.c | 6 +- src/share/native/sun/java2d/pipe/Region.c | 5 +- src/solaris/native/sun/awt/awt_Robot.c | 8 +- src/solaris/native/sun/awt/awt_UNIXToolkit.c | 10 +- src/solaris/native/sun/awt/fontpath.c | 12 +- src/solaris/native/sun/awt/gtk2_interface.c | 4 +- .../sun/awt/splashscreen/splashscreen_sys.c | 22 +++- src/solaris/native/sun/xawt/XlibWrapper.c | 10 +- .../sun/awt/splashscreen/splashscreen_sys.c | 31 +++-- src/windows/native/sun/font/lcdglyph.c | 10 +- .../native/sun/java2d/opengl/WGLSurfaceData.c | 3 +- .../sun/java2d/windows/GDIBlitLoops.cpp | 1 + .../native/sun/java2d/windows/GDIRenderer.cpp | 2 +- .../java2d/windows/GDIWindowSurfaceData.cpp | 5 +- src/windows/native/sun/windows/CmdIDList.cpp | 6 +- src/windows/native/sun/windows/Devices.cpp | 7 +- .../native/sun/windows/ShellFolder2.cpp | 6 + .../native/sun/windows/WPrinterJob.cpp | 2 +- src/windows/native/sun/windows/alloc.h | 3 + src/windows/native/sun/windows/awt.h | 6 +- .../native/sun/windows/awt_BitmapUtil.cpp | 14 ++- .../native/sun/windows/awt_Component.cpp | 43 ++++--- src/windows/native/sun/windows/awt_Cursor.cpp | 6 +- .../native/sun/windows/awt_DataTransferer.cpp | 12 +- .../sun/windows/awt_DesktopProperties.cpp | 6 +- src/windows/native/sun/windows/awt_DnDDT.cpp | 4 +- .../native/sun/windows/awt_InputMethod.cpp | 8 +- .../native/sun/windows/awt_PrintControl.cpp | 4 +- .../native/sun/windows/awt_PrintJob.cpp | 17 +-- src/windows/native/sun/windows/awt_Robot.cpp | 5 + 35 files changed, 313 insertions(+), 99 deletions(-) create mode 100644 src/share/native/common/sizecalc.h diff --git a/src/macosx/native/sun/awt/CRobot.m b/src/macosx/native/sun/awt/CRobot.m index 056fd19e2..3a986eb99 100644 --- a/src/macosx/native/sun/awt/CRobot.m +++ b/src/macosx/native/sun/awt/CRobot.m @@ -29,6 +29,7 @@ #import "LWCToolkit.h" #import "sun_lwawt_macosx_CRobot.h" #import "java_awt_event_InputEvent.h" +#import "sizecalc.h" // Starting number for event numbers generated by Robot. @@ -115,7 +116,7 @@ Java_sun_lwawt_macosx_CRobot_initRobot gsLastClickTime = 0; gsEventNumber = ROBOT_EVENT_NUMBER_START; - gsButtonEventNumber = (int*)malloc(sizeof(int) * gNumberOfButtons); + gsButtonEventNumber = (int*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(int), gNumberOfButtons); if (gsButtonEventNumber == NULL) { JNU_ThrowOutOfMemoryError(env, NULL); return; diff --git a/src/macosx/native/sun/awt/LWCToolkit.m b/src/macosx/native/sun/awt/LWCToolkit.m index 47c72abbf..3c6dfd8af 100644 --- a/src/macosx/native/sun/awt/LWCToolkit.m +++ b/src/macosx/native/sun/awt/LWCToolkit.m @@ -37,6 +37,8 @@ #import "sun_lwawt_macosx_LWCToolkit.h" +#import "sizecalc.h" + int gNumberOfButtons; jint* gButtonDownMasks; @@ -202,7 +204,7 @@ Java_sun_lwawt_macosx_LWCToolkit_initIDs jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID); jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE); - gButtonDownMasks = (jint*)malloc(sizeof(jint) * gNumberOfButtons); + gButtonDownMasks = (jint*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(jint), gNumberOfButtons); if (gButtonDownMasks == NULL) { gNumberOfButtons = 0; JNU_ThrowOutOfMemoryError(env, NULL); diff --git a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m index 709fbe481..bbe54aeb8 100644 --- a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m +++ b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m @@ -44,6 +44,7 @@ #include #include +#include static NSScreen* SplashNSScreen() { @@ -99,9 +100,12 @@ char* SplashConvertStringAlloc(const char* in, int* size) { goto done; } inSize = strlen(in); + buf = SAFE_SIZE_ARRAY_ALLOC(malloc, inSize, 2); + if (!buf) { + return NULL; + } bufSize = inSize*2; // need 2 bytes per char for UCS-2, this is // 2 bytes per source byte max - buf = malloc(bufSize); out = buf; outSize = bufSize; /* linux iconv wants char** source and solaris wants const char**... cast to void* */ diff --git a/src/share/native/common/sizecalc.h b/src/share/native/common/sizecalc.h new file mode 100644 index 000000000..675750e8a --- /dev/null +++ b/src/share/native/common/sizecalc.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef SIZECALC_H +#define SIZECALC_H + +/* + * A machinery for safe calculation of sizes used when allocating memory. + * + * All size checks are performed against the SIZE_MAX (the maximum value for + * size_t). All numerical arguments as well as the result of calculation must + * be non-negative integers less than or equal to SIZE_MAX, otherwise the + * calculated size is considered unsafe. + * + * If the SIZECALC_ALLOC_THROWING_BAD_ALLOC macro is defined, then _ALLOC_ + * helper macros throw the std::bad_alloc instead of returning NULL. + */ + +#include /* SIZE_MAX for C99+ */ +/* http://stackoverflow.com/questions/3472311/what-is-a-portable-method-to-find-the-maximum-value-of-size-t */ +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t)-1) +#endif + +#define IS_SAFE_SIZE_T(x) ((x) >= 0 && (unsigned long long)(x) <= SIZE_MAX) + +#define IS_SAFE_SIZE_MUL(m, n) \ + (IS_SAFE_SIZE_T(m) && IS_SAFE_SIZE_T(n) && ((m) == 0 || (n) == 0 || (size_t)(n) <= (SIZE_MAX / (size_t)(m)))) + +#define IS_SAFE_SIZE_ADD(a, b) \ + (IS_SAFE_SIZE_T(a) && IS_SAFE_SIZE_T(b) && (size_t)(b) <= (SIZE_MAX - (size_t)(a))) + + + +/* Helper macros */ + +#ifdef SIZECALC_ALLOC_THROWING_BAD_ALLOC +#define FAILURE_RESULT throw std::bad_alloc() +#else +#define FAILURE_RESULT NULL +#endif + +/* + * A helper macro to safely allocate an array of size m*n. + * Example usage: + * int* p = (int*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(int), n); + * if (!p) throw OutOfMemory; + * // Use the allocated array... + */ +#define SAFE_SIZE_ARRAY_ALLOC(func, m, n) \ + (IS_SAFE_SIZE_MUL((m), (n)) ? ((func)((m) * (n))) : FAILURE_RESULT) + +#define SAFE_SIZE_ARRAY_REALLOC(func, p, m, n) \ + (IS_SAFE_SIZE_MUL((m), (n)) ? ((func)((p), (m) * (n))) : FAILURE_RESULT) + +/* + * A helper macro to safely allocate an array of type 'type' with 'n' items + * using the C++ new[] operator. + * Example usage: + * MyClass* p = SAFE_SIZE_NEW_ARRAY(MyClass, n); + * // Use the pointer. + * This macro throws the std::bad_alloc C++ exception to indicate + * a failure. + * NOTE: if 'n' is calculated, the calling code is responsible for using the + * IS_SAFE_... macros to check if the calculations are safe. + */ +#define SAFE_SIZE_NEW_ARRAY(type, n) \ + (IS_SAFE_SIZE_MUL(sizeof(type), (n)) ? (new type[(n)]) : throw std::bad_alloc()) + +#define SAFE_SIZE_NEW_ARRAY2(type, n, m) \ + (IS_SAFE_SIZE_MUL((m), (n)) && IS_SAFE_SIZE_MUL(sizeof(type), (n) * (m)) ? \ + (new type[(n) * (m)]) : throw std::bad_alloc()) + +/* + * Checks if a data structure of size (a + m*n) can be safely allocated + * w/o producing an integer overflow when calculating its size. + */ +#define IS_SAFE_STRUCT_SIZE(a, m, n) \ + ( \ + IS_SAFE_SIZE_MUL((m), (n)) && IS_SAFE_SIZE_ADD((m) * (n), (a)) \ + ) + +/* + * A helper macro for implementing safe memory allocation for a data structure + * of size (a + m * n). + * Example usage: + * void * p = SAFE_SIZE_ALLOC(malloc, header, num, itemSize); + * if (!p) throw OutOfMemory; + * // Use the allocated memory... + */ +#define SAFE_SIZE_STRUCT_ALLOC(func, a, m, n) \ + (IS_SAFE_STRUCT_SIZE((a), (m), (n)) ? ((func)((a) + (m) * (n))) : FAILURE_RESULT) + + +#endif /* SIZECALC_H */ + diff --git a/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c b/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c index 2d5cdc1c5..f6cc52c03 100644 --- a/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c +++ b/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c @@ -26,6 +26,7 @@ #include "splashscreen_impl.h" #include #include +#include JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * vm, void *reserved) @@ -57,7 +58,7 @@ Java_java_awt_SplashScreen__1update(JNIEnv * env, jclass thisClass, if (splash->overlayData) { free(splash->overlayData); } - splash->overlayData = malloc(dataSize * sizeof(rgbquad_t)); + splash->overlayData = SAFE_SIZE_ARRAY_ALLOC(malloc, dataSize, sizeof(rgbquad_t)); if (splash->overlayData) { /* we need a copy anyway, so we'll be using GetIntArrayRegion */ (*env)->GetIntArrayRegion(env, data, 0, dataSize, diff --git a/src/share/native/sun/awt/splashscreen/splashscreen_gif.c b/src/share/native/sun/awt/splashscreen/splashscreen_gif.c index 1fc081e6d..e986bac6f 100644 --- a/src/share/native/sun/awt/splashscreen/splashscreen_gif.c +++ b/src/share/native/sun/awt/splashscreen/splashscreen_gif.c @@ -28,6 +28,8 @@ #include +#include "sizecalc.h" + #define GIF_TRANSPARENT 0x01 #define GIF_USER_INPUT 0x02 #define GIF_DISPOSE_MASK 0x07 @@ -120,7 +122,7 @@ SplashDecodeGif(Splash * splash, GifFileType * gif) splash->height = gif->SHeight; splash->frameCount = gif->ImageCount; splash->frames = (SplashImage *) - malloc(sizeof(SplashImage) * gif->ImageCount); + SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(SplashImage), gif->ImageCount); if (!splash->frames) { free(pBitmapBits); free(pOldBitmapBits); @@ -254,7 +256,7 @@ SplashDecodeGif(Splash * splash, GifFileType * gif) // now dispose of the previous frame correctly splash->frames[imageIndex].bitmapBits = - (rgbquad_t *) malloc(bufferSize); + (rgbquad_t *) malloc(bufferSize); // bufferSize is safe (checked above) if (!splash->frames[imageIndex].bitmapBits) { free(pBitmapBits); free(pOldBitmapBits); diff --git a/src/share/native/sun/java2d/pipe/Region.c b/src/share/native/sun/java2d/pipe/Region.c index 0a7a07a2e..97c682cf0 100644 --- a/src/share/native/sun/java2d/pipe/Region.c +++ b/src/share/native/sun/java2d/pipe/Region.c @@ -28,6 +28,7 @@ #include "jni_util.h" #include "Region.h" +#include "sizecalc.h" static jfieldID endIndexID; static jfieldID bandsID; @@ -260,8 +261,8 @@ RegionToYXBandedRectangles(JNIEnv *env, } Region_StartIteration(env, &clipInfo); numrects = Region_CountIterationRects(&clipInfo); - if (numrects > initialBufferSize) { - *pRect = (RECT_T *) malloc(numrects * sizeof(RECT_T)); + if ((unsigned long)numrects > initialBufferSize) { + *pRect = (RECT_T *) SAFE_SIZE_ARRAY_ALLOC(malloc, numrects, sizeof(RECT_T)); if (*pRect == NULL) { Region_EndIteration(env, &clipInfo); JNU_ThrowOutOfMemoryError(env, diff --git a/src/solaris/native/sun/awt/awt_Robot.c b/src/solaris/native/sun/awt/awt_Robot.c index 6818b3b5e..8387f5edb 100644 --- a/src/solaris/native/sun/awt/awt_Robot.c +++ b/src/solaris/native/sun/awt/awt_Robot.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "robot_common.h" #include "canvas.h" #include "wsutils.h" @@ -174,7 +175,7 @@ Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls, jint numberOfButton num_buttons = numberOfButtons; tmp = (*env)->GetIntArrayElements(env, buttonDownMasks, JNI_FALSE); - masks = (jint *)malloc(sizeof(jint) * num_buttons); + masks = (jint *)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(jint), num_buttons); if (masks == (jint *) NULL) { JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL); (*env)->ReleaseIntArrayElements(env, buttonDownMasks, tmp, 0); @@ -231,8 +232,9 @@ Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env, image = getWindowImage(awt_display, rootWindow, x, y, width, height); /* Array to use to crunch around the pixel values */ - ary = (jint *) malloc(width * height * sizeof (jint)); - if (ary == NULL) { + if (!IS_SAFE_SIZE_MUL(width, height) || + !(ary = (jint *) SAFE_SIZE_ARRAY_ALLOC(malloc, width * height, sizeof (jint)))) + { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); XDestroyImage(image); AWT_UNLOCK(); diff --git a/src/solaris/native/sun/awt/awt_UNIXToolkit.c b/src/solaris/native/sun/awt/awt_UNIXToolkit.c index a5993736b..c63698c5e 100644 --- a/src/solaris/native/sun/awt/awt_UNIXToolkit.c +++ b/src/solaris/native/sun/awt/awt_UNIXToolkit.c @@ -29,6 +29,7 @@ #include #include +#include #include "sun_awt_UNIXToolkit.h" #ifndef HEADLESS @@ -148,7 +149,8 @@ Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this, } len = (*env)->GetStringUTFLength(env, filename); - filename_str = (char *)malloc(sizeof(char) * (len + 1)); + filename_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc, + sizeof(char), len + 1); if (filename_str == NULL) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); return JNI_FALSE; @@ -189,7 +191,8 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, } len = (*env)->GetStringUTFLength(env, stock_id); - stock_id_str = (char *)malloc(sizeof(char) * (len + 1)); + stock_id_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc, + sizeof(char), len + 1); if (stock_id_str == NULL) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); return JNI_FALSE; @@ -200,7 +203,8 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, if (detail != NULL) { len = (*env)->GetStringUTFLength(env, detail); - detail_str = (char *)malloc(sizeof(char) * (len + 1)); + detail_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc, + sizeof(char), len + 1); if (detail_str == NULL) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); return JNI_FALSE; diff --git a/src/solaris/native/sun/awt/fontpath.c b/src/solaris/native/sun/awt/fontpath.c index 24146b962..00d956911 100644 --- a/src/solaris/native/sun/awt/fontpath.c +++ b/src/solaris/native/sun/awt/fontpath.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifndef HEADLESS #include #include @@ -225,7 +226,7 @@ static void AddFontsToX11FontPath ( fDirRecord *fDirP ) if ( fDirP->num == 0 ) return; - appendDirList = malloc ( fDirP->num * sizeof ( int )); + appendDirList = SAFE_SIZE_ARRAY_ALLOC(malloc, fDirP->num, sizeof ( int )); if ( appendDirList == NULL ) { return; /* if it fails we cannot do much */ } @@ -282,7 +283,7 @@ static void AddFontsToX11FontPath ( fDirRecord *fDirP ) } - newFontPath = malloc ( totalDirCount * sizeof ( char **) ); + newFontPath = SAFE_SIZE_ARRAY_ALLOC(malloc, totalDirCount, sizeof ( char **) ); /* if it fails free things and get out */ if ( newFontPath == NULL ) { free ( ( void *) appendDirList ); @@ -303,7 +304,12 @@ static void AddFontsToX11FontPath ( fDirRecord *fDirP ) /* printf ( "Appending %s\n", fDirP->name[index] ); */ - onePath = malloc ( ( strlen (fDirP->name[index]) + 2 )* sizeof( char ) ); + onePath = SAFE_SIZE_ARRAY_ALLOC(malloc, strlen (fDirP->name[index]) + 2, sizeof( char ) ); + if (onePath == NULL) { + free ( ( void *) appendDirList ); + XFreeFontPath ( origFontPath ); + return; + } strcpy ( onePath, fDirP->name[index] ); strcat ( onePath, "/" ); newFontPath[nPaths++] = onePath; diff --git a/src/solaris/native/sun/awt/gtk2_interface.c b/src/solaris/native/sun/awt/gtk2_interface.c index daca810e5..e1228fc90 100644 --- a/src/solaris/native/sun/awt/gtk2_interface.c +++ b/src/solaris/native/sun/awt/gtk2_interface.c @@ -31,6 +31,7 @@ #include "gtk2_interface.h" #include "java_awt_Transparency.h" #include "jvm_md.h" +#include "sizecalc.h" #define GTK2_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0") #define GTK2_LIB JNI_LIB_NAME("gtk-x11-2.0") @@ -765,7 +766,8 @@ gboolean gtk2_load() gtk_modules_env && strstr (gtk_modules_env, "gail")) { /* the new env will be smaller than the old one */ - gchar *s, *new_env = malloc (sizeof(ENV_PREFIX)+strlen (gtk_modules_env)); + gchar *s, *new_env = SAFE_SIZE_STRUCT_ALLOC(malloc, + sizeof(ENV_PREFIX), 1, strlen (gtk_modules_env)); if (new_env != NULL ) { diff --git a/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c b/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c index 08c5ec7dc..e43ebcaf2 100644 --- a/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c +++ b/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c @@ -41,6 +41,7 @@ #include #include #include +#include static Bool shapeSupported; static int shapeEventBase, shapeErrorBase; @@ -76,9 +77,12 @@ char* SplashConvertStringAlloc(const char* in, int* size) { goto done; } inSize = strlen(in); + buf = SAFE_SIZE_ARRAY_ALLOC(malloc, inSize, 2); + if (!buf) { + return NULL; + } bufSize = inSize*2; // need 2 bytes per char for UCS-2, this is // 2 bytes per source byte max - buf = malloc(bufSize); out = buf; outSize = bufSize; /* linux iconv wants char** source and solaris wants const char**... cast to void* */ @@ -114,12 +118,20 @@ SplashInitFrameShape(Splash * splash, int imageIndex) { initRect(&maskRect, 0, 0, splash->width, splash->height, 1, splash->width * splash->imageFormat.depthBytes, splash->frames[imageIndex].bitmapBits, &splash->imageFormat); - rects = - malloc(sizeof(XRectangle) * (splash->width / 2 + 1) * splash->height); + if (!IS_SAFE_SIZE_MUL(splash->width / 2 + 1, splash->height)) { + return; + } + rects = SAFE_SIZE_ARRAY_ALLOC(malloc, + sizeof(XRectangle), (splash->width / 2 + 1) * splash->height); + if (!rects) { + return; + } frame->numRects = BitmapToYXBandedRectangles(&maskRect, rects); - frame->rects = malloc(frame->numRects * sizeof(XRectangle)); - memcpy(frame->rects, rects, frame->numRects * sizeof(XRectangle)); + frame->rects = SAFE_SIZE_ARRAY_ALLOC(malloc, frame->numRects, sizeof(XRectangle)); + if (frame->rects) { // handle the error after the if(){} + memcpy(frame->rects, rects, frame->numRects * sizeof(XRectangle)); + } free(rects); } diff --git a/src/solaris/native/sun/xawt/XlibWrapper.c b/src/solaris/native/sun/xawt/XlibWrapper.c index f48e833ad..2b791e214 100644 --- a/src/solaris/native/sun/xawt/XlibWrapper.c +++ b/src/solaris/native/sun/xawt/XlibWrapper.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -2225,6 +2226,10 @@ Java_sun_awt_X11_XlibWrapper_SetBitmapShape RECT_T * pRect; int numrects; + if (!IS_SAFE_SIZE_MUL(width / 2 + 1, height)) { + return; + } + AWT_CHECK_HAVE_LOCK(); len = (*env)->GetArrayLength(env, bitmap); @@ -2237,7 +2242,10 @@ Java_sun_awt_X11_XlibWrapper_SetBitmapShape return; } - pRect = (RECT_T *)malloc(worstBufferSize * sizeof(RECT_T)); + pRect = (RECT_T *)SAFE_SIZE_ARRAY_ALLOC(malloc, worstBufferSize, sizeof(RECT_T)); + if (!pRect) { + return; + } /* Note: the values[0] and values[1] are supposed to contain the width * and height (see XIconInfo.getIntData() for details). So, we do +2. diff --git a/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c b/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c index 45950ff43..7ed415d25 100644 --- a/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c +++ b/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c @@ -37,6 +37,7 @@ #include #include #include +#include "sizecalc.h" #ifndef WS_EX_LAYERED #define WS_EX_LAYERED 0x80000 @@ -67,7 +68,10 @@ char* SplashConvertStringAlloc(const char* in, int *size) { len = strlen(in); outChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, len, NULL, 0); - buf = malloc(outChars*sizeof(WCHAR)); + buf = (WCHAR*) SAFE_SIZE_ARRAY_ALLOC(malloc, outChars, sizeof(WCHAR)); + if (!buf) { + return NULL; + } rc = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, len, buf, outChars); if (rc==0) { @@ -98,8 +102,14 @@ SplashInitFrameShape(Splash * splash, int imageIndex) return; /* reserving memory for the worst case */ - pRgnData = (RGNDATA *) malloc(sizeof(RGNDATAHEADER) + - sizeof(RECT) * (splash->width / 2 + 1) * splash->height); + if (!IS_SAFE_SIZE_MUL(splash->width / 2 + 1, splash->height)) { + return; + } + pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(malloc, sizeof(RGNDATAHEADER), + sizeof(RECT), (splash->width / 2 + 1) * splash->height); + if (!pRgnData) { + return; + } pRgnHdr = (RGNDATAHEADER *) pRgnData; initRect(&maskRect, 0, 0, splash->width, splash->height, 1, splash->width * splash->imageFormat.depthBytes, @@ -130,7 +140,6 @@ SplashPaint(Splash * splash, HDC hdc) { unsigned numColors = splash->screenFormat.colorMap ? splash->screenFormat.numColors : 0; - unsigned bmiSize; BITMAPV4HEADER *pBmi; HPALETTE hOldPal = NULL; @@ -138,8 +147,11 @@ SplashPaint(Splash * splash, HDC hdc) return; if (splash->currentFrame < 0 || splash->currentFrame >= splash->frameCount) return; - bmiSize = sizeof(BITMAPV4HEADER) + sizeof(RGBQUAD) * numColors; - pBmi = (BITMAPV4HEADER *) alloca(bmiSize); + pBmi = (BITMAPV4HEADER *) SAFE_SIZE_STRUCT_ALLOC(alloca, sizeof(BITMAPV4HEADER), + sizeof(RGBQUAD), numColors); + if (!pBmi) { + return; + } memset(pBmi, 0, sizeof(BITMAPV4HEADER)); if (splash->screenFormat.colorMap) memcpy(((BYTE *) pBmi) + sizeof(BITMAPV4HEADER), @@ -163,8 +175,11 @@ SplashPaint(Splash * splash, HDC hdc) here on demand */ if (!splash->hPalette) { unsigned i; - LOGPALETTE *pLogPal = - malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * numColors); + LOGPALETTE *pLogPal = (LOGPALETTE *) SAFE_SIZE_STRUCT_ALLOC(malloc, + sizeof(LOGPALETTE), sizeof(PALETTEENTRY), numColors); + if (!pLogPal) { + return; + } pLogPal->palVersion = 0x300; pLogPal->palNumEntries = (WORD) numColors; diff --git a/src/windows/native/sun/font/lcdglyph.c b/src/windows/native/sun/font/lcdglyph.c index 4f408d170..b24a305b8 100644 --- a/src/windows/native/sun/font/lcdglyph.c +++ b/src/windows/native/sun/font/lcdglyph.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include "fontscalerdefs.h" @@ -374,11 +375,11 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; - dibImageSize = dibBytesWidth*height; - dibImage = malloc(dibImageSize); + dibImage = SAFE_SIZE_ARRAY_ALLOC(malloc, dibBytesWidth, height); if (dibImage == NULL) { FREE_AND_RETURN; } + dibImageSize = dibBytesWidth*height; memset(dibImage, 0, dibImageSize); err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage, @@ -407,11 +408,12 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows * that extra "1" was added as padding, so the sub-pixel positioning of * fractional metrics could index into it. */ - imageSize = bytesWidth*height; - glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize); + glyphInfo = (GlyphInfo*)SAFE_SIZE_STRUCT_ALLOC(malloc, sizeof(GlyphInfo), + bytesWidth, height); if (glyphInfo == NULL) { FREE_AND_RETURN; } + imageSize = bytesWidth*height; glyphInfo->cellInfo = NULL; glyphInfo->rowBytes = bytesWidth; glyphInfo->width = width; diff --git a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c index cf68feb5f..ee553224b 100644 --- a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c +++ b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c @@ -30,6 +30,7 @@ #include "jni.h" #include "jlong.h" #include "jni_util.h" +#include "sizecalc.h" #include "OGLRenderQueue.h" #include "WGLGraphicsConfig.h" #include "WGLSurfaceData.h" @@ -603,7 +604,7 @@ JNIEXPORT jboolean JNICALL height = h; srcx = srcy = dstx = dsty = 0; - pDst = malloc(height * scanStride); + pDst = SAFE_SIZE_ARRAY_ALLOC(malloc, height, scanStride); if (pDst == NULL) { return JNI_FALSE; } diff --git a/src/windows/native/sun/java2d/windows/GDIBlitLoops.cpp b/src/windows/native/sun/java2d/windows/GDIBlitLoops.cpp index 5f8889777..271074c55 100644 --- a/src/windows/native/sun/java2d/windows/GDIBlitLoops.cpp +++ b/src/windows/native/sun/java2d/windows/GDIBlitLoops.cpp @@ -166,6 +166,7 @@ Java_sun_java2d_windows_GDIBlitLoops_nativeBlit // when using ByteGray surfaces. Eventually, we should use // the new Disposer mechanism to delete this native memory. if (byteGrayPalette == NULL) { + // assert (256 * sizeof(RGBQUAD)) <= SIZE_MAX byteGrayPalette = (RGBQUAD *)safe_Malloc(256 * sizeof(RGBQUAD)); for (int i = 0; i < 256; ++i) { byteGrayPalette[i].rgbRed = i; diff --git a/src/windows/native/sun/java2d/windows/GDIRenderer.cpp b/src/windows/native/sun/java2d/windows/GDIRenderer.cpp index 27a6a390f..33c6205a6 100644 --- a/src/windows/native/sun/java2d/windows/GDIRenderer.cpp +++ b/src/windows/native/sun/java2d/windows/GDIRenderer.cpp @@ -84,7 +84,7 @@ static POINT *TransformPoly(jint *xpoints, jint *ypoints, *pNpoints = outpoints; } if (outpoints > POLYTEMPSIZE) { - pPoints = (POINT *) safe_Malloc(sizeof(POINT) * outpoints); + pPoints = (POINT *) SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(POINT), outpoints); } BOOL isempty = fixend; for (int i = 0; i < npoints; i++) { diff --git a/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp b/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp index e4473d268..2d5532bcd 100644 --- a/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp +++ b/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp @@ -1056,8 +1056,9 @@ GDIWinSD_InitDC(JNIEnv *env, GDIWinSDOps *wsdo, ThreadGraphicsInfo *info, int topInset = wsdo->insets.top; Region_StartIteration(env, &clipInfo); jint numrects = Region_CountIterationRects(&clipInfo); - DWORD nCount = sizeof(RGNDATAHEADER) + numrects * sizeof(RECT); - RGNDATA *lpRgnData = (RGNDATA *) safe_Malloc(nCount); + RGNDATA *lpRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, + sizeof(RGNDATAHEADER), numrects, sizeof(RECT)); + const DWORD nCount = sizeof(RGNDATAHEADER) + numrects * sizeof(RECT); lpRgnData->rdh.dwSize = sizeof(RGNDATAHEADER); lpRgnData->rdh.iType = RDH_RECTANGLES; lpRgnData->rdh.nCount = numrects; diff --git a/src/windows/native/sun/windows/CmdIDList.cpp b/src/windows/native/sun/windows/CmdIDList.cpp index 3a036c8ed..b829af1e6 100644 --- a/src/windows/native/sun/windows/CmdIDList.cpp +++ b/src/windows/native/sun/windows/CmdIDList.cpp @@ -39,7 +39,7 @@ AwtCmdIDList::AwtCmdIDList() { m_capacity = ARRAY_INITIAL_SIZE; m_first_free = -1; - m_array = (CmdIDEntry *)safe_Malloc(m_capacity * sizeof(AwtObject*)); + m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, m_capacity, sizeof(AwtObject*)); BuildFreeList(0); } @@ -80,8 +80,8 @@ UINT AwtCmdIDList::Add(AwtObject* obj) m_capacity += ARRAY_SIZE_INCREMENT; if (m_capacity > ARRAY_MAXIMUM_SIZE) m_capacity = ARRAY_MAXIMUM_SIZE; - m_array = (CmdIDEntry *)safe_Realloc(m_array, - m_capacity * sizeof(CmdIDEntry*)); + m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array, + m_capacity, sizeof(CmdIDEntry*)); BuildFreeList(old_capacity); } } diff --git a/src/windows/native/sun/windows/Devices.cpp b/src/windows/native/sun/windows/Devices.cpp index 27299d34a..85ac51da3 100644 --- a/src/windows/native/sun/windows/Devices.cpp +++ b/src/windows/native/sun/windows/Devices.cpp @@ -171,8 +171,8 @@ Devices::Devices(int numDevices) J2dTraceLn1(J2D_TRACE_INFO, "Devices::Devices numDevices=%d", numDevices); this->numDevices = numDevices; this->refCount = 0; - devices = (AwtWin32GraphicsDevice**)safe_Malloc - (numDevices * sizeof(AwtWin32GraphicsDevice *)); + devices = (AwtWin32GraphicsDevice**)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, + numDevices, sizeof(AwtWin32GraphicsDevice *)); } /** @@ -188,7 +188,8 @@ BOOL Devices::UpdateInstance(JNIEnv *env) J2dTraceLn(J2D_TRACE_INFO, "Devices::UpdateInstance"); int numScreens = CountMonitors(); - HMONITOR *monHds = (HMONITOR *)safe_Malloc(numScreens * sizeof(HMONITOR)); + HMONITOR *monHds = (HMONITOR *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, + numScreens, sizeof(HMONITOR)); if (numScreens != CollectMonitors(monHds, numScreens)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "Devices::UpdateInstance: Failed to get all "\ diff --git a/src/windows/native/sun/windows/ShellFolder2.cpp b/src/windows/native/sun/windows/ShellFolder2.cpp index 7a18213d8..02e7a0681 100644 --- a/src/windows/native/sun/windows/ShellFolder2.cpp +++ b/src/windows/native/sun/windows/ShellFolder2.cpp @@ -393,6 +393,9 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_copyFirstPIDLEntry if (cb == 0) return 0; + if (!IS_SAFE_SIZE_ADD(cb, sizeof(SHITEMID))) { + return 0; + } // Allocate space for this as well as null-terminating entry. LPITEMIDLIST newPIDL = (LPITEMIDLIST)pMalloc->Alloc(cb + sizeof(SHITEMID)); @@ -433,6 +436,9 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_combinePIDLs int len1 = pidlLength(parentPIDL); int len2 = pidlLength(relativePIDL); + if (!IS_SAFE_SIZE_ADD(len1, len2) || !IS_SAFE_SIZE_ADD(len1 + len2, sizeof(SHITEMID))) { + return 0; + } LPITEMIDLIST newPIDL = (LPITEMIDLIST)pMalloc->Alloc(len1 + len2 + sizeof(SHITEMID)); memcpy(newPIDL, parentPIDL, len1); memcpy(((LPBYTE) newPIDL) + len1, relativePIDL, len2); diff --git a/src/windows/native/sun/windows/WPrinterJob.cpp b/src/windows/native/sun/windows/WPrinterJob.cpp index 37075266d..1d7b692c4 100644 --- a/src/windows/native/sun/windows/WPrinterJob.cpp +++ b/src/windows/native/sun/windows/WPrinterJob.cpp @@ -810,7 +810,7 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, int numSizes = ::DeviceCapabilities(printerName, printerPort, DC_PAPERS, NULL, NULL); if (numSizes > 0) { - LPTSTR papers = (LPTSTR)safe_Malloc(numSizes * sizeof(WORD)); + LPTSTR papers = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, numSizes, sizeof(WORD)); if (papers != NULL && ::DeviceCapabilities(printerName, printerPort, DC_PAPERS, papers, NULL) != -1) { diff --git a/src/windows/native/sun/windows/alloc.h b/src/windows/native/sun/windows/alloc.h index 527da4227..7b497e937 100644 --- a/src/windows/native/sun/windows/alloc.h +++ b/src/windows/native/sun/windows/alloc.h @@ -40,6 +40,9 @@ namespace std { class bad_alloc {}; } +#define SIZECALC_ALLOC_THROWING_BAD_ALLOC +#include "sizecalc.h" + class awt_toolkit_shutdown {}; // Disable "C++ Exception Specification ignored" warnings. diff --git a/src/windows/native/sun/windows/awt.h b/src/windows/native/sun/windows/awt.h index 0ae6511c2..42684be13 100644 --- a/src/windows/native/sun/windows/awt.h +++ b/src/windows/native/sun/windows/awt.h @@ -326,7 +326,7 @@ public: m_dwSize = cbTCharCount; m_pStr = (0 == m_dwSize) ? NULL - : (LPWSTR)safe_Malloc( (m_dwSize+1)*sizeof(WCHAR) ); + : (LPWSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (m_dwSize+1), sizeof(WCHAR) ); } JavaStringBuffer(JNIEnv *env, jstring text) { @@ -336,7 +336,7 @@ public: if (0 == m_dwSize) { m_pStr = NULL; } else { - m_pStr = (LPWSTR)safe_Malloc( (m_dwSize+1)*sizeof(WCHAR) ); + m_pStr = (LPWSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (m_dwSize+1), sizeof(WCHAR) ); env->GetStringRegion(text, 0, m_dwSize, reinterpret_cast(m_pStr)); m_pStr[m_dwSize] = 0; } @@ -353,7 +353,7 @@ public: //The function is used only for space reservation in staff buffer for //followed data copying process. And that is the reason why we ignore //the special case m_dwSize==0 here. - m_pStr = (LPWSTR)safe_Realloc(m_pStr, (m_dwSize+1)*sizeof(WCHAR) ); + m_pStr = (LPWSTR)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_pStr, m_dwSize+1, sizeof(WCHAR) ); } //we are in UNICODE now, so LPWSTR:=:LPTSTR operator LPWSTR() { return getNonEmptyString(); } diff --git a/src/windows/native/sun/windows/awt_BitmapUtil.cpp b/src/windows/native/sun/windows/awt_BitmapUtil.cpp index 4ca8eb0da..f75ee904b 100644 --- a/src/windows/native/sun/windows/awt_BitmapUtil.cpp +++ b/src/windows/native/sun/windows/awt_BitmapUtil.cpp @@ -39,13 +39,13 @@ HBITMAP BitmapUtil::CreateTransparencyMaskFromARGB(int width, int height, int* imageData) { //Scan lines should be aligned to word boundary - int bufLength = ((width + 15) / 16 * 2) * height;//buf length (bytes) + if (!IS_SAFE_SIZE_ADD(width, 15)) return NULL; + char* buf = SAFE_SIZE_NEW_ARRAY2(char, (width + 15) / 16 * 2, height); + if (buf == NULL) return NULL; int* srcPos = imageData; - char* buf = new char[bufLength]; char* bufPos = buf; int tmp = 0; int cbit = 0x80; - if (buf == NULL) return NULL; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { //cbit is shifted right for every pixel @@ -251,8 +251,12 @@ HRGN BitmapUtil::BitmapToRgn(HBITMAP hBitmap) reinterpret_cast(&bi), DIB_RGB_COLORS); /* reserving memory for the worst case */ - RGNDATA * pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) + - sizeof(RECT) * (width / 2 + 1) * height); + if (!IS_SAFE_SIZE_MUL(width / 2 + 1, height)) { + throw std::bad_alloc(); + } + RGNDATA * pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, + sizeof(RGNDATAHEADER), + sizeof(RECT), (width / 2 + 1) * height); RGNDATAHEADER * pRgnHdr = (RGNDATAHEADER *) pRgnData; pRgnHdr->dwSize = sizeof(RGNDATAHEADER); pRgnHdr->iType = RDH_RECTANGLES; diff --git a/src/windows/native/sun/windows/awt_Component.cpp b/src/windows/native/sun/windows/awt_Component.cpp index d6c4e974e..e929ba897 100644 --- a/src/windows/native/sun/windows/awt_Component.cpp +++ b/src/windows/native/sun/windows/awt_Component.cpp @@ -2186,12 +2186,12 @@ void AwtComponent::PaintUpdateRgn(const RECT *insets) if (insets != NULL) { ::OffsetRgn(rgn, insets->left, insets->top); } - int size = ::GetRegionData(rgn, 0, NULL); + DWORD size = ::GetRegionData(rgn, 0, NULL); if (size == 0) { ::DeleteObject((HGDIOBJ)rgn); return; } - char* buffer = new char[size]; + char* buffer = new char[size]; // safe because sizeof(char)==1 memset(buffer, 0, size); LPRGNDATA rgndata = (LPRGNDATA)buffer; rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); @@ -6134,18 +6134,30 @@ void AwtComponent::_SetRectangularShape(void *param) c = (AwtComponent *)pData; if (::IsWindow(c->GetHWnd())) { HRGN hRgn = NULL; + + // If all the params are zeros, the shape must be simply reset. + // Otherwise, convert it into a region. if (region || x1 || x2 || y1 || y2) { - // If all the params are zeros, the shape must be simply reset. - // Otherwise, convert it into a region. - RGNDATA *pRgnData = NULL; - RGNDATAHEADER *pRgnHdr; + RECT_T rects[256]; + RECT_T *pRect = rects; + + const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, + region, &pRect, sizeof(rects)/sizeof(rects[0])); + if (!pRect) { + // RegionToYXBandedRectangles doesn't use safe_Malloc(), + // so throw the exception explicitly + throw std::bad_alloc(); + } - /* reserving memory for the worst case */ - size_t worstBufferSize = size_t(((x2 - x1) / 2 + 1) * (y2 - y1)); - pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) + - sizeof(RECT_T) * worstBufferSize); - pRgnHdr = (RGNDATAHEADER *) pRgnData; + RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, + sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects); + memcpy(pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects); + if (pRect != rects) { + free(pRect); + } + pRect = NULL; + RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData; pRgnHdr->dwSize = sizeof(RGNDATAHEADER); pRgnHdr->iType = RDH_RECTANGLES; pRgnHdr->nRgnSize = 0; @@ -6153,9 +6165,7 @@ void AwtComponent::_SetRectangularShape(void *param) pRgnHdr->rcBound.left = 0; pRgnHdr->rcBound.bottom = LONG(y2 - y1); pRgnHdr->rcBound.right = LONG(x2 - x1); - - RECT_T * pRect = (RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER)); - pRgnHdr->nCount = RegionToYXBandedRectangles(env, x1, y1, x2, y2, region, &pRect, worstBufferSize); + pRgnHdr->nCount = numrects; hRgn = ::ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData); @@ -6297,7 +6307,7 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE); jsize len = env->GetArrayLength(obj); - AwtComponent::masks = new jint[len]; + AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len); for (int i = 0; i < len; i++) { AwtComponent::masks[i] = tmp[i]; } @@ -7184,4 +7194,5 @@ void ReleaseDCList(HWND hwnd, DCList &list) { removedDCs = removedDCs->next; delete tmpDCList; } -} \ No newline at end of file +} + diff --git a/src/windows/native/sun/windows/awt_Cursor.cpp b/src/windows/native/sun/windows/awt_Cursor.cpp index 64cdef9af..477fe80ee 100644 --- a/src/windows/native/sun/windows/awt_Cursor.cpp +++ b/src/windows/native/sun/windows/awt_Cursor.cpp @@ -345,14 +345,14 @@ Java_sun_awt_windows_WCustomCursor_createCursorIndirect( return; } - int length = env->GetArrayLength(andMask); - jbyte *andMaskPtr = new jbyte[length]; + jsize length = env->GetArrayLength(andMask); + jbyte *andMaskPtr = new jbyte[length]; // safe because sizeof(jbyte)==1 env->GetByteArrayRegion(andMask, 0, length, andMaskPtr); HBITMAP hMask = ::CreateBitmap(nW, nH, 1, 1, (BYTE *)andMaskPtr); ::GdiFlush(); - int *cols = new int[nW*nH]; + int *cols = SAFE_SIZE_NEW_ARRAY2(int, nW, nH); jint *intRasterDataPtr = NULL; HBITMAP hColor = NULL; diff --git a/src/windows/native/sun/windows/awt_DataTransferer.cpp b/src/windows/native/sun/windows/awt_DataTransferer.cpp index 835ccf9af..91bcad2d7 100644 --- a/src/windows/native/sun/windows/awt_DataTransferer.cpp +++ b/src/windows/native/sun/windows/awt_DataTransferer.cpp @@ -281,13 +281,13 @@ Java_sun_awt_windows_WDataTransferer_dragQueryFile } UINT bufsize = 512; // in characters, not in bytes - buffer = (LPTSTR)safe_Malloc(bufsize*sizeof(TCHAR)); + buffer = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, bufsize, sizeof(TCHAR)); for (UINT i = 0; i < nFilenames; i++) { UINT size = ::DragQueryFile(hdrop, i, NULL, 0); if (size > bufsize) { bufsize = size; - buffer = (LPTSTR)safe_Realloc(buffer, bufsize*sizeof(TCHAR)); + buffer = (LPTSTR)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, buffer, bufsize, sizeof(TCHAR)); } ::DragQueryFile(hdrop, i, buffer, bufsize); @@ -359,7 +359,7 @@ Java_sun_awt_windows_WDataTransferer_platformImageBytesToImageData( return NULL; } - jbyte* bBytes = (jbyte*)safe_Malloc(size * sizeof(jbyte)); + jbyte* bBytes = (jbyte*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, size, sizeof(jbyte)); try { @@ -771,9 +771,9 @@ Java_sun_awt_windows_WDataTransferer_imageDataToPlatformImageBytes(JNIEnv *env, } else { LPBYTE lpbMfBuffer = NULL; try { - UINT uMfSizeWithHead = uMfSize + sizeof(METAFILEPICT); - - lpbMfBuffer = (LPBYTE)safe_Malloc(uMfSizeWithHead); + lpbMfBuffer = (LPBYTE)SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, + sizeof(METAFILEPICT), uMfSize, 1); + const UINT uMfSizeWithHead = uMfSize + sizeof(METAFILEPICT); VERIFY(::GetMetaFileBitsEx(hmf, uMfSize, lpbMfBuffer + sizeof(METAFILEPICT)) == uMfSize); bytes = env->NewByteArray(uMfSizeWithHead); diff --git a/src/windows/native/sun/windows/awt_DesktopProperties.cpp b/src/windows/native/sun/windows/awt_DesktopProperties.cpp index 6b50ec15c..4c6e1f9bf 100644 --- a/src/windows/native/sun/windows/awt_DesktopProperties.cpp +++ b/src/windows/native/sun/windows/awt_DesktopProperties.cpp @@ -171,7 +171,7 @@ static LPTSTR getWindowsPropFromReg(LPTSTR subKey, LPTSTR valueName, DWORD *valu if (*valueType == REG_EXPAND_SZ) { // Pending: buffer must be null-terminated at this point valueChar = ExpandEnvironmentStrings(buffer, NULL, 0); - LPTSTR buffer2 = (LPTSTR)safe_Malloc(valueChar*sizeof(TCHAR)); + LPTSTR buffer2 = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, valueChar, sizeof(TCHAR)); ExpandEnvironmentStrings(buffer, buffer2, valueChar); free(buffer); return buffer2; @@ -588,11 +588,11 @@ void AwtDesktopProperties::GetOtherParameters() { } LPTSTR valueName = TEXT("PlaceN"); - LPTSTR valueNameBuf = (LPTSTR)safe_Malloc((lstrlen(valueName) + 1) * sizeof(TCHAR)); + LPTSTR valueNameBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(valueName) + 1), sizeof(TCHAR)); lstrcpy(valueNameBuf, valueName); LPTSTR propKey = TEXT("win.comdlg.placesBarPlaceN"); - LPTSTR propKeyBuf = (LPTSTR)safe_Malloc((lstrlen(propKey) + 1) * sizeof(TCHAR)); + LPTSTR propKeyBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(propKey) + 1), sizeof(TCHAR)); lstrcpy(propKeyBuf, propKey); int i = 0; diff --git a/src/windows/native/sun/windows/awt_DnDDT.cpp b/src/windows/native/sun/windows/awt_DnDDT.cpp index 734b2efea..230baf84c 100644 --- a/src/windows/native/sun/windows/awt_DnDDT.cpp +++ b/src/windows/native/sun/windows/awt_DnDDT.cpp @@ -1037,8 +1037,8 @@ void AwtDropTarget::LoadCache(IDataObject* pDataObj) { if (m_dataObject->QueryGetData(&tmp) != S_OK) continue; if (m_nformats % CACHE_INCR == 0) { - m_formats = (FORMATETC *)safe_Realloc(m_formats, - (CACHE_INCR + m_nformats) * + m_formats = (FORMATETC *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_formats, + CACHE_INCR + m_nformats, sizeof(FORMATETC)); } diff --git a/src/windows/native/sun/windows/awt_InputMethod.cpp b/src/windows/native/sun/windows/awt_InputMethod.cpp index b2d12c05a..9d81ea6af 100644 --- a/src/windows/native/sun/windows/awt_InputMethod.cpp +++ b/src/windows/native/sun/windows/awt_InputMethod.cpp @@ -333,7 +333,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale // list which is returned by GetKeyboardLayoutList ensures to match first when // looking up suitable layout. int layoutCount = ::GetKeyboardLayoutList(0, NULL) + 1; // +1 for user's preferred HKL - HKL FAR * hKLList = (HKL FAR *)safe_Malloc(sizeof(HKL)*layoutCount); + HKL FAR * hKLList = (HKL FAR *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(HKL), layoutCount); DASSERT(!safe_ExceptionOccurred(env)); ::GetKeyboardLayoutList(layoutCount - 1, &(hKLList[1])); hKLList[0] = getDefaultKeyboardLayout(); // put user's preferred layout on top of the list @@ -444,7 +444,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa // get list of available HKLs int layoutCount = ::GetKeyboardLayoutList(0, NULL); - HKL FAR * hKLList = (HKL FAR *)safe_Malloc(sizeof(HKL)*layoutCount); + HKL FAR * hKLList = (HKL FAR *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(HKL), layoutCount); DASSERT(!safe_ExceptionOccurred(env)); ::GetKeyboardLayoutList(layoutCount, hKLList); @@ -453,7 +453,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa int destIndex = 0; int javaLocaleNameCount = 0; int current = 0; - const char ** javaLocaleNames = (const char **)safe_Malloc(sizeof(char *)*layoutCount); + const char ** javaLocaleNames = (const char **)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(char *), layoutCount); DASSERT(!safe_ExceptionOccurred(env)); for (; srcIndex < layoutCount; srcIndex++) { const char * srcLocaleName = getJavaIDFromLangID(LOWORD(hKLList[srcIndex])); @@ -517,7 +517,7 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WInputMethod_getNativeIMMDescript jstring infojStr = NULL; if ((buffSize = ::ImmGetDescription(hkl, szImmDescription, 0)) > 0) { - szImmDescription = (LPTSTR) safe_Malloc((buffSize+1) * sizeof(TCHAR)); + szImmDescription = (LPTSTR) SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (buffSize+1), sizeof(TCHAR)); if (szImmDescription != NULL) { ImmGetDescription(hkl, szImmDescription, (buffSize+1)); diff --git a/src/windows/native/sun/windows/awt_PrintControl.cpp b/src/windows/native/sun/windows/awt_PrintControl.cpp index 236149714..400583599 100644 --- a/src/windows/native/sun/windows/awt_PrintControl.cpp +++ b/src/windows/native/sun/windows/awt_PrintControl.cpp @@ -484,8 +484,8 @@ WORD AwtPrintControl::getNearestMatchingPaper(LPTSTR printer, LPTSTR port, NULL, NULL); if (numPaperSizes > 0) { - papers = (WORD*)safe_Malloc(sizeof(WORD) * numPaperSizes); - paperSizes = (POINT *)safe_Malloc(sizeof(*paperSizes) * + papers = (WORD*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(WORD), numPaperSizes); + paperSizes = (POINT *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(*paperSizes), numPaperSizes); DWORD result1 = DeviceCapabilities(printer, port, diff --git a/src/windows/native/sun/windows/awt_PrintJob.cpp b/src/windows/native/sun/windows/awt_PrintJob.cpp index 0d5374747..a2deb14b5 100644 --- a/src/windows/native/sun/windows/awt_PrintJob.cpp +++ b/src/windows/native/sun/windows/awt_PrintJob.cpp @@ -433,7 +433,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) int measure = PSD_INTHOUSANDTHSOFINCHES; int sz = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, NULL, 0); if (sz > 0) { - LPTSTR str = (LPTSTR)safe_Malloc(sizeof(TCHAR) * sz); + LPTSTR str = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(TCHAR), sz); if (str != NULL) { sz = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, str, sz); if (sz > 0) { @@ -645,7 +645,7 @@ Java_sun_awt_windows_WPrinterJob_getDefaultPage(JNIEnv *env, jobject self, int sz = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, NULL, 0); if (sz > 0) { - LPTSTR str = (LPTSTR)safe_Malloc(sizeof(TCHAR) * sz); + LPTSTR str = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(TCHAR), sz); if (str != NULL) { sz = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, str, sz); @@ -2302,8 +2302,8 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_textOut * rounded advances will drift away from the true advance. */ if (glyphPos != NULL && strLen > 0) { - xadvances = (int*)safe_Malloc(strLen * sizeof(int)); - xyadvances = (int*)safe_Malloc(strLen * sizeof(int) * 2); + xadvances = (int*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, strLen, sizeof(int)); + xyadvances = (int*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, strLen, sizeof(int) * 2); } if (xadvances != NULL && xyadvances != NULL) { int *inxAdvances = xadvances; @@ -2513,8 +2513,9 @@ static jbyte* reverseDIB(jbyte* imageBits, long srcWidth, long srcHeight, if ((imgWidthByteSz % sizeof(DWORD)) != 0) padBytes = sizeof(DWORD) - (imgWidthByteSz % sizeof(DWORD)); + jbyte* alignedImage = (jbyte*) SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, + imgWidthByteSz+padBytes, ROUND_TO_LONG(srcHeight)); long newImgSize = (imgWidthByteSz+padBytes) * ROUND_TO_LONG(srcHeight); - jbyte* alignedImage = (jbyte*) safe_Malloc(newImgSize); if (alignedImage != NULL) { memset(alignedImage, 0xff, newImgSize); @@ -3116,7 +3117,7 @@ static POINT *getPaperSizeList(LPCTSTR deviceName, LPCTSTR portName) { DC_PAPERSIZE, NULL, NULL); if (numPaperSizes > 0) { - paperSizes = (POINT *)safe_Malloc(sizeof(*paperSizes) * numPaperSizes); + paperSizes = (POINT *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(*paperSizes), numPaperSizes); DWORD result = DeviceCapabilities(deviceName, portName, DC_PAPERSIZE, (LPTSTR) paperSizes, @@ -3766,8 +3767,8 @@ static void matchPaperSize(HDC printDC, HGLOBAL hDevMode, HGLOBAL hDevNames, numPaperSizes = (int)DeviceCapabilities(printer, port, DC_PAPERSIZE, NULL, NULL); if (numPaperSizes > 0) { - papers = (WORD*)safe_Malloc(sizeof(WORD) * numPaperSizes); - paperSizes = (POINT *)safe_Malloc(sizeof(*paperSizes) * numPaperSizes); + papers = (WORD*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(WORD), numPaperSizes); + paperSizes = (POINT *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(*paperSizes), numPaperSizes); DWORD result1 = DeviceCapabilities(printer, port, DC_PAPERS, (LPTSTR) papers, NULL); diff --git a/src/windows/native/sun/windows/awt_Robot.cpp b/src/windows/native/sun/windows/awt_Robot.cpp index 09e12debf..c2d3726fa 100644 --- a/src/windows/native/sun/windows/awt_Robot.cpp +++ b/src/windows/native/sun/windows/awt_Robot.cpp @@ -234,7 +234,9 @@ void AwtRobot::GetRGBPixels(jint x, jint y, jint width, jint height, jintArray p static const int BITS_PER_PIXEL = 32; static const int BYTES_PER_PIXEL = BITS_PER_PIXEL/8; + if (!IS_SAFE_SIZE_MUL(width, height)) throw std::bad_alloc(); int numPixels = width*height; + if (!IS_SAFE_SIZE_MUL(BYTES_PER_PIXEL, numPixels)) throw std::bad_alloc(); int pixelDataSize = BYTES_PER_PIXEL*numPixels; DASSERT(pixelDataSize > 0 && pixelDataSize % 4 == 0); // allocate memory for BITMAPINFO + pixel data @@ -244,6 +246,9 @@ void AwtRobot::GetRGBPixels(jint x, jint y, jint width, jint height, jintArray p // end of our block of memory. Now we allocate sufficient memory. // See MSDN docs for BITMAPINFOHEADER -bchristi + if (!IS_SAFE_SIZE_ADD(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD), pixelDataSize)) { + throw std::bad_alloc(); + } BITMAPINFO * pinfo = (BITMAPINFO *)(new BYTE[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD) + pixelDataSize]); // pixel data starts after 3 RGBQUADS for color masks -- GitLab