diff --git a/src/windows/native/sun/windows/CmdIDList.cpp b/src/windows/native/sun/windows/CmdIDList.cpp index a71ede3d3812826dbc63ee7cec6c4531d10735fd..138f3e980754cc1f82bf07f5203e19e955b9a0af 100644 --- a/src/windows/native/sun/windows/CmdIDList.cpp +++ b/src/windows/native/sun/windows/CmdIDList.cpp @@ -61,29 +61,36 @@ INLINE void AwtCmdIDList::BuildFreeList(UINT first_index) m_first_free = first_index; // head of the free list } + +jboolean AwtCmdIDList::isFreeIDAvailable() { + CriticalSection::Lock l(m_lock); + + if (m_first_free == -1) { // out of free ids + if (m_capacity == ARRAY_MAXIMUM_SIZE) { + return JNI_FALSE; + } + } + return JNI_TRUE; +} + // Assign an id to the object. Recycle the first free entry from the // head of the free list or allocate more memory for a new free list. UINT AwtCmdIDList::Add(AwtObject* obj) { CriticalSection::Lock l(m_lock); + if (!isFreeIDAvailable()) { + throw std::bad_alloc(); // fatal error + } if (m_first_free == -1) { // out of free ids - if (m_capacity == ARRAY_MAXIMUM_SIZE) { - // Really bad - out of ids. Since we hardly can have *so* - // many items simultaneously in existence, we have an id - // leak somewhere. - DASSERT(FALSE); - return 0; - } - else { // snarf a bigger arena - UINT old_capacity = m_capacity; // will be the first free entry - m_capacity += ARRAY_SIZE_INCREMENT; - if (m_capacity > ARRAY_MAXIMUM_SIZE) - m_capacity = ARRAY_MAXIMUM_SIZE; - m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array, - m_capacity, sizeof(CmdIDEntry*)); - BuildFreeList(old_capacity); - } + // snarf a bigger arena + UINT old_capacity = m_capacity; // will be the first free entry + m_capacity += ARRAY_SIZE_INCREMENT; + if (m_capacity > ARRAY_MAXIMUM_SIZE) + m_capacity = ARRAY_MAXIMUM_SIZE; + m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array, + m_capacity, sizeof(CmdIDEntry*)); + BuildFreeList(old_capacity); } DASSERT(m_first_free != -1); diff --git a/src/windows/native/sun/windows/CmdIDList.h b/src/windows/native/sun/windows/CmdIDList.h index 3677b6dcf0490a9635732a67cdd207e652dc7736..15b032e625d57e30191ddc4fe979513c2820b19f 100644 --- a/src/windows/native/sun/windows/CmdIDList.h +++ b/src/windows/native/sun/windows/CmdIDList.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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 @@ -38,6 +38,7 @@ public: UINT Add(AwtObject* obj); AwtObject* Lookup(UINT id); void Remove(UINT id); + jboolean isFreeIDAvailable(); CriticalSection m_lock; diff --git a/src/windows/native/sun/windows/awt_MenuItem.cpp b/src/windows/native/sun/windows/awt_MenuItem.cpp index 36b395c2501083954f2f73a7d8da7cfed30f23b7..580062c5cf5ce55ba4ab5a43f273959614e09233 100644 --- a/src/windows/native/sun/windows/awt_MenuItem.cpp +++ b/src/windows/native/sun/windows/awt_MenuItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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 @@ -217,6 +217,10 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer) if (env->EnsureLocalCapacity(1) < 0) { return NULL; } + if (!AwtToolkit::GetInstance().isFreeIDAvailable()) { + return NULL; + } + JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer"); /* target is a java.awt.MenuItem */ diff --git a/src/windows/native/sun/windows/awt_Toolkit.cpp b/src/windows/native/sun/windows/awt_Toolkit.cpp index dcb4ea71f8db4b0262a737f56b73189c0d9e91cf..4c657ad94d2ea175113909efc1b15d3504d63536 100644 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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 @@ -1583,6 +1583,11 @@ void AwtToolkit::SyncCall(void (*ftn)(void)) { } } +jboolean AwtToolkit::isFreeIDAvailable() +{ + return m_cmdIDs->isFreeIDAvailable(); +} + UINT AwtToolkit::CreateCmdID(AwtObject* object) { return m_cmdIDs->Add(object); diff --git a/src/windows/native/sun/windows/awt_Toolkit.h b/src/windows/native/sun/windows/awt_Toolkit.h index 3782aac8cf7bea8a637d11e6a08c6072a0d528a4..e0de73d0608950225849fbbac137914eab8258d2 100644 --- a/src/windows/native/sun/windows/awt_Toolkit.h +++ b/src/windows/native/sun/windows/awt_Toolkit.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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 @@ -317,6 +317,8 @@ public: BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg); BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg); + /* Checks that an free ID exists. */ + jboolean isFreeIDAvailable(); /* Create an ID which maps to an AwtObject pointer, such as a menu. */ UINT CreateCmdID(AwtObject* object);