From 06c379e859be3678183feec8ba4b680fe0b4172f Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Tue, 19 Apr 2011 10:11:58 +0400 Subject: [PATCH 01/32] 7036025: java.security.AccessControlException when creating JFileChooser in signed applet Reviewed-by: malenkov --- .../classes/sun/swing/WindowsPlacesBar.java | 9 ++- .../JFileChooser/7036025/bug7036025.java | 62 +++++++++++++++++++ .../JFileChooser/7036025/security.policy | 5 ++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java create mode 100644 jdk/test/javax/swing/JFileChooser/7036025/security.policy diff --git a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java index 9972b671d75..a05259e5978 100644 --- a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java +++ b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java @@ -29,6 +29,8 @@ import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.swing.*; import javax.swing.border.*; @@ -79,7 +81,12 @@ public class WindowsPlacesBar extends JToolBar setBackground(bgColor); FileSystemView fsv = fc.getFileSystemView(); - files = (File[])ShellFolder.get("fileChooserShortcutPanelFolders"); + files = AccessController.doPrivileged(new PrivilegedAction() { + public File[] run() { + return (File[]) ShellFolder.get("fileChooserShortcutPanelFolders"); + } + }); + buttons = new JToggleButton[files.length]; buttonGroup = new ButtonGroup(); for (int i = 0; i < files.length; i++) { diff --git a/jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java b/jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java new file mode 100644 index 00000000000..dd7b003a01f --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011, 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. + * + * 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. + */ + +/* @test + @bug 7036025 + @summary java.security.AccessControlException when creating JFileChooser in signed applet + @author Pavel Porvatov + @run main/othervm/policy=security.policy bug7036025 +*/ + +import javax.swing.*; +import java.io.File; + +public class bug7036025 { + public static final String DIR = "c:/temp"; + + public static void main(String[] args) throws Exception { + String systemLookAndFeelClassName = UIManager.getSystemLookAndFeelClassName(); + + if (!systemLookAndFeelClassName.toLowerCase().contains("windows")) { + System.out.println("The test is only for Windows OS."); + + return; + } + + File file = new File(DIR); + + if (!file.exists()) { + if (!file.mkdir()) { + throw new RuntimeException("Cannot create " + DIR); + } + + file.deleteOnExit(); + } + + UIManager.setLookAndFeel(systemLookAndFeelClassName); + + new JFileChooser(file); + + System.out.println("Test passed for LookAndFeel " + UIManager.getLookAndFeel().getName()); + } +} diff --git a/jdk/test/javax/swing/JFileChooser/7036025/security.policy b/jdk/test/javax/swing/JFileChooser/7036025/security.policy new file mode 100644 index 00000000000..57e0bd2af52 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/7036025/security.policy @@ -0,0 +1,5 @@ +grant { + permission java.io.FilePermission "C:\\temp\\*", "read"; + permission java.io.FilePermission "C:\\temp", "read,write,delete"; + permission java.util.PropertyPermission "*", "read"; +}; From 89d504b32f618ac6beecf8aa773fe94d09c1f5bb Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 19 Apr 2011 14:44:09 +0400 Subject: [PATCH 02/32] 7036669: Simplify revalidating component hierarchy with multiple validate roots Introduce Component.revalidate() method Reviewed-by: art, alexp --- jdk/src/share/classes/java/awt/Component.java | 40 ++++++ .../plaf/basic/BasicSplitPaneDivider.java | 6 +- .../awt/Component/Revalidate/Revalidate.java | 122 ++++++++++++++++++ 3 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/Component/Revalidate/Revalidate.java diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 5b572797d84..f577887abe6 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -2944,6 +2944,46 @@ public abstract class Component implements ImageObserver, MenuContainer, } } + /** + * Revalidates the component hierarchy up to the nearest validate root. + *

+ * This method first invalidates the component hierarchy starting from this + * component up to the nearest validate root. Afterwards, the component + * hierarchy is validated starting from the nearest validate root. + *

+ * This is a convenience method supposed to help application developers + * avoid looking for validate roots manually. Basically, it's equivalent to + * first calling the {@link #invalidate()} method on this component, and + * then calling the {@link #validate()} method on the nearest validate + * root. + * + * @see Container#isValidateRoot + * @since 1.7 + */ + public void revalidate() { + synchronized (getTreeLock()) { + invalidate(); + + Container root = getContainer(); + if (root == null) { + // There's no parents. Just validate itself. + validate(); + } else { + while (!root.isValidateRoot()) { + if (root.getContainer() == null) { + // If there's no validate roots, we'll validate the + // topmost container + break; + } + + root = root.getContainer(); + } + + root.validate(); + } + } + } + /** * Creates a graphics context for this component. This method will * return null if this component is currently not diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 42c88e02823..70b0bffaac7 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -154,7 +154,7 @@ public class BasicSplitPaneDivider extends Container setBackground(UIManager.getColor("SplitPane.background")); } - private void revalidate() { + private void revalidateSplitPane() { invalidate(); if (splitPane != null) { splitPane.revalidate(); @@ -315,7 +315,7 @@ public class BasicSplitPaneDivider extends Container setCursor((orientation == JSplitPane.HORIZONTAL_SPLIT) ? Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); - revalidate(); + revalidateSplitPane(); } else if (e.getPropertyName() == JSplitPane. ONE_TOUCH_EXPANDABLE_PROPERTY) { @@ -376,7 +376,7 @@ public class BasicSplitPaneDivider extends Container add(rightButton); } } - revalidate(); + revalidateSplitPane(); } diff --git a/jdk/test/java/awt/Component/Revalidate/Revalidate.java b/jdk/test/java/awt/Component/Revalidate/Revalidate.java new file mode 100644 index 00000000000..670c374f87d --- /dev/null +++ b/jdk/test/java/awt/Component/Revalidate/Revalidate.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011, 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. + * + * 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. + */ + +/* + @test + @bug 7036669 + @summary Test Component.revalidate() method + @author anthony.petrov@oracle.com: area=awt.component + @run main Revalidate +*/ + +import java.awt.*; + +public class Revalidate { + private static Frame frame = new Frame(); + private static Panel panel = new Panel() { + @Override + public boolean isValidateRoot() { + return true; + } + }; + private static Button button = new Button("Test"); + + private static void sleep() { + try { Thread.sleep(500); } catch (Exception e) {} + } + + private static void printState(String str) { + System.out.println(str + " isValid state: "); + System.out.println(" frame: " + frame.isValid()); + System.out.println(" panel: " + panel.isValid()); + System.out.println(" button: " + button.isValid()); + } + + private static void fail(String msg) { + frame.dispose(); + throw new RuntimeException(msg); + } + + private static void check(String n, Component c, boolean v) { + if (c.isValid() != v) { + fail(n + ".isValid() = " + c.isValid() + "; expected: " + v); + } + } + private static void check(String str, boolean f, boolean p, boolean b) { + printState(str); + + check("frame", frame, f); + check("panel", panel, p); + check("button", button, b); + } + + public static void main(String[] args) { + // setup + frame.add(panel); + panel.add(button); + frame.setBounds(200, 200, 300, 200); + frame.setVisible(true); + sleep(); + check("Upon showing", true, true, true); + + button.setBounds(1, 1, 30, 30); + sleep(); + check("button.setBounds():", true, false, false); + + button.revalidate(); + sleep(); + check("button.revalidate():", true, true, true); + + button.setBounds(1, 1, 30, 30); + sleep(); + check("button.setBounds():", true, false, false); + + panel.revalidate(); + sleep(); + // because the panel's validate root is actually OK + check("panel.revalidate():", true, false, false); + + button.revalidate(); + sleep(); + check("button.revalidate():", true, true, true); + + panel.setBounds(2, 2, 125, 130); + sleep(); + check("panel.setBounds():", false, false, true); + + button.revalidate(); + sleep(); + check("button.revalidate():", false, true, true); + + panel.setBounds(3, 3, 152, 121); + sleep(); + check("panel.setBounds():", false, false, true); + + panel.revalidate(); + sleep(); + check("panel.revalidate():", true, true, true); + + // cleanup + frame.dispose(); + } +} From d097a2cab142e19c36b1d8c4ca5455eb125ba719 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Tue, 19 Apr 2011 18:52:49 +0400 Subject: [PATCH 03/32] 7036733: Regression : NullPointerException when scrolling horizontally on AWT List Reviewed-by: dcherepanov --- .../classes/sun/awt/X11/XListPeer.java | 5 +- .../awt/List/ScrollOutside/ScrollOut.java | 84 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/List/ScrollOutside/ScrollOut.java diff --git a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java index c8799a1ad07..838899e49b8 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java @@ -1479,16 +1479,19 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { int h = height - (SCROLLBAR_AREA + (2 * MARGIN)); hsb.setValue(hsb.getValue() + x); + int options = PAINT_ITEMS | PAINT_HSCROLL; + Rectangle source = null; Point distance = null; if (x < 0) { source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h); distance = new Point(-x, 0); + options |= COPY_AREA; } else if (x > 0) { source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h); distance = new Point(-x, 0); + options |= COPY_AREA; } - int options = COPY_AREA | PAINT_ITEMS | PAINT_HSCROLL; repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance); } diff --git a/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java b/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java new file mode 100644 index 00000000000..21b8f848229 --- /dev/null +++ b/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 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. + * + * 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. + */ + +/* + @test + @bug 7036733 + @summary Regression : NullPointerException when scrolling horizontally on AWT List + @author Andrei Dmitriev area=awt-list + @library ../../regtesthelpers + @build Util + @run main ScrollOut +*/ + +import java.awt.*; +import java.awt.event.*; +import sun.awt.SunToolkit; +import test.java.awt.regtesthelpers.Util; + +public class ScrollOut +{ + public static final void main(String args[]) + { + final Frame frame = new Frame(); + final List list = new List(); + Robot robot = null; + + for (int i = 0; i < 5; i++){ + list.add("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + } + + frame.add(list); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + try{ + robot = new Robot(); + }catch(AWTException e){ + throw new RuntimeException(e); + } + + //Drag from center to the outside on left + Point from = new Point(list.getLocationOnScreen().x + list.getWidth()/2, + list.getLocationOnScreen().y + list.getHeight()/2); + Point to = new Point(list.getLocationOnScreen().x - 30, + from.y); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Util.drag(robot, from, to, InputEvent.BUTTON1_MASK); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + //Drag from center to the outside on up + to = new Point(from.x, + list.getLocationOnScreen().y - 50); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Util.drag(robot, from, to, InputEvent.BUTTON1_MASK); + + }//End init() +} From e45512128a063241bb4de8c1463aa7fc11016cf7 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 20 Apr 2011 16:46:31 +0400 Subject: [PATCH 04/32] 7030629: closed/sun/audio/AudioClipClose/AudioClipClose.java test fails just against jdk7 b134 7033899: SoundTestSuite: test050 fails on Ubuntu Linux Reviewed-by: bae --- .../sound/PLATFORM_API_LinuxOS_ALSA_PCM.c | 56 ++++++++++++++++--- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c index fb2ba3c5da3..0c5784bc496 100644 --- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c +++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c @@ -239,6 +239,13 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre snd_pcm_close(handle); } +/** Workaround for cr 7033899, 7030629: + * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty + * (just opened, underruned or already flushed). + * Sometimes it causes PCM falls to -EBADFD error, + * sometimes causes bufferSize change. + * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used. + */ /* ******* ALSA PCM INFO ******************** */ typedef struct tag_AlsaPcmInfo { snd_pcm_t* handle; @@ -248,6 +255,8 @@ typedef struct tag_AlsaPcmInfo { int frameSize; // storage size in Bytes unsigned int periods; snd_pcm_uframes_t periodSize; + short int isRunning; // see comment above + short int isFlushed; // see comment above #ifdef GET_POSITION_METHOD2 // to be used exclusively by getBytePosition! snd_pcm_status_t* positionStatus; @@ -432,6 +441,9 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, return NULL; } memset(info, 0, sizeof(AlsaPcmInfo)); + // initial values are: stopped, flushed + info->isRunning = 0; + info->isFlushed = 1; ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/); if (ret == 0) { @@ -587,6 +599,14 @@ int DAUDIO_Start(void* id, int isSource) { || (state == SND_PCM_STATE_RUNNING) || (state == SND_PCM_STATE_XRUN) || (state == SND_PCM_STATE_SUSPENDED); + if (ret) { + info->isRunning = 1; + // source line should keep isFlushed value until Write() is called; + // for target data line reset it right now. + if (!isSource) { + info->isFlushed = 0; + } + } TRACE1("< DAUDIO_Start %s\n", ret?"success":"error"); return ret?TRUE:FALSE; } @@ -606,6 +626,7 @@ int DAUDIO_Stop(void* id, int isSource) { ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret)); return FALSE; } + info->isRunning = 0; TRACE0("< DAUDIO_Stop success\n"); return TRUE; } @@ -651,8 +672,7 @@ int xrun_recovery(AlsaPcmInfo* info, int err) { return -1; } return 1; - } - else if (err == -ESTRPIPE) { + } else if (err == -ESTRPIPE) { TRACE0("xrun_recovery: suspended.\n"); ret = snd_pcm_resume(info->handle); if (ret < 0) { @@ -667,11 +687,11 @@ int xrun_recovery(AlsaPcmInfo* info, int err) { return -1; } return 1; - } - else if (err == -EAGAIN) { + } else if (err == -EAGAIN) { TRACE0("xrun_recovery: EAGAIN try again flag.\n"); return 0; } + TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err)); return -1; } @@ -691,6 +711,7 @@ int DAUDIO_Write(void* id, char* data, int byteSize) { TRACE0("< DAUDIO_Write returning -1\n"); return -1; } + count = 2; // maximum number of trials to recover from underrun //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize); frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize); @@ -712,6 +733,12 @@ int DAUDIO_Write(void* id, char* data, int byteSize) { } } while (TRUE); //ret = snd_pcm_frames_to_bytes(info->handle, writtenFrames); + + if (writtenFrames > 0) { + // reset "flushed" flag + info->isFlushed = 0; + } + ret = (int) (writtenFrames * info->frameSize); TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret); return ret; @@ -736,6 +763,11 @@ int DAUDIO_Read(void* id, char* data, int byteSize) { TRACE0("< DAUDIO_Read returning -1\n"); return -1; } + if (!info->isRunning && info->isFlushed) { + // PCM has nothing to read + return 0; + } + count = 2; // maximum number of trials to recover from error //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize); frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize); @@ -784,12 +816,22 @@ int DAUDIO_Flush(void* id, int isSource) { int ret; TRACE0("DAUDIO_Flush\n"); + + if (info->isFlushed) { + // nothing to drop + return 1; + } + ret = snd_pcm_drop(info->handle); if (ret != 0) { ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret)); return FALSE; } - ret = DAUDIO_Start(id, isSource); + + info->isFlushed = 1; + if (info->isRunning) { + ret = DAUDIO_Start(id, isSource); + } return ret; } @@ -800,7 +842,7 @@ int DAUDIO_GetAvailable(void* id, int isSource) { int ret; state = snd_pcm_state(info->handle); - if (state == SND_PCM_STATE_XRUN) { + if (info->isFlushed || state == SND_PCM_STATE_XRUN) { // if in xrun state then we have the entire buffer available, // not 0 as alsa reports ret = info->bufferSizeInBytes; @@ -841,7 +883,7 @@ INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) { snd_pcm_state_t state; state = snd_pcm_state(info->handle); - if (state != SND_PCM_STATE_XRUN) { + if (!info->isFlushed && state != SND_PCM_STATE_XRUN) { #ifdef GET_POSITION_METHOD2 snd_timestamp_t* ts; snd_pcm_uframes_t framesAvail; From f3c1d5f3ea80220483e024f9f3fffa80063f5267 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Wed, 20 Apr 2011 09:10:36 -0700 Subject: [PATCH 05/32] 6989724: font warnings in the build, native code Reviewed-by: bae, igor --- .../share/native/sun/awt/giflib/dgif_lib.c | 2 +- .../share/native/sun/font/fontscalerdefs.h | 4 +++- .../sun/font/layout/HangulLayoutEngine.cpp | 2 +- .../native/sun/font/layout/MPreFixups.cpp | 4 ++-- jdk/src/solaris/native/sun/awt/fontpath.c | 3 ++- jdk/src/windows/native/sun/font/fontpath.c | 24 +++++++++---------- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/jdk/src/share/native/sun/awt/giflib/dgif_lib.c b/jdk/src/share/native/sun/awt/giflib/dgif_lib.c index b566e7e1cc1..742ae9c3335 100644 --- a/jdk/src/share/native/sun/awt/giflib/dgif_lib.c +++ b/jdk/src/share/native/sun/awt/giflib/dgif_lib.c @@ -70,7 +70,7 @@ /* avoid extra function call in case we use fread (TVT) */ #define READ(_gif,_buf,_len) \ (((GifFilePrivateType*)_gif->Private)->Read ? \ - ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ + (size_t)((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File)) static int DGifGetWord(GifFileType *GifFile, int *Word); diff --git a/jdk/src/share/native/sun/font/fontscalerdefs.h b/jdk/src/share/native/sun/font/fontscalerdefs.h index 4e1bb99e9c3..8f142752af9 100644 --- a/jdk/src/share/native/sun/font/fontscalerdefs.h +++ b/jdk/src/share/native/sun/font/fontscalerdefs.h @@ -55,13 +55,15 @@ typedef Int32 hsFixed; typedef Int32 hsFract; typedef UInt32 Bool32; +#ifndef __cplusplus #ifndef false - #define false 0 + #define false 0 #endif #ifndef true #define true 1 #endif +#endif #define kPosInfinity32 (0x7fffffff) #define kNegInfinity32 (0x80000000) diff --git a/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp b/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp index 806f2dc5813..adc30bd526d 100644 --- a/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp +++ b/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp @@ -162,7 +162,7 @@ static le_int32 decompose(LEUnicode syllable, LEUnicode &lead, LEUnicode &vowel, return 0; } - lead = LJMO_FIRST + (sIndex / HSYL_LVCNT); + lead = (LEUnicode)(LJMO_FIRST + (sIndex / HSYL_LVCNT)); vowel = VJMO_FIRST + (sIndex % HSYL_LVCNT) / TJMO_COUNT; trail = TJMO_FIRST + (sIndex % TJMO_COUNT); diff --git a/jdk/src/share/native/sun/font/layout/MPreFixups.cpp b/jdk/src/share/native/sun/font/layout/MPreFixups.cpp index 673ea32ca16..254b3b01ace 100644 --- a/jdk/src/share/native/sun/font/layout/MPreFixups.cpp +++ b/jdk/src/share/native/sun/font/layout/MPreFixups.cpp @@ -65,9 +65,9 @@ void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex) } } -void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success) +void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& leSuccess) { - if (LE_FAILURE(success)) { + if (LE_FAILURE(leSuccess)) { return; } diff --git a/jdk/src/solaris/native/sun/awt/fontpath.c b/jdk/src/solaris/native/sun/awt/fontpath.c index 68c352db16c..98d6f1419fc 100644 --- a/jdk/src/solaris/native/sun/awt/fontpath.c +++ b/jdk/src/solaris/native/sun/awt/fontpath.c @@ -1107,7 +1107,8 @@ Java_sun_font_FontConfigManager_getFontConfig arrlen = (*env)->GetArrayLength(env, fcCompFontArray); for (i=0; iNewString(env, lpelfe->elfFullName, - wcslen((LPWSTR)lpelfe->elfFullName)); + (jsize)wcslen((LPWSTR)lpelfe->elfFullName)); fullnameLC = (*env)->CallObjectMethod(env, fullname, fmi->toLowerCaseMID, fmi->locale); (*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname); @@ -314,7 +314,7 @@ static int CALLBACK EnumFamilyNamesW( GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam; JNIEnv *env = fmi->env; jstring familyLC; - int slen; + size_t slen; LOGFONTW lfw; /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */ @@ -336,7 +336,7 @@ static int CALLBACK EnumFamilyNamesW( return 1; } slen = wcslen(lpelfe->elfLogFont.lfFaceName); - fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, slen); + fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, (jsize)slen); familyLC = (*env)->CallObjectMethod(env, fmi->family, fmi->toLowerCaseMID, fmi->locale); /* check if already seen this family with a different charset */ @@ -386,10 +386,10 @@ static int CALLBACK EnumFamilyNamesW( static BOOL RegistryToBaseTTNameA(LPSTR name) { static const char TTSUFFIX[] = " (TrueType)"; static const char OTSUFFIX[] = " (OpenType)"; - int TTSLEN = strlen(TTSUFFIX); + size_t TTSLEN = strlen(TTSUFFIX); char *suffix; - int len = strlen(name); + size_t len = strlen(name); if (len == 0) { return FALSE; } @@ -412,10 +412,10 @@ static BOOL RegistryToBaseTTNameA(LPSTR name) { static BOOL RegistryToBaseTTNameW(LPWSTR name) { static const wchar_t TTSUFFIX[] = L" (TrueType)"; static const wchar_t OTSUFFIX[] = L" (OpenType)"; - int TTSLEN = wcslen(TTSUFFIX); + size_t TTSLEN = wcslen(TTSUFFIX); wchar_t *suffix; - int len = wcslen(name); + size_t len = wcslen(name); if (len == 0) { return FALSE; } @@ -439,7 +439,7 @@ static void registerFontA(GdiFontMapInfo *fmi, jobject fontToFileMap, LPSTR ptr1, ptr2; jstring fontStr; JNIEnv *env = fmi->env; - int dslen = strlen(data); + size_t dslen = strlen(data); jstring fileStr = JNU_NewStringPlatform(env, data); /* TTC or ttc means it may be a collection. Need to parse out @@ -488,8 +488,8 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap, wchar_t *ptr1, *ptr2; jstring fontStr; JNIEnv *env = fmi->env; - int dslen = wcslen(data); - jstring fileStr = (*env)->NewString(env, data, dslen); + size_t dslen = wcslen(data); + jstring fileStr = (*env)->NewString(env, data, (jsize)dslen); /* TTC or ttc means it may be a collection. Need to parse out * multiple font face names separated by " & " @@ -510,7 +510,7 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap, while ((ptr2 = wcsstr(ptr1, L" & ")) != NULL) { ptr1 = ptr2+3; } - fontStr = (*env)->NewString(env, ptr1, wcslen(ptr1)); + fontStr = (*env)->NewString(env, ptr1, (jsize)wcslen(ptr1)); fontStr = (*env)->CallObjectMethod(env, fontStr, fmi->toLowerCaseMID, fmi->locale); @@ -524,7 +524,7 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap, } } } else { - fontStr = (*env)->NewString(env, name, wcslen(name)); + fontStr = (*env)->NewString(env, name, (jsize)wcslen(name)); fontStr = (*env)->CallObjectMethod(env, fontStr, fmi->toLowerCaseMID, fmi->locale); (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID, From 90df638cdcc3f7651ba244ee0c7c16b2701f310b Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Thu, 21 Apr 2011 14:29:23 +0400 Subject: [PATCH 06/32] 7021058: The Create folder button produces error in the Details mode (JFileChooser) Reviewed-by: malenkov --- jdk/src/share/classes/sun/swing/FilePane.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java index a5e7dffda32..5bf5c1f43b0 100644 --- a/jdk/src/share/classes/sun/swing/FilePane.java +++ b/jdk/src/share/classes/sun/swing/FilePane.java @@ -763,7 +763,7 @@ public class FilePane extends JPanel implements PropertyChangeListener { public void setValueAt(Object value, int row, int col) { if (col == COLUMN_FILENAME) { - JFileChooser chooser = getFileChooser(); + final JFileChooser chooser = getFileChooser(); File f = (File)getValueAt(row, col); if (f != null) { String oldDisplayName = chooser.getName(f); @@ -782,18 +782,25 @@ public class FilePane extends JPanel implements PropertyChangeListener { // rename FileSystemView fsv = chooser.getFileSystemView(); - File f2 = fsv.createFileObject(f.getParentFile(), newFileName); + final File f2 = fsv.createFileObject(f.getParentFile(), newFileName); if (f2.exists()) { JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorFileExistsText, oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE); } else { if (FilePane.this.getModel().renameFile(f, f2)) { if (fsv.isParent(chooser.getCurrentDirectory(), f2)) { - if (chooser.isMultiSelectionEnabled()) { - chooser.setSelectedFiles(new File[]{f2}); - } else { - chooser.setSelectedFile(f2); - } + // The setSelectedFile method produces a new setValueAt invocation while the JTable + // is editing. Postpone file selection to be sure that edit mode of the JTable + // is completed + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (chooser.isMultiSelectionEnabled()) { + chooser.setSelectedFiles(new File[]{f2}); + } else { + chooser.setSelectedFile(f2); + } + } + }); } else { // Could be because of delay in updating Desktop folder // chooser.setSelectedFile(null); From 6431b121c725e931240020868be7f13e26a436c5 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 22 Apr 2011 20:54:37 +0400 Subject: [PATCH 07/32] 7036871: Some JCK interactive JSplitPane tests that test continuous layout fail with Nimbus L&F Reviewed-by: rupashka --- jdk/src/share/classes/javax/swing/JSplitPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/javax/swing/JSplitPane.java b/jdk/src/share/classes/javax/swing/JSplitPane.java index d947329d663..fa773e5ae67 100644 --- a/jdk/src/share/classes/javax/swing/JSplitPane.java +++ b/jdk/src/share/classes/javax/swing/JSplitPane.java @@ -671,7 +671,7 @@ public class JSplitPane extends JComponent implements Accessible * which must be true for the child components * to be continuously * redisplayed and laid out during user intervention. - * The default value of this property is false. + * The default value of this property is look and feel dependent. * Some look and feels might not support continuous layout; * they will ignore this property. * From b5141e63fd863154e856d0147176b7fd65a8f620 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 22 Apr 2011 12:59:15 -0700 Subject: [PATCH 08/32] 7031011: fallbackfont testing failed on OEL 6 Reviewed-by: igor, jgodinez --- jdk/src/solaris/classes/sun/font/FcFontConfiguration.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java b/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java index ce2c935ba71..14d8e7ed221 100644 --- a/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java +++ b/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java @@ -256,9 +256,9 @@ public class FcFontConfiguration extends FontConfiguration { } if (installedFallbackFontFiles != null) { - System.arraycopy(fileNames, index, - installedFallbackFontFiles, - 0, installedFallbackFontFiles.length); + System.arraycopy(installedFallbackFontFiles, 0, + fileNames, fcFonts.length, + installedFallbackFontFiles.length); } result[fontIndex * NUM_STYLES + styleIndex] From b91701fce632312a5aacec63e7f9126dccc2dec0 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Mon, 25 Apr 2011 21:08:14 +0400 Subject: [PATCH 09/32] 7030632: Pasting HTML that was copied from MS Word results in IOException Reviewed-by: uta, denis --- .../windows/classes/sun/awt/windows/WDataTransferer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java index 21c1945140f..47dcf275430 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java @@ -830,7 +830,14 @@ class HTMLCodec extends InputStream { if( -1 == iStartOffset ){ throw new IOException(FAILURE_MSG + "invalid HTML format."); } - iReadCount = bufferedStream.skip(iStartOffset); + + int curOffset = 0; + while (curOffset < iStartOffset){ + curOffset += bufferedStream.skip(iStartOffset - curOffset); + } + + iReadCount = curOffset; + if( iStartOffset != iReadCount ){ throw new IOException(FAILURE_MSG + "Byte stream ends in description."); } From 5621d404bfbc05943b42affbba32ad2e43cda565 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Mon, 25 Apr 2011 20:39:35 +0400 Subject: [PATCH 10/32] 6888182: Readable and permitted to delete files could not be transferred through Clipboard and DnD Reviewed-by: uta --- jdk/src/windows/native/sun/windows/awt_Clipboard.cpp | 2 +- jdk/src/windows/native/sun/windows/awt_DnDDS.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp b/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp index d978090b8b3..6cea4a715fb 100644 --- a/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp @@ -294,7 +294,7 @@ Java_sun_awt_windows_WClipboard_publishClipboardData(JNIEnv *env, if (format == CF_HDROP) { DROPFILES *dropfiles = (DROPFILES *)dataout; dropfiles->pFiles = sizeof(DROPFILES); - dropfiles->fWide = FALSE; // good guess! + dropfiles->fWide = TRUE; // we publish only Unicode dataout += sizeof(DROPFILES); } diff --git a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp index 1aea026c885..2d585e0330a 100644 --- a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp +++ b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp @@ -843,7 +843,7 @@ HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc, dropfiles->pt.x = m_dropPoint.x; dropfiles->pt.y = m_dropPoint.y; dropfiles->fNC = m_fNC; - dropfiles->fWide = TRUE; // good guess! + dropfiles->fWide = TRUE; // we publish only Unicode dataout += sizeof(DROPFILES); } From 58aa826b315dbb63a3d5844c221920af0d660922 Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Tue, 26 Apr 2011 10:46:19 +0900 Subject: [PATCH 11/32] 7039469: (tz) Support tzdata2011g Reviewed-by: okutsu --- jdk/make/sun/javazic/tzdata/VERSION | 2 +- jdk/make/sun/javazic/tzdata/africa | 18 ++++++++++++++++-- jdk/make/sun/javazic/tzdata/europe | 4 ++-- jdk/make/sun/javazic/tzdata/southamerica | 23 +++++++++++++++++++++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION index c19847f5a11..c52096254ae 100644 --- a/jdk/make/sun/javazic/tzdata/VERSION +++ b/jdk/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2011e +tzdata2011g diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa index bea5f8157bb..a43e73ce10b 100644 --- a/jdk/make/sun/javazic/tzdata/africa +++ b/jdk/make/sun/javazic/tzdata/africa @@ -234,7 +234,21 @@ Rule Egypt 1989 only - May 6 1:00 1:00 S Rule Egypt 1990 1994 - May 1 1:00 1:00 S # IATA (after 1990) says transitions are at 0:00. # Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29. -Rule Egypt 1995 max - Apr lastFri 0:00s 1:00 S + +# From Alexander Krivenyshev (2011-04-20): +# "...Egypt's interim cabinet decided on Wednesday to cancel daylight +# saving time after a poll posted on its website showed the majority of +# Egyptians would approve the cancellation." +# +# Egypt to cancel daylight saving time +# +# http://www.almasryalyoum.com/en/node/407168 +# +# or +# +# http://www.worldtimezone.com/dst_news/dst_news_egypt04.html +# +Rule Egypt 1995 2010 - Apr lastFri 0:00s 1:00 S Rule Egypt 1995 2005 - Sep lastThu 23:00s 0 - # From Steffen Thorsen (2006-09-19): # The Egyptian Gazette, issue 41,090 (2006-09-18), page 1, reports: @@ -335,7 +349,7 @@ Rule Egypt 2008 only - Aug lastThu 23:00s 0 - Rule Egypt 2009 only - Aug 20 23:00s 0 - Rule Egypt 2010 only - Aug 11 0:00 0 - Rule Egypt 2010 only - Sep 10 0:00 1:00 S -Rule Egypt 2010 max - Sep lastThu 23:00s 0 - +Rule Egypt 2010 only - Sep lastThu 23:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Cairo 2:05:00 - LMT 1900 Oct diff --git a/jdk/make/sun/javazic/tzdata/europe b/jdk/make/sun/javazic/tzdata/europe index 5b11dfb5122..89bf6c5d3dc 100644 --- a/jdk/make/sun/javazic/tzdata/europe +++ b/jdk/make/sun/javazic/tzdata/europe @@ -168,7 +168,7 @@ # A monument to Willett was unveiled on 1927-05-21, in an open space in # a 45-acre wood near Chislehurst, Kent that was purchased by popular # subscription and open to the public. On the south face of the monolith, -# designed by G. W. Miller, is the the William Willett Memorial Sundial, +# designed by G. W. Miller, is the...William Willett Memorial Sundial, # which is permanently set to Summer Time. # From Winston Churchill (1934-04-28): @@ -1808,7 +1808,7 @@ Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1 # # All these events predate our cutoff date of 1970. Unless we can # come up with more definitive info about the timekeeping during the -# war years it's probably best just do do the following for now: +# war years it's probably best just do...the following for now: Link Europe/Oslo Arctic/Longyearbyen # Poland diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica index 7afec35d696..7717d12d17a 100644 --- a/jdk/make/sun/javazic/tzdata/southamerica +++ b/jdk/make/sun/javazic/tzdata/southamerica @@ -767,7 +767,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # # As a result of the above Decree I believe the America/Rio_Branco # timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall -# be created to represent the the west side of the Para State. I +# be created to represent the...west side of the Para State. I # suggest this new timezone be called Santarem as the most # important/populated city in the affected area. # @@ -1365,6 +1365,24 @@ Zone Pacific/Galapagos -5:58:24 - LMT 1931 # Puerto Baquerizo Moreno # For now, we'll just record the time in Stanley, since we have no # better info. +# From Steffen Thorsen (2011-04-01): +# The Falkland Islands will not turn back clocks this winter, but stay on +# daylight saving time. +# +# One source: +# +# http://www.falklandnews.com/public/story.cfm?get=5914&source=3 +# +# +# We have gotten this confirmed by a clerk of the legislative assembly: +# Normally the clocks revert to Local Mean Time (UTC/GMT -4 hours) on the +# third Sunday of April at 0200hrs and advance to Summer Time (UTC/GMT -3 +# hours) on the first Sunday of September at 0200hrs. +# +# IMPORTANT NOTE: During 2011, on a trial basis, the Falkland Islands +# will not revert to local mean time, but clocks will remain on Summer +# time (UTC/GMT - 3 hours) throughout the whole of 2011. Any long term +# change to local time following the trial period will be notified. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Falk 1937 1938 - Sep lastSun 0:00 1:00 S Rule Falk 1938 1942 - Mar Sun>=19 0:00 0 - @@ -1376,7 +1394,8 @@ Rule Falk 1984 1985 - Apr lastSun 0:00 0 - Rule Falk 1984 only - Sep 16 0:00 1:00 S Rule Falk 1985 2000 - Sep Sun>=9 0:00 1:00 S Rule Falk 1986 2000 - Apr Sun>=16 0:00 0 - -Rule Falk 2001 max - Apr Sun>=15 2:00 0 - +Rule Falk 2001 2010 - Apr Sun>=15 2:00 0 - +Rule Falk 2012 max - Apr Sun>=15 2:00 0 - Rule Falk 2001 max - Sep Sun>=1 2:00 1:00 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Atlantic/Stanley -3:51:24 - LMT 1890 From d21b9aa7bfc5ac29b551a95466d4e8576f9703e2 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Wed, 27 Apr 2011 12:15:34 +0400 Subject: [PATCH 12/32] 7037091: sun/java2d/pipe/Test7027667.java test is not executed Reviewed-by: prr --- jdk/test/sun/java2d/pipe/Test7027667.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/sun/java2d/pipe/Test7027667.java b/jdk/test/sun/java2d/pipe/Test7027667.java index 08f478f60b1..e30c72c0504 100644 --- a/jdk/test/sun/java2d/pipe/Test7027667.java +++ b/jdk/test/sun/java2d/pipe/Test7027667.java @@ -23,7 +23,7 @@ /** * @test - * @bug 7027667, 7023591 + * @bug 7027667 7023591 7037091 * * @summary Verifies that aa clipped rectangles are drawn, not filled. * From aa161ffe8d9b643893b13bed12468f399f71e66d Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Wed, 27 Apr 2011 13:43:22 +0400 Subject: [PATCH 13/32] 7039403: Could not compile test/javax/swing/JLabel/6596966/bug6596966.java Reviewed-by: malenkov --- jdk/test/javax/swing/JLabel/6596966/bug6596966.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/jdk/test/javax/swing/JLabel/6596966/bug6596966.java b/jdk/test/javax/swing/JLabel/6596966/bug6596966.java index 5cf0110f700..5e94459bcb7 100644 --- a/jdk/test/javax/swing/JLabel/6596966/bug6596966.java +++ b/jdk/test/javax/swing/JLabel/6596966/bug6596966.java @@ -24,13 +24,13 @@ /* @test @bug 6596966 @summary Some JFileChooser mnemonics do not work with sticky keys - * @library ../../regtesthelpers - * @build Util @run main bug6596966 @author Pavel Porvatov */ +import sun.awt.SunToolkit; + import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; @@ -44,6 +44,7 @@ public class bug6596966 { public static void main(String[] args) throws Exception { Robot robot = new Robot(); + SunToolkit toolkit = (SunToolkit) SunToolkit.getDefaultToolkit(); SwingUtilities.invokeAndWait(new Runnable() { public void run() { @@ -68,17 +69,17 @@ public class bug6596966 { } }); - Util.blockTillDisplayed(frame); + toolkit.realSync(); robot.keyPress(KeyEvent.VK_ALT); robot.keyPress(KeyEvent.VK_L); - robot.waitForIdle(); + toolkit.realSync(); - Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new KeyEvent(label, KeyEvent.KEY_RELEASED, + toolkit.getSystemEventQueue().postEvent(new KeyEvent(label, KeyEvent.KEY_RELEASED, EventQueue.getMostRecentEventTime(), 0, KeyEvent.VK_L, 'L')); - robot.waitForIdle(); + toolkit.realSync(); try { SwingUtilities.invokeAndWait(new Runnable() { From f5afc05e608009a6805b59072f44a983c1b81350 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 27 Apr 2011 14:58:40 +0400 Subject: [PATCH 14/32] 7020922: java.awt.Toolkit.getPropertyChangeListeners() should mention that it returns proxies Reviewed-by: malenkov --- jdk/src/share/classes/java/awt/Toolkit.java | 40 ++++++++++++++------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 58a4ddc7b4f..6e00e6afdbf 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1870,11 +1870,15 @@ public abstract class Toolkit { /** * Adds the specified property change listener for the named desktop - * property. - * If pcl is null, no exception is thrown and no action is performed. + * property. When a {@link PropertyChangeListenerProxy} object is added, + * its property name is ignored, and the wrapped listener is added. + * If {@code name} is {@code null} or {@code pcl} is {@code null}, + * no exception is thrown and no action is performed. * * @param name The name of the property to listen for * @param pcl The property change listener + * @see PropertyChangeSupport#addPropertyChangeListener(String, + PropertyChangeListener) * @since 1.2 */ public void addPropertyChangeListener(String name, PropertyChangeListener pcl) { @@ -1883,11 +1887,16 @@ public abstract class Toolkit { /** * Removes the specified property change listener for the named - * desktop property. - * If pcl is null, no exception is thrown and no action is performed. + * desktop property. When a {@link PropertyChangeListenerProxy} object + * is removed, its property name is ignored, and + * the wrapped listener is removed. + * If {@code name} is {@code null} or {@code pcl} is {@code null}, + * no exception is thrown and no action is performed. * * @param name The name of the property to remove * @param pcl The property change listener + * @see PropertyChangeSupport#removePropertyChangeListener(String, + PropertyChangeListener) * @since 1.2 */ public void removePropertyChangeListener(String name, PropertyChangeListener pcl) { @@ -1896,12 +1905,15 @@ public abstract class Toolkit { /** * Returns an array of all the property change listeners - * registered on this toolkit. + * registered on this toolkit. The returned array + * contains {@code PropertyChangeListenerProxy} objects + * that associate listeners with the names of desktop properties. * - * @return all of this toolkit's PropertyChangeListeners - * or an empty array if no property change - * listeners are currently registered + * @return all of this toolkit's {@ code PropertyChangeListener} + * objects wrapped in {@code PropertyChangeListenerProxy} objects + * or an empty array if no listeners are added * + * @see PropertyChangeSupport#getPropertyChangeListeners() * @since 1.4 */ public PropertyChangeListener[] getPropertyChangeListeners() { @@ -1909,13 +1921,15 @@ public abstract class Toolkit { } /** - * Returns an array of all the PropertyChangeListeners - * associated with the named property. + * Returns an array of all property change listeners + * associated with the specified name of a desktop property. * * @param propertyName the named property - * @return all of the PropertyChangeListeners associated with - * the named property or an empty array if no such listeners have - * been added + * @return all of the {@code PropertyChangeListener} objects + * associated with the specified name of a desktop property + * or an empty array if no such listeners are added + * + * @see PropertyChangeSupport#getPropertyChangeListeners(String) * @since 1.4 */ public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { From 57f34d2482bcdc2c4636cc64b5072af3e03e930f Mon Sep 17 00:00:00 2001 From: Oleg Pekhovskiy Date: Wed, 27 Apr 2011 15:26:38 +0400 Subject: [PATCH 15/32] 7035209: 6u26 ea b01 - running an applet with old plugin crashes in awt.dll Reviewed-by: art, amenkov --- jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp b/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp index a7da3f3b38c..a563c78802b 100644 --- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp +++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp @@ -187,6 +187,7 @@ void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter, } JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + RETURN_IF_NULL(env); pMgr = D3DPipelineManager::GetInstance(); RETURN_IF_NULL(pMgr); From ed12b2ab1870adf1e80c6c9d03b6ce77f29b2f4d Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 27 Apr 2011 17:18:38 +0400 Subject: [PATCH 16/32] 6998716: client vm crashes making browser fails to respond under some scenarios Reviewed-by: art, denis, uta --- .../windows/native/sun/windows/ObjectList.cpp | 7 +++-- .../windows/native/sun/windows/ObjectList.h | 2 +- .../native/sun/windows/awt_Component.cpp | 7 ++--- .../native/sun/windows/awt_MenuItem.cpp | 3 +-- .../windows/native/sun/windows/awt_Object.cpp | 19 +++++++++----- .../windows/native/sun/windows/awt_Object.h | 4 +++ .../windows/native/sun/windows/awt_Robot.cpp | 3 +-- .../native/sun/windows/awt_Toolkit.cpp | 26 +++++++++++++++---- .../native/sun/windows/awt_TrayIcon.cpp | 3 +-- jdk/src/windows/native/sun/windows/awtmsg.h | 1 + 10 files changed, 51 insertions(+), 24 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/ObjectList.cpp b/jdk/src/windows/native/sun/windows/ObjectList.cpp index b0614e6b97f..601c42ce2e3 100644 --- a/jdk/src/windows/native/sun/windows/ObjectList.cpp +++ b/jdk/src/windows/native/sun/windows/ObjectList.cpp @@ -48,7 +48,7 @@ void AwtObjectList::Add(AwtObject* obj) m_head = item; } -void AwtObjectList::Remove(AwtObject* obj) +BOOL AwtObjectList::Remove(AwtObject* obj) { CriticalSection::Lock l(m_lock); @@ -64,11 +64,14 @@ void AwtObjectList::Remove(AwtObject* obj) } DASSERT(item != NULL); delete item; - return; + return TRUE; } lastItem = item; item = item->next; } + + return FALSE; + // DASSERT(FALSE); // should never get here... // even if it does it shouldn't be fatal. } diff --git a/jdk/src/windows/native/sun/windows/ObjectList.h b/jdk/src/windows/native/sun/windows/ObjectList.h index 9775d0c9f1e..1e80732ca39 100644 --- a/jdk/src/windows/native/sun/windows/ObjectList.h +++ b/jdk/src/windows/native/sun/windows/ObjectList.h @@ -46,7 +46,7 @@ public: AwtObjectList(); void Add(AwtObject* obj); - void Remove(AwtObject* obj); + BOOL Remove(AwtObject* obj); #ifdef DEBUG /* Used for sanity checks only. */ AwtObject* LookUp(AwtObject* obj); diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index fd75b8d52ee..592a9b434b2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1969,7 +1969,9 @@ MsgRouting AwtComponent::WmDestroy() { // fix for 6259348: we should enter the SyncCall critical section before // disposing the native object, that is value 1 of lParam is intended for - AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)this, (LPARAM)1); + if(m_peerObject != NULL) { // is not being terminating + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)m_peerObject, (LPARAM)1); + } return mrConsume; } @@ -6534,8 +6536,7 @@ Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) { TRY_NO_HANG; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp index aeb1021262a..97f3e2a7a21 100644 --- a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp +++ b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp @@ -974,8 +974,7 @@ Java_sun_awt_windows_WMenuItemPeer__1dispose(JNIEnv *env, jobject self) { TRY_NO_HANG; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Object.cpp b/jdk/src/windows/native/sun/windows/awt_Object.cpp index b7afe1aa510..54ec69a9a19 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp @@ -60,11 +60,20 @@ AwtObject::~AwtObject() void AwtObject::Dispose() { - theAwtObjectList.Remove(this); + AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); +} + +void AwtObject::_Dispose(jobject self) +{ + TRY_NO_VERIFY; + + CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); // value 0 of lParam means that we should not attempt to enter the // SyncCall critical section, as it was entered someshere earlier - AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)self, (LPARAM)0); + + CATCH_BAD_ALLOC; } void AwtObject::_Dispose(PDATA pData) @@ -73,14 +82,10 @@ void AwtObject::_Dispose(PDATA pData) CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); - if (pData != NULL) { - AwtObject *o = (AwtObject *)pData; - AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)o, (LPARAM)0); - } + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSEPDATA, (WPARAM)pData, (LPARAM)0); CATCH_BAD_ALLOC; } - /* * Return the peer associated with some target. This information is * maintained in a hashtable at the java level. diff --git a/jdk/src/windows/native/sun/windows/awt_Object.h b/jdk/src/windows/native/sun/windows/awt_Object.h index 6cfb83ebcc5..918e95d1c18 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.h +++ b/jdk/src/windows/native/sun/windows/awt_Object.h @@ -66,6 +66,10 @@ public: // After this method has been called, this object must not be used in any way. virtual void Dispose(); + // Static method to be called from JNI methods to dispose AwtObject + // specified by jobject + static void _Dispose(jobject self); + // Static method to be called from JNI methods to dispose AwtObject // specified by pData static void _Dispose(PDATA pData); diff --git a/jdk/src/windows/native/sun/windows/awt_Robot.cpp b/jdk/src/windows/native/sun/windows/awt_Robot.cpp index cdee9cf6001..09e12debf38 100644 --- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp @@ -353,8 +353,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer__1dispose( { TRY_NO_VERIFY; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index ca2bae8325a..d010d6b130c 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -740,18 +740,34 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, canDispose = syncCS.TryEnter(); } if (canDispose) { - AwtObject *o = (AwtObject *)wParam; - o->Dispose(); - if (shouldEnterCriticalSection) { - syncCS.Leave(); + if(wParam != NULL) { + AwtObject *o = (AwtObject *) JNI_GET_PDATA((jobject)wParam); + if(o != NULL && theAwtObjectList.Remove(o)) { + o->Dispose(); + } + if (shouldEnterCriticalSection) { + syncCS.Leave(); + } } } else { AwtToolkit::GetInstance().PostMessage(WM_AWT_DISPOSE, wParam, lParam); } return 0; } + case WM_AWT_DISPOSEPDATA: { + /* + * NOTE: synchronization routine (like in WM_AWT_DISPOSE) was omitted because + * this handler is called ONLY while disposing Cursor and Font objects where + * synchronization takes place. + */ + AwtObject *o = (AwtObject *) wParam; + if(o != NULL && theAwtObjectList.Remove(o)) { + o->Dispose(); + } + return 0; + } case WM_AWT_DELETEOBJECT: { - AwtObject *p = (AwtObject *)wParam; + AwtObject *p = (AwtObject *) wParam; if (p->CanBeDeleted()) { // all the messages for this component are processed, so // it can be deleted diff --git a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp index 4156c9cfec1..c2682b3b113 100644 --- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp @@ -926,8 +926,7 @@ Java_sun_awt_windows_WTrayIconPeer__1dispose(JNIEnv *env, jobject self) { TRY; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awtmsg.h b/jdk/src/windows/native/sun/windows/awtmsg.h index 898471b4923..05733c7a6f0 100644 --- a/jdk/src/windows/native/sun/windows/awtmsg.h +++ b/jdk/src/windows/native/sun/windows/awtmsg.h @@ -219,6 +219,7 @@ enum { WM_AWT_ENDCOMPOSITION, WM_AWT_DISPOSE, + WM_AWT_DISPOSEPDATA, WM_AWT_DELETEOBJECT, WM_AWT_SETCONVERSIONSTATUS, WM_AWT_GETCONVERSIONSTATUS, From 1f4f92b81d50cfdd03dbfa9263ad55808a547139 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Wed, 27 Apr 2011 17:46:59 +0400 Subject: [PATCH 17/32] 6888633: test/closed/javax/swing/JPopupMenu/4786415/bug4786415.java fails Reviewed-by: rupashka, alexp --- jdk/src/share/classes/javax/swing/JPopupMenu.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index 24a9d4cf6c5..53926e4a744 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -342,8 +342,8 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { // Calculate the screen size that popup should fit Dimension popupSize = JPopupMenu.this.getPreferredSize(); - int popupRightX = popupLocation.x + popupSize.width; - int popupBottomY = popupLocation.y + popupSize.height; + long popupRightX = (long)popupLocation.x + (long)popupSize.width; + long popupBottomY = (long)popupLocation.y + (long)popupSize.height; int scrWidth = scrBounds.width; int scrHeight = scrBounds.height; if (!canPopupOverlapTaskBar()) { @@ -358,13 +358,13 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { int scrBottomY = scrBounds.y + scrHeight; // Ensure that popup menu fits the screen - if (popupRightX > scrRightX) { + if (popupRightX > (long)scrRightX) { popupLocation.x = scrRightX - popupSize.width; if( popupLocation.x < scrBounds.x ) { popupLocation.x = scrBounds.x ; } } - if (popupBottomY > scrBottomY) { + if (popupBottomY > (long)scrBottomY) { popupLocation.y = scrBottomY - popupSize.height; if( popupLocation.y < scrBounds.y ) { popupLocation.y = scrBounds.y; From b44f91dc52db004e35fcce686f8c45181220b5cc Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Wed, 27 Apr 2011 18:15:27 +0400 Subject: [PATCH 18/32] 6979551: closed/javax/swing/plaf/basic/BasicLabelUI/4798542/bug4798542.java fails Reviewed-by: art, yan, alexp --- .../classes/sun/awt/ExtendedKeyCodes.java | 17 +++++- .../keyboard/EqualKeyCode/EqualKeyCode.java | 61 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java diff --git a/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java b/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java index d6d72ac4ad7..fc004ba2a28 100644 --- a/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java +++ b/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java @@ -13,7 +13,7 @@ public class ExtendedKeyCodes { */ // Keycodes declared in KeyEvent.java with corresponding Unicode values. private final static HashMap regularKeyCodesMap = - new HashMap(83, 1.0f); + new HashMap(98, 1.0f); // Keycodes derived from Unicode values. Here should be collected codes // for characters appearing on the primary layer of at least one @@ -108,6 +108,21 @@ public class ExtendedKeyCodes { regularKeyCodesMap.put(0x5E, KeyEvent.VK_CIRCUMFLEX); regularKeyCodesMap.put(0x5F, KeyEvent.VK_UNDERSCORE); regularKeyCodesMap.put(0x60, KeyEvent.VK_BACK_QUOTE); + regularKeyCodesMap.put(0x61, KeyEvent.VK_A); + regularKeyCodesMap.put(0x62, KeyEvent.VK_B); + regularKeyCodesMap.put(0x63, KeyEvent.VK_C); + regularKeyCodesMap.put(0x64, KeyEvent.VK_D); + regularKeyCodesMap.put(0x65, KeyEvent.VK_E); + regularKeyCodesMap.put(0x66, KeyEvent.VK_F); + regularKeyCodesMap.put(0x67, KeyEvent.VK_G); + regularKeyCodesMap.put(0x68, KeyEvent.VK_H); + regularKeyCodesMap.put(0x69, KeyEvent.VK_I); + regularKeyCodesMap.put(0x6A, KeyEvent.VK_J); + regularKeyCodesMap.put(0x6B, KeyEvent.VK_K); + regularKeyCodesMap.put(0x6C, KeyEvent.VK_L); + regularKeyCodesMap.put(0x6D, KeyEvent.VK_M); + regularKeyCodesMap.put(0x6E, KeyEvent.VK_N); + regularKeyCodesMap.put(0x6F, KeyEvent.VK_O); regularKeyCodesMap.put(0x70, KeyEvent.VK_P); regularKeyCodesMap.put(0x71, KeyEvent.VK_Q); regularKeyCodesMap.put(0x72, KeyEvent.VK_R); diff --git a/jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java b/jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java new file mode 100644 index 00000000000..d4acc95ef2b --- /dev/null +++ b/jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, 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. + * + * 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. + */ + +/* + @test + @bug 6799551 + @library ../../regtesthelpers + @build Util Sysout + @summary Extended key codes for small letters undefined + @author Andrei Dmitriev: area=awt.keyboard + @run main EqualKeyCode +*/ + + +import sun.awt.*; +import java.awt.*; +import test.java.awt.regtesthelpers.Util; +import test.java.awt.regtesthelpers.Sysout; + +public class EqualKeyCode { + + final static String LETTERS = "abcdefghijklmnopqrstuvwxyz"; + + public static void main(String []s) { + for (int i = 0; i < LETTERS.length(); i++){ + char cSmall = LETTERS.charAt(i); + char cLarge = Character.toUpperCase(cSmall); + + int iSmall = ExtendedKeyCodes.getExtendedKeyCodeForChar(cSmall); + int iLarge = ExtendedKeyCodes.getExtendedKeyCodeForChar(cLarge); + + System.out.print(" " + cSmall + ":" + iSmall + " ---- "); + System.out.println(" " + cLarge + " : " + iLarge); + if (ExtendedKeyCodes.getExtendedKeyCodeForChar(cSmall) != + ExtendedKeyCodes.getExtendedKeyCodeForChar(cLarge)) + { + throw new RuntimeException("ExtendedKeyCode doesn't exist or doesn't match between capital and small letters."); + } + } + } +} From 88ddcf5e65d080f143e57965f8171241db96624d Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 28 Apr 2011 13:26:18 +0400 Subject: [PATCH 19/32] 7032830: GraphicsDevice.setFullScreenWindow() works strange for decorated windows on OEL 7016382: GraphicsDevice.setFullScreenWindow() - spec clarification for exclusive mode for dec/undec Frames Reviewed-by: art --- jdk/src/share/classes/java/awt/GraphicsDevice.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/src/share/classes/java/awt/GraphicsDevice.java b/jdk/src/share/classes/java/awt/GraphicsDevice.java index f3b7cd390a6..b99d7ef8def 100644 --- a/jdk/src/share/classes/java/awt/GraphicsDevice.java +++ b/jdk/src/share/classes/java/awt/GraphicsDevice.java @@ -257,6 +257,11 @@ public abstract class GraphicsDevice { * 1.0f, and the background color alpha is set to 255 (completely opaque). * These values are not restored when returning to windowed mode. *

+ * It is unspecified and platform-dependent how decorated windows operate + * in full-screen mode. For this reason, it is recommended to turn off + * the decorations in a {@code Frame} or {@code Dialog} object by using the + * {@code setUndecorated} method. + *

* When returning to windowed mode from an exclusive full-screen window, * any display changes made by calling {@code setDisplayMode} are * automatically restored to their original state. @@ -272,6 +277,8 @@ public abstract class GraphicsDevice { * @see #setDisplayMode * @see Component#enableInputMethods * @see Component#setVisible + * @see Frame#setUndecorated + * @see Dialog#setUndecorated * * @since 1.4 */ From cf97b67aa29b33791b466ba7bbdce81cb14d512d Mon Sep 17 00:00:00 2001 From: Denis Lila Date: Thu, 28 Apr 2011 08:55:19 -0400 Subject: [PATCH 20/32] 7036754: NaNs in stroked quadratics Check for them and remove them. Reviewed-by: flar --- .../classes/sun/java2d/pisces/Stroker.java | 252 +++++++++--------- jdk/test/sun/java2d/pisces/Test7036754.java | 58 ++++ 2 files changed, 185 insertions(+), 125 deletions(-) create mode 100644 jdk/test/sun/java2d/pisces/Test7036754.java diff --git a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java index dc270c194c8..6d4a4c75ac5 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java +++ b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java @@ -27,6 +27,8 @@ package sun.java2d.pisces; import java.util.Arrays; import java.util.Iterator; +import static java.lang.Math.ulp; +import static java.lang.Math.sqrt; import sun.awt.geom.PathConsumer2D; @@ -130,7 +132,7 @@ final class Stroker implements PathConsumer2D { private static void computeOffset(final float lx, final float ly, final float w, final float[] m) { - final float len = (float)Math.sqrt(lx*lx + ly*ly); + final float len = (float) sqrt(lx*lx + ly*ly); if (len == 0) { m[0] = m[1] = 0; } else { @@ -217,7 +219,7 @@ final class Stroker implements PathConsumer2D { // this normal's length is at least 0.5 and at most sqrt(2)/2 (because // we know the angle of the arc is > 90 degrees). float nx = my - omy, ny = omx - mx; - float nlen = (float)Math.sqrt(nx*nx + ny*ny); + float nlen = (float) sqrt(nx*nx + ny*ny); float scale = lineWidth2/nlen; float mmx = nx * scale, mmy = ny * scale; @@ -246,8 +248,8 @@ final class Stroker implements PathConsumer2D { // define the bezier curve we're computing. // It is computed using the constraints that P1-P0 and P3-P2 are parallel // to the arc tangents at the endpoints, and that |P1-P0|=|P3-P2|. - float cv = (float)((4.0 / 3.0) * Math.sqrt(0.5-cosext2) / - (1.0 + Math.sqrt(cosext2+0.5))); + float cv = (float) ((4.0 / 3.0) * sqrt(0.5-cosext2) / + (1.0 + sqrt(cosext2+0.5))); // if clockwise, we need to negate cv. if (rev) { // rev is equivalent to isCW(omx, omy, mx, my) cv = -cv; @@ -284,28 +286,20 @@ final class Stroker implements PathConsumer2D { false); } - // Return the intersection point of the lines (x0, y0) -> (x1, y1) - // and (x0p, y0p) -> (x1p, y1p) in m[0] and m[1] - private void computeMiter(final float x0, final float y0, - final float x1, final float y1, - final float x0p, final float y0p, - final float x1p, final float y1p, - final float[] m, int off) + // Put the intersection point of the lines (x0, y0) -> (x1, y1) + // and (x0p, y0p) -> (x1p, y1p) in m[off] and m[off+1]. + // If the lines are parallel, it will put a non finite number in m. + private void computeIntersection(final float x0, final float y0, + final float x1, final float y1, + final float x0p, final float y0p, + final float x1p, final float y1p, + final float[] m, int off) { float x10 = x1 - x0; float y10 = y1 - y0; float x10p = x1p - x0p; float y10p = y1p - y0p; - // if this is 0, the lines are parallel. If they go in the - // same direction, there is no intersection so m[off] and - // m[off+1] will contain infinity, so no miter will be drawn. - // If they go in the same direction that means that the start of the - // current segment and the end of the previous segment have the same - // tangent, in which case this method won't even be involved in - // miter drawing because it won't be called by drawMiter (because - // (mx == omx && my == omy) will be true, and drawMiter will return - // immediately). float den = x10*y10p - x10p*y10; float t = x10p*(y0-y0p) - y10p*(x0-x0p); t /= den; @@ -321,7 +315,8 @@ final class Stroker implements PathConsumer2D { { if ((mx == omx && my == omy) || (pdx == 0 && pdy == 0) || - (dx == 0 && dy == 0)) { + (dx == 0 && dy == 0)) + { return; } @@ -332,12 +327,17 @@ final class Stroker implements PathConsumer2D { my = -my; } - computeMiter((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy, - (dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my, - miter, 0); + computeIntersection((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy, + (dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my, + miter, 0); float lenSq = (miter[0]-x0)*(miter[0]-x0) + (miter[1]-y0)*(miter[1]-y0); + // If the lines are parallel, lenSq will be either NaN or +inf + // (actually, I'm not sure if the latter is possible. The important + // thing is that -inf is not possible, because lenSq is a square). + // For both of those values, the comparison below will fail and + // no miter will be drawn, which is correct. if (lenSq < miterLimitSq) { emitLineTo(miter[0], miter[1], rev); } @@ -566,8 +566,8 @@ final class Stroker implements PathConsumer2D { // if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4, // in which case ignore if p1 == p2 - final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2)); - final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * Math.ulp(y4)); + final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * ulp(y2)); + final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * ulp(y4)); if (p1eqp2 && p3eqp4) { getLineOffsets(x1, y1, x4, y4, leftOff, rightOff); return 4; @@ -583,7 +583,7 @@ final class Stroker implements PathConsumer2D { float dotsq = (dx1 * dx4 + dy1 * dy4); dotsq = dotsq * dotsq; float l1sq = dx1 * dx1 + dy1 * dy1, l4sq = dx4 * dx4 + dy4 * dy4; - if (Helpers.within(dotsq, l1sq * l4sq, 4 * Math.ulp(dotsq))) { + if (Helpers.within(dotsq, l1sq * l4sq, 4 * ulp(dotsq))) { getLineOffsets(x1, y1, x4, y4, leftOff, rightOff); return 4; } @@ -693,8 +693,6 @@ final class Stroker implements PathConsumer2D { return 8; } - // compute offset curves using bezier spline through t=0.5 (i.e. - // ComputedCurve(0.5) == IdealParallelCurve(0.5)) // return the kind of curve in the right and left arrays. private int computeOffsetQuad(float[] pts, final int off, float[] leftOff, float[] rightOff) @@ -703,58 +701,69 @@ final class Stroker implements PathConsumer2D { final float x2 = pts[off + 2], y2 = pts[off + 3]; final float x3 = pts[off + 4], y3 = pts[off + 5]; - float dx3 = x3 - x2; - float dy3 = y3 - y2; - float dx1 = x2 - x1; - float dy1 = y2 - y1; + final float dx3 = x3 - x2; + final float dy3 = y3 - y2; + final float dx1 = x2 - x1; + final float dy1 = y2 - y1; - // if p1=p2 or p3=p4 it means that the derivative at the endpoint - // vanishes, which creates problems with computeOffset. Usually - // this happens when this stroker object is trying to winden - // a curve with a cusp. What happens is that curveTo splits - // the input curve at the cusp, and passes it to this function. - // because of inaccuracies in the splitting, we consider points - // equal if they're very close to each other. - - // if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4, - // in which case ignore. - final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2)); - final boolean p2eqp3 = within(x2,y2,x3,y3, 6 * Math.ulp(y3)); - if (p1eqp2 || p2eqp3) { - getLineOffsets(x1, y1, x3, y3, leftOff, rightOff); - return 4; - } - - // if p2-p1 and p4-p3 are parallel, that must mean this curve is a line - float dotsq = (dx1 * dx3 + dy1 * dy3); - dotsq = dotsq * dotsq; - float l1sq = dx1 * dx1 + dy1 * dy1, l3sq = dx3 * dx3 + dy3 * dy3; - if (Helpers.within(dotsq, l1sq * l3sq, 4 * Math.ulp(dotsq))) { - getLineOffsets(x1, y1, x3, y3, leftOff, rightOff); - return 4; - } - - // this computes the offsets at t=0, 0.5, 1, using the property that - // for any bezier curve the vectors p2-p1 and p4-p3 are parallel to - // the (dx/dt, dy/dt) vectors at the endpoints. + // this computes the offsets at t = 0, 1 computeOffset(dx1, dy1, lineWidth2, offset[0]); computeOffset(dx3, dy3, lineWidth2, offset[1]); - float x1p = x1 + offset[0][0]; // start - float y1p = y1 + offset[0][1]; // point - float x3p = x3 + offset[1][0]; // end - float y3p = y3 + offset[1][1]; // point - computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2); - leftOff[0] = x1p; leftOff[1] = y1p; - leftOff[4] = x3p; leftOff[5] = y3p; - x1p = x1 - offset[0][0]; y1p = y1 - offset[0][1]; - x3p = x3 - offset[1][0]; y3p = y3 - offset[1][1]; - computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2); - rightOff[0] = x1p; rightOff[1] = y1p; - rightOff[4] = x3p; rightOff[5] = y3p; + leftOff[0] = x1 + offset[0][0]; leftOff[1] = y1 + offset[0][1]; + leftOff[4] = x3 + offset[1][0]; leftOff[5] = y3 + offset[1][1]; + rightOff[0] = x1 - offset[0][0]; rightOff[1] = y1 - offset[0][1]; + rightOff[4] = x3 - offset[1][0]; rightOff[5] = y3 - offset[1][1]; + + float x1p = leftOff[0]; // start + float y1p = leftOff[1]; // point + float x3p = leftOff[4]; // end + float y3p = leftOff[5]; // point + + // Corner cases: + // 1. If the two control vectors are parallel, we'll end up with NaN's + // in leftOff (and rightOff in the body of the if below), so we'll + // do getLineOffsets, which is right. + // 2. If the first or second two points are equal, then (dx1,dy1)==(0,0) + // or (dx3,dy3)==(0,0), so (x1p, y1p)==(x1p+dx1, y1p+dy1) + // or (x3p, y3p)==(x3p-dx3, y3p-dy3), which means that + // computeIntersection will put NaN's in leftOff and right off, and + // we will do getLineOffsets, which is right. + computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2); + float cx = leftOff[2]; + float cy = leftOff[3]; + + if (!(isFinite(cx) && isFinite(cy))) { + // maybe the right path is not degenerate. + x1p = rightOff[0]; + y1p = rightOff[1]; + x3p = rightOff[4]; + y3p = rightOff[5]; + computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2); + cx = rightOff[2]; + cy = rightOff[3]; + if (!(isFinite(cx) && isFinite(cy))) { + // both are degenerate. This curve is a line. + getLineOffsets(x1, y1, x3, y3, leftOff, rightOff); + return 4; + } + // {left,right}Off[0,1,4,5] are already set to the correct values. + leftOff[2] = 2*x2 - cx; + leftOff[3] = 2*y2 - cy; + return 6; + } + + // rightOff[2,3] = (x2,y2) - ((left_x2, left_y2) - (x2, y2)) + // == 2*(x2, y2) - (left_x2, left_y2) + rightOff[2] = 2*x2 - cx; + rightOff[3] = 2*y2 - cy; return 6; } + private static boolean isFinite(float x) { + return (Float.NEGATIVE_INFINITY < x && x < Float.POSITIVE_INFINITY); + } + // This is where the curve to be processed is put. We give it // enough room to store 2 curves: one for the current subdivision, the // other for the rest of the curve. @@ -812,12 +821,12 @@ final class Stroker implements PathConsumer2D { // if these vectors are too small, normalize them, to avoid future // precision problems. if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { - float len = (float)Math.sqrt(dxs*dxs + dys*dys); + float len = (float) sqrt(dxs*dxs + dys*dys); dxs /= len; dys /= len; } if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { - float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + float len = (float) sqrt(dxf*dxf + dyf*dyf); dxf /= len; dyf /= len; } @@ -834,7 +843,6 @@ final class Stroker implements PathConsumer2D { while(it.hasNext()) { int curCurveOff = it.next(); - kind = 0; switch (type) { case 8: kind = computeOffsetCubic(middle, curCurveOff, lp, rp); @@ -843,24 +851,22 @@ final class Stroker implements PathConsumer2D { kind = computeOffsetQuad(middle, curCurveOff, lp, rp); break; } - if (kind != 0) { - emitLineTo(lp[0], lp[1]); - switch(kind) { - case 8: - emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); - emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); - break; - case 6: - emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); - emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); - break; - case 4: - emitLineTo(lp[2], lp[3]); - emitLineTo(rp[0], rp[1], true); - break; - } - emitLineTo(rp[kind - 2], rp[kind - 1], true); + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 8: + emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); + emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); + break; + case 6: + emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); + emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; } + emitLineTo(rp[kind - 2], rp[kind - 1], true); } this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; @@ -887,7 +893,7 @@ final class Stroker implements PathConsumer2D { // we rotate it so that the first vector in the control polygon is // parallel to the x-axis. This will ensure that rotated quarter // circles won't be subdivided. - final float hypot = (float)Math.sqrt(x12 * x12 + y12 * y12); + final float hypot = (float) sqrt(x12 * x12 + y12 * y12); final float cos = x12 / hypot; final float sin = y12 / hypot; final float x1 = cos * pts[0] + sin * pts[1]; @@ -976,12 +982,12 @@ final class Stroker implements PathConsumer2D { // if these vectors are too small, normalize them, to avoid future // precision problems. if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { - float len = (float)Math.sqrt(dxs*dxs + dys*dys); + float len = (float) sqrt(dxs*dxs + dys*dys); dxs /= len; dys /= len; } if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { - float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + float len = (float) sqrt(dxf*dxf + dyf*dyf); dxf /= len; dyf /= len; } @@ -999,20 +1005,18 @@ final class Stroker implements PathConsumer2D { int curCurveOff = it.next(); kind = computeOffsetCubic(middle, curCurveOff, lp, rp); - if (kind != 0) { - emitLineTo(lp[0], lp[1]); - switch(kind) { - case 8: - emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); - emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); - break; - case 4: - emitLineTo(lp[2], lp[3]); - emitLineTo(rp[0], rp[1], true); - break; - } - emitLineTo(rp[kind - 2], rp[kind - 1], true); + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 8: + emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); + emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; } + emitLineTo(rp[kind - 2], rp[kind - 1], true); } this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; @@ -1050,12 +1054,12 @@ final class Stroker implements PathConsumer2D { // if these vectors are too small, normalize them, to avoid future // precision problems. if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { - float len = (float)Math.sqrt(dxs*dxs + dys*dys); + float len = (float) sqrt(dxs*dxs + dys*dys); dxs /= len; dys /= len; } if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { - float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + float len = (float) sqrt(dxf*dxf + dyf*dyf); dxf /= len; dyf /= len; } @@ -1073,20 +1077,18 @@ final class Stroker implements PathConsumer2D { int curCurveOff = it.next(); kind = computeOffsetQuad(middle, curCurveOff, lp, rp); - if (kind != 0) { - emitLineTo(lp[0], lp[1]); - switch(kind) { - case 6: - emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); - emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); - break; - case 4: - emitLineTo(lp[2], lp[3]); - emitLineTo(rp[0], rp[1], true); - break; - } - emitLineTo(rp[kind - 2], rp[kind - 1], true); + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 6: + emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); + emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; } + emitLineTo(rp[kind - 2], rp[kind - 1], true); } this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; diff --git a/jdk/test/sun/java2d/pisces/Test7036754.java b/jdk/test/sun/java2d/pisces/Test7036754.java new file mode 100644 index 00000000000..1dd39ddc8b9 --- /dev/null +++ b/jdk/test/sun/java2d/pisces/Test7036754.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, 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. + * + * 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. + */ + +/** + * @test + * @bug 7036754 + * + * @summary Verifies that there are no non-finite numbers when stroking + * certain quadratic curves. + * + * @author Jim Graham + * @run main Test7036754 + */ + +import java.awt.*; +import java.awt.geom.*; + +public class Test7036754 { + public static void main(String argv[]) { + Shape s = new QuadCurve2D.Float(839.24677f, 508.97888f, + 839.2953f, 508.97122f, + 839.3438f, 508.96353f); + s = new BasicStroke(10f).createStrokedShape(s); + float nsegs[] = {2, 2, 4, 6, 0}; + float coords[] = new float[6]; + PathIterator pi = s.getPathIterator(null); + while (!pi.isDone()) { + int type = pi.currentSegment(coords); + for (int i = 0; i < nsegs[type]; i++) { + float c = coords[i]; + if (Float.isNaN(c) || Float.isInfinite(c)) { + throw new RuntimeException("bad value in stroke"); + } + } + pi.next(); + } + } +} From c9f3d958ec3d62c02f19ec1e34c601c276fe7f25 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Thu, 28 Apr 2011 20:14:30 +0400 Subject: [PATCH 21/32] 6956646: Test: MouseWheelEvent/InfiniteRecursion test receives more MouseWheelEvents than expected Reviewed-by: serb, dcherepanov --- .../InfiniteRecursion/InfiniteRecursion.java | 13 ++++++++++--- .../InfiniteRecursion/InfiniteRecursion_1.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_2.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_3.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_4.java | 10 +++++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java index 6ec02ffbf45..e5533b41891 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -50,6 +50,11 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; + static int actualEvents = 0; public static void main(String []s) @@ -96,8 +101,10 @@ public class InfiniteRecursion { Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java index 3ed18f0e4a2..733af38731d 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -50,6 +50,9 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion_1 { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public static void main(String []s) @@ -95,8 +98,10 @@ public class InfiniteRecursion_1 { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java index 4aecedeb833..94444088671 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -56,6 +56,9 @@ import java.applet.Applet; public class InfiniteRecursion_2 extends Applet { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public void init() @@ -107,8 +110,10 @@ public class InfiniteRecursion_2 extends Applet { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } }// start() } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java index 2804b14ce7e..c12636acdc5 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -50,6 +50,9 @@ import java.applet.Applet; public class InfiniteRecursion_3 extends Applet { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public void init() @@ -91,8 +94,10 @@ public class InfiniteRecursion_3 extends Applet { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } }// start() } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java index 600e0fa5af3..2fbb3d2e2b0 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -47,6 +47,8 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion_4 { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions over a single frame without any siblings + final static int EXPECTED_COUNT = MOVE_COUNT * 2; static int actualEvents = 0; public static void main(String []s) @@ -80,8 +82,10 @@ public class InfiniteRecursion_4 { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } From 1e3fce0242fc651d74d060f0817f2761a862aae9 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 28 Apr 2011 19:23:44 +0400 Subject: [PATCH 22/32] 6853146: Regression: on-the-spot input is broken in AWT Peered components Reviewed-by: art, ant, naoto --- jdk/src/windows/native/sun/windows/awt_TextComponent.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp index c1fc17826b0..5e9a08f46ee 100644 --- a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp @@ -191,8 +191,11 @@ void AwtTextComponent::SetCompositionWindow(RECT& rc) { HIMC hIMC = ImmGetContext(); // rc is not used for text component. - COMPOSITIONFORM cf = { CFS_POINT, {0,0}, {0,0,0,0} }; + COMPOSITIONFORM cf = { CFS_FORCE_POSITION, {0,0}, {0,0,0,0} }; GetCaretPos(&(cf.ptCurrentPos)); + // the proxy is the native focus owner and it contains the composition window + // let's convert the position to a coordinate space relative to proxy + ::MapWindowPoints(GetHWnd(), GetProxyFocusOwner(), (LPPOINT)&cf.ptCurrentPos, 1); ImmSetCompositionWindow(hIMC, &cf); LOGFONT lf; From ac156aab263ec8a9597dcc20807b27776ad18ccd Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 28 Apr 2011 19:39:47 +0400 Subject: [PATCH 23/32] 7034766: closed/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java failed on jdk7 b134 Reviewed-by: art, ant --- jdk/src/windows/native/sun/windows/awt_Frame.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 4d3374e5734..398aea6db67 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -340,12 +340,16 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms } break; case WM_SETFOCUS: + if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain + if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) { AwtSetActiveWindow(); } mr = mrConsume; break; case WM_KILLFOCUS: + if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain + if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) { AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL); From bf38109be47b9acb0eb7ec1006c9a6a655958b7d Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:34 -0700 Subject: [PATCH 24/32] Added tag jdk7-b140 for changeset adbb12180d75 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index c3032b54af6..68e25fecbb6 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -114,3 +114,4 @@ aa13e7702cd9d8aca9aa38f1227f966990866944 jdk7-b136 29296ea6529a418037ccce95903249665ef31c11 jdk7-b137 60d3d55dcc9c31a30ced9caa6ef5c0dcd7db031d jdk7-b138 d80954a89b49fda47c0c5cace65a17f5a758b8bd jdk7-b139 +9315c733fb17ddfb9fb44be7e0ffea37bf3c727d jdk7-b140 From e8ad64314e5b39588ffdcb613a4b421aca2d4841 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 29 Apr 2011 01:40:11 -0700 Subject: [PATCH 25/32] 7020955: No focus point adjustment for RadialGradientPaint Reviewed-by: prr --- .../share/classes/java/awt/RadialGradientPaint.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/awt/RadialGradientPaint.java b/jdk/src/share/classes/java/awt/RadialGradientPaint.java index d2ba4be3ece..c9cc43a8e32 100644 --- a/jdk/src/share/classes/java/awt/RadialGradientPaint.java +++ b/jdk/src/share/classes/java/awt/RadialGradientPaint.java @@ -49,9 +49,11 @@ import java.beans.ConstructorProperties; * from the focus point to the circumference will thus span all the gradient * colors. *

- * Specifying a focus point outside of the circle's radius will result in the - * focus being set to the intersection point of the focus-center line and the - * perimeter of the circle. + * Specifying a focus point outside of the radius of the circle will cause + * the rings of the gradient pattern to be centered on the point just inside + * the edge of the circle in the direction of the focus point. + * The rendering will internally use this modified location as if it were + * the specified focus point. *

* The user must provide an array of floats specifying how to distribute the * colors along the gradient. These values should range from 0.0 to 1.0 and @@ -621,6 +623,11 @@ public final class RadialGradientPaint extends MultipleGradientPaint { /** * Returns a copy of the focus point of the radial gradient. + * Note that if the focus point specified when the radial gradient + * was constructed lies outside of the radius of the circle, this + * method will still return the original focus point even though + * the rendering may center the rings of color on a different + * point that lies inside the radius. * * @return a {@code Point2D} object that is a copy of the focus point */ From 2ab6e13a2190b421760e1571bb8c396fc561e562 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 29 Apr 2011 16:02:05 +0400 Subject: [PATCH 26/32] 7034291: Regression : Preedit String on active client is committed into unexpected component Reviewed-by: art, naoto --- .../native/sun/windows/awt_Component.cpp | 8 ++----- .../windows/native/sun/windows/awt_Frame.cpp | 22 ++++++++++++++++--- .../windows/native/sun/windows/awt_Frame.h | 9 ++++---- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 592a9b434b2..45236e6ffcd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1203,7 +1203,7 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { WIN_MSG(WM_IME_COMPOSITIONFULL) WIN_MSG(WM_IME_SELECT) WIN_MSG(WM_IME_CHAR) - FMT_MSG(0x0288, "WM_IME_REQUEST") + FMT_MSG(WM_IME_REQUEST) WIN_MSG(WM_IME_KEYDOWN) WIN_MSG(WM_IME_KEYUP) FMT_MSG(0x02A1, "WM_MOUSEHOVER") @@ -1733,7 +1733,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) case WM_IME_SELECT: case WM_IME_KEYUP: case WM_IME_KEYDOWN: - case 0x0288: // WM_IME_REQUEST + case WM_IME_REQUEST: CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_CHAR: @@ -4657,10 +4657,6 @@ void* AwtComponent::SetNativeFocusOwner(void *self) { ret: if (c && ::IsWindow(c->GetHWnd())) { sm_focusOwner = c->GetHWnd(); - AwtFrame *owner = (AwtFrame*)GetComponent(c->GetProxyToplevelContainer()); - if (owner) { - owner->SetLastProxiedFocusOwner(sm_focusOwner); - } } else { sm_focusOwner = NULL; } diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 398aea6db67..6662d6d54c2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -109,7 +109,7 @@ AwtFrame::AwtFrame() { m_isMenuDropped = FALSE; m_isInputMethodWindow = FALSE; m_isUndecorated = FALSE; - m_lastProxiedFocusOwner = NULL; + m_imeTargetComponent = NULL; m_actualFocusedWindow = NULL; m_iconic = FALSE; m_zoomed = FALSE; @@ -311,6 +311,8 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms LRESULT retValue = 0L; AwtComponent *focusOwner = NULL; + AwtComponent *imeTargetComponent = NULL; + // IME and input language related messages need to be sent to a window // which has the Java input focus switch (message) { @@ -323,15 +325,29 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: case WM_IME_CHAR: - case 0x0288: // WM_IME_REQUEST + case WM_IME_REQUEST: case WM_IME_KEYDOWN: case WM_IME_KEYUP: case WM_INPUTLANGCHANGEREQUEST: case WM_INPUTLANGCHANGE: + if (message == WM_IME_STARTCOMPOSITION) { + SetImeTargetComponent(sm_focusOwner); + } + imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent()); + if (imeTargetComponent != NULL && + imeTargetComponent != this) // avoid recursive calls + { + retValue = imeTargetComponent->WindowProc(message, wParam, lParam); + mr = mrConsume; + } + if (message == WM_IME_ENDCOMPOSITION) { + SetImeTargetComponent(NULL); + } + break; // TODO: when a Choice's list is dropped down and we're scrolling in // the list WM_MOUSEWHEEL messages come to the poxy, not to the list. Why? case WM_MOUSEWHEEL: - focusOwner = AwtComponent::GetComponent(GetLastProxiedFocusOwner()); + focusOwner = AwtComponent::GetComponent(sm_focusOwner); if (focusOwner != NULL && focusOwner != this) // avoid recursive calls { diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.h b/jdk/src/windows/native/sun/windows/awt_Frame.h index 1adca139bf9..f6d692b87eb 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.h +++ b/jdk/src/windows/native/sun/windows/awt_Frame.h @@ -150,8 +150,8 @@ public: void CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd); BOOL CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd); - INLINE HWND GetLastProxiedFocusOwner() { return m_lastProxiedFocusOwner; } - INLINE void SetLastProxiedFocusOwner(HWND hwnd) { m_lastProxiedFocusOwner = hwnd; } + INLINE HWND GetImeTargetComponent() { return m_imeTargetComponent; } + INLINE void SetImeTargetComponent(HWND hwnd) { m_imeTargetComponent = hwnd; } protected: /* The frame is undecorated. */ @@ -179,9 +179,8 @@ private: /* The frame is an InputMethodWindow */ BOOL m_isInputMethodWindow; - /* Retains the last/current sm_focusOwner proxied. Actually, it should be - * a component of an owned window last/currently active. */ - HWND m_lastProxiedFocusOwner; + // retains the target component for the IME messages + HWND m_imeTargetComponent; /* * Fix for 4823903. From 202b18b4f568e73a1eef78094f9ff5ce7d6e2c3c Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 29 Apr 2011 16:16:25 +0400 Subject: [PATCH 27/32] 7026055: Regression : Cannot use IME on JComboBox Japanese Reviewed-by: art, ant, naoto --- .../native/sun/windows/awt_Component.cpp | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 45236e6ffcd..024915fcffc 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -549,8 +549,6 @@ AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, m_hwnd = hwnd; - ImmAssociateContext(NULL); - SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | (jint)JAWT_LOCK_BOUNDS_CHANGED | (jint)JAWT_LOCK_CLIP_CHANGED); @@ -2022,25 +2020,6 @@ MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) { - // NULL-InputContext is associated to all window just after they created. - // ( see CreateHWnd() ) - // But to TextField and TextArea on Win95, valid InputContext is associated - // by system after that. This is not happen on NT4.0 - // For workaround, force context to NULL here. - - // Fix for 4730228 - // Check if we already have Java-associated input method - HIMC context = 0; - if (m_InputMethod != NULL) { - // If so get the appropriate context from it and use it instead of empty context - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - context = (HIMC)(UINT_PTR)(JNU_GetFieldByName(env, NULL, m_InputMethod, "context", "I").i); - } - - if (ImmGetContext() != 0 && ImmGetContext() != context) { - ImmAssociateContext(context); - } - return mrDoDefault; } From 6b348af4c0a33f84fd73253bfa4efcaa78942816 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 29 Apr 2011 10:58:33 -0700 Subject: [PATCH 28/32] 6522514: Extending Arc2D.Double and serializing the object causes InvalidClassException Reviewed-by: prr --- jdk/src/share/classes/java/awt/geom/Arc2D.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/geom/Arc2D.java b/jdk/src/share/classes/java/awt/geom/Arc2D.java index 86653be120c..802ec5a5297 100644 --- a/jdk/src/share/classes/java/awt/geom/Arc2D.java +++ b/jdk/src/share/classes/java/awt/geom/Arc2D.java @@ -681,7 +681,7 @@ public abstract class Arc2D extends RectangularShape { * @see java.awt.geom.Arc2D.Float * @see java.awt.geom.Arc2D.Double */ - Arc2D() { + protected Arc2D() { this(OPEN); } From 589a17bd790d360f3b15edcd5ed24845a22dcebb Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 29 Apr 2011 16:27:34 -0700 Subject: [PATCH 29/32] 6982632: closed/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java fails Reviewed-by: prr --- .../MTGraphicsAccessTest.java | 361 ++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java diff --git a/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java b/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java new file mode 100644 index 00000000000..569af1f3aaf --- /dev/null +++ b/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2010, 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. + * + * 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. + */ + +/* + @test + @bug 5089429 6982632 + @summary Checks that we don't crash if rendering operations and state + changes are performed on a graphics context from different threads. + + @author Dmitri.Trembovetski@sun.com area=Graphics + @run main MTGraphicsAccessTest + */ + +import java.awt.*; +import java.awt.image.*; +import java.awt.geom.*; + +public class MTGraphicsAccessTest { + + // in seconds + static final long STANDALONE_RUN_TIME = 20; + static final long JTREG_RUN_TIME = 7; + + static boolean standaloneMode; + static boolean allowExceptions = true; + static long testRunTime; + + volatile boolean done; + volatile int stillRunning; + volatile int numexceptions; + + Graphics2D sharedGraphics; + BufferedImage sharedBI = + new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB); + + static final Paint colors[] = { + Color.red, + new Color(0x7f, 0xff, 0x00, 0x7f), + new GradientPaint(0, 0, Color.red, + 50, 50, new Color(0x7f, 0xff, 0x00, 0x7f)), + }; + static final Font fonts[] = { + new Font("Dialog", Font.PLAIN, 12), + new Font("Dialog", Font.BOLD, 16), + new Font("Dialog", Font.ITALIC, 18), + }; + static final AlphaComposite comps[] = { + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f), + AlphaComposite.Src, + AlphaComposite.Xor, + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f), + null, + }; + static final Stroke strokes[] = { + new BasicStroke(), + new BasicStroke(0.0f), + new BasicStroke(2.0f), + new BasicStroke(2.0f, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_BEVEL), + new BasicStroke(5.0f, BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_ROUND), + new BasicStroke(0.0f, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND, 0, + new float[]{0,6,0,6}, 0), + }; + static final AffineTransform transforms[] = { + new AffineTransform(), + AffineTransform.getRotateInstance(10.0), + AffineTransform.getShearInstance(10.0, 4.0), + AffineTransform.getScaleInstance(1.1, 1.2), + AffineTransform.getScaleInstance(3.0, 2.0), + }; + + public MTGraphicsAccessTest() { + BufferedImage bi = + new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB); + sharedGraphics = (Graphics2D)bi.getGraphics(); + + done = false; + numexceptions = 0; + + for (int i = 0; i < (standaloneMode ? stateChangers.length : 3); i++) { + (new TesterThread(stateChangers[i])).start(); + } + for (int i = 0; i < (standaloneMode ? renderTests.length : 5); i++) { + (new TesterThread(renderTests[i])).start(); + } + + mysleep(testRunTime); + done = true; + while (stillRunning > 0) { mysleep(500); } + + if (numexceptions == 0) { + System.err.println("Test passed"); + } else if (!allowExceptions) { + throw new RuntimeException("Test failed with "+ + numexceptions+" exceptions"); + } else { + System.err.println("Test finished with "+ + numexceptions+" exceptions"); + } + } + + private void mysleep(long time) { + try { + // add +/-5ms variance to increase randomness + Thread.sleep(time + (long)(5 - Math.random()*10)); + } catch (InterruptedException e) {}; + } + + public static void usage(String message) { + if (message != null) { + System.err.println(message); + } + System.err.println("Usage: MTGraphicsAccessTest [-full] "+ + "[-time N/forever] [-help]"); + System.err.println(" -full: run full suite of tests "+ + "(default: limited number of tests is run)"); + System.err.println(" -time N: test duration in seconds/forever"+ + " (default: "+JTREG_RUN_TIME+"s for the short suite, "+ + STANDALONE_RUN_TIME+"s for the full suite)"); + System.err.println(" -help: print this help page"); + System.exit(1); + } + + public static void main(String[] args) { + boolean testRunSet = false; + for (int i = 0; i < args.length; i++) { + if ("-full".equals(args[i])) { + standaloneMode = true; + System.err.println("Running complete list of tests"); + } else if ("-noexc".equals(args[i])) { + allowExceptions = false; + } else if ("-time".equals(args[i])) { + try { + String time = args[++i]; + if ("forever".equals(time)) { + testRunTime = (Long.MAX_VALUE - 20)/1000; + } else { + testRunTime = 1000*Integer.parseInt(time); + } + testRunSet = true; + } catch (NumberFormatException e) { + usage("Can't parse number of seconds: " + args[i]); + } catch (ArrayIndexOutOfBoundsException e1) { + usage("Missing the 'seconds' argument for -time parameter"); + } + } else if ("-help".equals(args[i])) { + usage(null); + } else { + usage("Unknown argument:" + args[i]); + } + } + + if (!testRunSet) { + testRunTime = 1000 * + (standaloneMode ? STANDALONE_RUN_TIME : JTREG_RUN_TIME); + } + + System.err.println("Approximate test run time: "+ + testRunTime/1000+" seconds"); + + new MTGraphicsAccessTest(); + } + + class TesterThread extends Thread { + Runnable testRunnable; + + public TesterThread(Runnable testRunnable) { + stillRunning++; + this.testRunnable = testRunnable; + } + + public void run() { + try { + while (!done) { + try { + testRunnable.run(); + yield(); + } catch (Throwable t) { + numexceptions++; + t.printStackTrace(); + } + } + } finally { + stillRunning--; + } + } + } + + final Runnable stateChangers[] = { + new Runnable() { + public void run() { + sharedGraphics.setClip(10, 10, 30, 30); + mysleep(10); + } + }, + new Runnable() { + public void run() { + sharedGraphics.setClip(10, 10, 30, 30); + mysleep(10); + } + }, + new Runnable() { + int c = 0; + public void run() { + sharedGraphics.setPaint(colors[c++ % colors.length]); + mysleep(10); + } + }, + new Runnable() { + boolean AA = false; + public void run() { + if (AA) { + sharedGraphics.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } else { + sharedGraphics.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + } + AA = !AA; + mysleep(10); + } + }, + new Runnable() { + int t = 0; + public void run() { + sharedGraphics.setTransform( + transforms[t++ % transforms.length]); + mysleep(10); + } + }, + new Runnable() { + int c = 0; + public void run() { + AlphaComposite comp = comps[c++ % comps.length]; + if (comp == null) { + sharedGraphics.setXORMode(Color.green); + } else { + sharedGraphics.setComposite(comp); + } + mysleep(10); + } + }, + new Runnable() { + int s = 0; + public void run() { + sharedGraphics.setStroke(strokes[s++ % strokes.length]); + mysleep(10); + } + }, + new Runnable() { + int f = 0; + public void run() { + sharedGraphics.setFont(fonts[f++ % fonts.length]); + mysleep(10); + } + }, + }; + + final Runnable renderTests[] = { + new Runnable() { + public void run() { + sharedGraphics.drawLine(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawLine(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawRect(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillRect(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawString("Stuff", 10, 10); + } + }, + new Runnable() { + public void run() { + sharedGraphics.draw3DRect(10, 10, 30, 30, true); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawImage(sharedBI, 10, 10, null); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fill3DRect(10, 10, 30, 30, false); + } + }, + // REMIND: copyArea doesn't work when transform is set.. + // new Runnable() { + // public void run() { + // sharedGraphics.copyArea(10, 10, 30, 30, 20, 20); + // } + // }, + new Runnable() { + public void run() { + sharedGraphics.drawRoundRect(10, 10, 30, 30, 20, 20); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillRoundRect(10, 10, 30, 30, 20, 20); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawArc(10, 10, 30, 30, 0, 90); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillArc(10, 10, 30, 30, 0, 90); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawOval(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillOval(10, 10, 30, 30); + } + } + }; +} From 2b924057aae6e39dcf586f2e14c0b88a14963b30 Mon Sep 17 00:00:00 2001 From: Igor Nekrestyanov Date: Sun, 1 May 2011 09:14:36 -0700 Subject: [PATCH 30/32] 7040803: regression: bugster fail to start Reviewed-by: mullan, weijun, ngthomas --- .../share/classes/java/util/jar/JarFile.java | 22 +- .../classes/java/util/jar/JarInputStream.java | 2 +- .../classes/java/util/jar/JarVerifier.java | 224 ++++++++++++---- .../classes/sun/security/pkcs/PKCS7.java | 176 +----------- .../classes/sun/security/pkcs/SignerInfo.java | 136 +++++++++- .../security/util/ManifestEntryVerifier.java | 4 +- .../security/util/SignatureFileManifest.java | 251 ------------------ .../security/util/SignatureFileVerifier.java | 172 ++++-------- .../jar/JarInputStream/ScanSignedJar.java | 7 +- .../TestIndexedJarWithBadSignature.java | 4 +- 10 files changed, 377 insertions(+), 621 deletions(-) delete mode 100644 jdk/src/share/classes/sun/security/util/SignatureFileManifest.java diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java index 20d0363f57a..79d0f84b7e1 100644 --- a/jdk/src/share/classes/java/util/jar/JarFile.java +++ b/jdk/src/share/classes/java/util/jar/JarFile.java @@ -37,7 +37,6 @@ import java.security.CodeSource; import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.misc.SharedSecrets; -import sun.security.util.SignatureFileVerifier; /** * The JarFile class is used to read the contents of a jar file @@ -179,7 +178,7 @@ class JarFile extends ZipFile { byte[] b = getBytes(manEntry); man = new Manifest(new ByteArrayInputStream(b)); if (!jvInitialized) { - jv = new JarVerifier(b, man); + jv = new JarVerifier(b); } } else { man = new Manifest(super.getInputStream(manEntry)); @@ -298,7 +297,10 @@ class JarFile extends ZipFile { if (names != null) { for (int i = 0; i < names.length; i++) { String name = names[i].toUpperCase(Locale.ENGLISH); - if (SignatureFileVerifier.isBlockOrSF(name)) { + if (name.endsWith(".DSA") || + name.endsWith(".RSA") || + name.endsWith(".EC") || + name.endsWith(".SF")) { // Assume since we found a signature-related file // that the jar is signed and that we therefore // need a JarVerifier and Manifest @@ -327,17 +329,17 @@ class JarFile extends ZipFile { if (names != null) { for (int i = 0; i < names.length; i++) { JarEntry e = getJarEntry(names[i]); - if (!e.isDirectory() && - SignatureFileVerifier.isBlock(names[i])) { + if (!e.isDirectory()) { if (mev == null) { mev = new ManifestEntryVerifier (getManifestFromReference()); } - String key = names[i].substring( - 0, names[i].lastIndexOf(".")); - jv.verifyBlock(names[i], - getBytes(e), - super.getInputStream(getJarEntry(key + ".SF"))); + byte[] b = getBytes(e); + if (b != null && b.length > 0) { + jv.beginEntry(e, mev); + jv.update(b.length, b, 0, b.length, mev); + jv.update(-1, null, 0, 0, mev); + } } } } diff --git a/jdk/src/share/classes/java/util/jar/JarInputStream.java b/jdk/src/share/classes/java/util/jar/JarInputStream.java index b84219ea87a..67f27be2975 100644 --- a/jdk/src/share/classes/java/util/jar/JarInputStream.java +++ b/jdk/src/share/classes/java/util/jar/JarInputStream.java @@ -95,7 +95,7 @@ class JarInputStream extends ZipInputStream { man.read(new ByteArrayInputStream(bytes)); closeEntry(); if (doVerify) { - jv = new JarVerifier(bytes, man); + jv = new JarVerifier(bytes); mev = new ManifestEntryVerifier(man); } return (JarEntry)super.getNextEntry(); diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java index 8c69ff5c583..4f84ac28eff 100644 --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java @@ -48,18 +48,35 @@ class JarVerifier { /* a table mapping names to code signers, for jar entries that have had their actual hashes verified */ - private Map verifiedSigners; + private Hashtable verifiedSigners; /* a table mapping names to code signers, for jar entries that have passed the .SF/.DSA/.EC -> MANIFEST check */ - private Map sigFileSigners; + private Hashtable sigFileSigners; + + /* a hash table to hold .SF bytes */ + private Hashtable sigFileData; + + /** "queue" of pending PKCS7 blocks that we couldn't parse + * until we parsed the .SF file */ + private ArrayList pendingBlocks; /* cache of CodeSigner objects */ private ArrayList signerCache; + /* Are we parsing a block? */ + private boolean parsingBlockOrSF = false; + + /* Are we done parsing META-INF entries? */ + private boolean parsingMeta = true; + /* Are there are files to verify? */ private boolean anyToVerify = true; + /* The output stream to use when keeping track of files we are interested + in */ + private ByteArrayOutputStream baos; + /** The ManifestDigester object */ private volatile ManifestDigester manDig; @@ -75,20 +92,20 @@ class JarVerifier { /** collect -DIGEST-MANIFEST values for blacklist */ private List manifestDigests; - /** The manifest object */ - Manifest man = null; - - public JarVerifier(byte rawBytes[], Manifest man) { - this.man = man; + public JarVerifier(byte rawBytes[]) { manifestRawBytes = rawBytes; - sigFileSigners = new HashMap(); - verifiedSigners = new HashMap(); + sigFileSigners = new Hashtable(); + verifiedSigners = new Hashtable(); + sigFileData = new Hashtable(11); + pendingBlocks = new ArrayList(); + baos = new ByteArrayOutputStream(); manifestDigests = new ArrayList(); } /** - * This method scans to see which entry we're parsing and keeps - * various state information depending on the file being parsed. + * This method scans to see which entry we're parsing and + * keeps various state information depending on what type of + * file is being parsed. */ public void beginEntry(JarEntry je, ManifestEntryVerifier mev) throws IOException @@ -112,6 +129,30 @@ class JarVerifier { * b. digest mismatch between the actual jar entry and the manifest */ + if (parsingMeta) { + String uname = name.toUpperCase(Locale.ENGLISH); + if ((uname.startsWith("META-INF/") || + uname.startsWith("/META-INF/"))) { + + if (je.isDirectory()) { + mev.setEntry(null, je); + return; + } + + if (SignatureFileVerifier.isBlockOrSF(uname)) { + /* We parse only DSA, RSA or EC PKCS7 blocks. */ + parsingBlockOrSF = true; + baos.reset(); + mev.setEntry(null, je); + } + return; + } + } + + if (parsingMeta) { + doneWithMeta(); + } + if (je.isDirectory()) { mev.setEntry(null, je); return; @@ -147,7 +188,11 @@ class JarVerifier { throws IOException { if (b != -1) { - mev.update((byte)b); + if (parsingBlockOrSF) { + baos.write(b); + } else { + mev.update((byte)b); + } } else { processEntry(mev); } @@ -162,7 +207,11 @@ class JarVerifier { throws IOException { if (n != -1) { - mev.update(b, off, n); + if (parsingBlockOrSF) { + baos.write(b, off, n); + } else { + mev.update(b, off, n); + } } else { processEntry(mev); } @@ -174,10 +223,101 @@ class JarVerifier { private void processEntry(ManifestEntryVerifier mev) throws IOException { - JarEntry je = mev.getEntry(); - if ((je != null) && (je.signers == null)) { - je.signers = mev.verify(verifiedSigners, sigFileSigners); - je.certs = mapSignersToCertArray(je.signers); + if (!parsingBlockOrSF) { + JarEntry je = mev.getEntry(); + if ((je != null) && (je.signers == null)) { + je.signers = mev.verify(verifiedSigners, sigFileSigners); + je.certs = mapSignersToCertArray(je.signers); + } + } else { + + try { + parsingBlockOrSF = false; + + if (debug != null) { + debug.println("processEntry: processing block"); + } + + String uname = mev.getEntry().getName() + .toUpperCase(Locale.ENGLISH); + + if (uname.endsWith(".SF")) { + String key = uname.substring(0, uname.length()-3); + byte bytes[] = baos.toByteArray(); + // add to sigFileData in case future blocks need it + sigFileData.put(key, bytes); + // check pending blocks, we can now process + // anyone waiting for this .SF file + Iterator it = pendingBlocks.iterator(); + while (it.hasNext()) { + SignatureFileVerifier sfv = + (SignatureFileVerifier) it.next(); + if (sfv.needSignatureFile(key)) { + if (debug != null) { + debug.println( + "processEntry: processing pending block"); + } + + sfv.setSignatureFile(bytes); + sfv.process(sigFileSigners, manifestDigests); + } + } + return; + } + + // now we are parsing a signature block file + + String key = uname.substring(0, uname.lastIndexOf(".")); + + if (signerCache == null) + signerCache = new ArrayList(); + + if (manDig == null) { + synchronized(manifestRawBytes) { + if (manDig == null) { + manDig = new ManifestDigester(manifestRawBytes); + manifestRawBytes = null; + } + } + } + + SignatureFileVerifier sfv = + new SignatureFileVerifier(signerCache, + manDig, uname, baos.toByteArray()); + + if (sfv.needSignatureFileBytes()) { + // see if we have already parsed an external .SF file + byte[] bytes = (byte[]) sigFileData.get(key); + + if (bytes == null) { + // put this block on queue for later processing + // since we don't have the .SF bytes yet + // (uname, block); + if (debug != null) { + debug.println("adding pending block"); + } + pendingBlocks.add(sfv); + return; + } else { + sfv.setSignatureFile(bytes); + } + } + sfv.process(sigFileSigners, manifestDigests); + + } catch (IOException ioe) { + // e.g. sun.security.pkcs.ParsingException + if (debug != null) debug.println("processEntry caught: "+ioe); + // ignore and treat as unsigned + } catch (SignatureException se) { + if (debug != null) debug.println("processEntry caught: "+se); + // ignore and treat as unsigned + } catch (NoSuchAlgorithmException nsae) { + if (debug != null) debug.println("processEntry caught: "+nsae); + // ignore and treat as unsigned + } catch (CertificateException ce) { + if (debug != null) debug.println("processEntry caught: "+ce); + // ignore and treat as unsigned + } } } @@ -214,15 +354,15 @@ class JarVerifier { * Force a read of the entry data to generate the * verification hash. */ - try (InputStream s = jar.getInputStream(entry)) { + try { + InputStream s = jar.getInputStream(entry); byte[] buffer = new byte[1024]; int n = buffer.length; while (n != -1) { n = s.read(buffer, 0, buffer.length); } + s.close(); } catch (IOException e) { - // Ignore. When an exception is thrown, code signer - // will not be assigned. } } return getCodeSigners(name); @@ -268,7 +408,11 @@ class JarVerifier { */ void doneWithMeta() { + parsingMeta = false; anyToVerify = !sigFileSigners.isEmpty(); + baos = null; + sigFileData = null; + pendingBlocks = null; signerCache = null; manDig = null; // MANIFEST.MF is always treated as signed and verified, @@ -279,41 +423,6 @@ class JarVerifier { } } - /** - * Verifies a PKCS7 SignedData block - * @param key name of block - * @param block the pkcs7 file - * @param ins the clear data - */ - void verifyBlock(String key, byte[] block, InputStream ins) { - try { - if (signerCache == null) - signerCache = new ArrayList(); - - if (manDig == null) { - synchronized(manifestRawBytes) { - if (manDig == null) { - manDig = new ManifestDigester(manifestRawBytes); - manifestRawBytes = null; - } - } - } - SignatureFileVerifier sfv = - new SignatureFileVerifier(signerCache, man, - manDig, key, block); - - if (sfv.needSignatureFile()) { - // see if we have already parsed an external .SF file - sfv.setSignatureFile(ins); - } - sfv.process(sigFileSigners, manifestDigests); - } catch (Exception e) { - if (debug != null) { - e.printStackTrace(); - } - } - } - static class VerifierStream extends java.io.InputStream { private InputStream is; @@ -444,7 +553,10 @@ class JarVerifier { * but this handles a CodeSource of any type, just in case. */ CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true); - List sourceList = Arrays.asList(sources); + List sourceList = new ArrayList(); + for (int i = 0; i < sources.length; i++) { + sourceList.add(sources[i]); + } int j = sourceList.indexOf(cs); if (j != -1) { CodeSigner[] match; diff --git a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java index 72a2e5f9f3e..54e52151256 100644 --- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java @@ -38,7 +38,6 @@ import java.security.*; import sun.security.util.*; import sun.security.x509.AlgorithmId; import sun.security.x509.CertificateIssuerName; -import sun.security.x509.KeyUsageExtension; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertInfo; import sun.security.x509.X509CRLImpl; @@ -493,7 +492,7 @@ public class PKCS7 { // CRLs (optional) if (crls != null && crls.length != 0) { // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder - Set implCRLs = new HashSet<>(crls.length); + Set implCRLs = new HashSet(crls.length); for (X509CRL crl: crls) { if (crl instanceof X509CRLImpl) implCRLs.add((X509CRLImpl) crl); @@ -530,168 +529,6 @@ public class PKCS7 { block.encode(out); } - /** - * Verifying signed data using an external chunked data source. - */ - public static class PKCS7Verifier { - - private final SignerInfo si; // Signer to verify - private final MessageDigest md; // MessageDigest object for chunks - private final Signature sig; // Signature object for chunks - - private PKCS7Verifier(SignerInfo si, MessageDigest md, Signature sig) { - this.si = si; - this.md = md; - this.sig = sig; - } - - public static PKCS7Verifier from(PKCS7 block, SignerInfo si) throws - SignatureException, NoSuchAlgorithmException { - - try { - MessageDigest md = null; - Signature sig; - - ContentInfo content = block.getContentInfo(); - String digestAlgname = si.getDigestAlgorithmId().getName(); - - // if there are authenticate attributes, feed data chunks to - // the message digest. In this case, pv.md is not null - if (si.authenticatedAttributes != null) { - // first, check content type - ObjectIdentifier contentType = (ObjectIdentifier) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.CONTENT_TYPE_OID); - if (contentType == null || - !contentType.equals(content.contentType)) - return null; // contentType does not match, bad SignerInfo - - // now, check message digest - byte[] messageDigest = (byte[]) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.MESSAGE_DIGEST_OID); - - if (messageDigest == null) // fail if there is no message digest - return null; - - md = MessageDigest.getInstance(digestAlgname); - } - - // put together digest algorithm and encryption algorithm - // to form signing algorithm - String encryptionAlgname = - si.getDigestEncryptionAlgorithmId().getName(); - - // Workaround: sometimes the encryptionAlgname is actually - // a signature name - String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); - if (tmp != null) encryptionAlgname = tmp; - String algname = AlgorithmId.makeSigAlg( - digestAlgname, encryptionAlgname); - - sig = Signature.getInstance(algname); - X509Certificate cert = si.getCertificate(block); - - if (cert == null) { - return null; - } - if (cert.hasUnsupportedCriticalExtension()) { - throw new SignatureException("Certificate has unsupported " - + "critical extension(s)"); - } - - // Make sure that if the usage of the key in the certificate is - // restricted, it can be used for digital signatures. - // XXX We may want to check for additional extensions in the - // future. - boolean[] keyUsageBits = cert.getKeyUsage(); - if (keyUsageBits != null) { - KeyUsageExtension keyUsage; - try { - // We don't care whether or not this extension was marked - // critical in the certificate. - // We're interested only in its value (i.e., the bits set) - // and treat the extension as critical. - keyUsage = new KeyUsageExtension(keyUsageBits); - } catch (IOException ioe) { - throw new SignatureException("Failed to parse keyUsage " - + "extension"); - } - - boolean digSigAllowed = ((Boolean)keyUsage.get( - KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue(); - - boolean nonRepuAllowed = ((Boolean)keyUsage.get( - KeyUsageExtension.NON_REPUDIATION)).booleanValue(); - - if (!digSigAllowed && !nonRepuAllowed) { - throw new SignatureException("Key usage restricted: " - + "cannot be used for " - + "digital signatures"); - } - } - - PublicKey key = cert.getPublicKey(); - sig.initVerify(key); - return new PKCS7Verifier(si, md, sig); - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); - - } catch (InvalidKeyException e) { - throw new SignatureException("InvalidKey: " + e.getMessage()); - - } - } - - public void update(byte[] data, int off, int end) - throws SignatureException { - if (md != null) { - md.update(data, off, end-off); - } else { - sig.update(data, off, end-off); - } - } - - public SignerInfo verify() throws SignatureException { - try { - // if there are authenticate attributes, get the message - // digest and compare it with the digest of data - if (md != null) { - // now, check message digest - byte[] messageDigest = (byte[]) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.MESSAGE_DIGEST_OID); - - byte[] computedMessageDigest = md.digest(); - - if (!MessageDigest.isEqual( - messageDigest, computedMessageDigest)) { - return null; - } - - // message digest attribute matched - // digest of original data - - // the data actually signed is the DER encoding of - // the authenticated attributes (tagged with - // the "SET OF" tag, not 0xA0). - byte[] dataSigned = si.authenticatedAttributes.getDerEncoding(); - sig.update(dataSigned); - } - - if (sig.verify(si.getEncryptedDigest())) { - return si; - } - - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); - } - return null; - } - } - /** * This verifies a given SignerInfo. * @@ -717,16 +554,19 @@ public class PKCS7 { public SignerInfo[] verify(byte[] bytes) throws NoSuchAlgorithmException, SignatureException { - List intResult = new ArrayList<>(); + Vector intResult = new Vector(); for (int i = 0; i < signerInfos.length; i++) { SignerInfo signerInfo = verify(signerInfos[i], bytes); if (signerInfo != null) { - intResult.add(signerInfo); + intResult.addElement(signerInfo); } } - if (!intResult.isEmpty()) { - return intResult.toArray(new SignerInfo[intResult.size()]); + if (intResult.size() != 0) { + + SignerInfo[] result = new SignerInfo[intResult.size()]; + intResult.copyInto(result); + return result; } return null; } diff --git a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java index 6addf69e416..93fab9df4e0 100644 --- a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java +++ b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java @@ -230,7 +230,7 @@ public class SignerInfo implements DerEncoder { if (userCert == null) return null; - ArrayList certList = new ArrayList<>(); + ArrayList certList = new ArrayList(); certList.add(userCert); X509Certificate[] pkcsCerts = block.getCertificates(); @@ -276,20 +276,132 @@ public class SignerInfo implements DerEncoder { /* Returns null if verify fails, this signerInfo if verify succeeds. */ SignerInfo verify(PKCS7 block, byte[] data) - throws NoSuchAlgorithmException, SignatureException { + throws NoSuchAlgorithmException, SignatureException { - PKCS7.PKCS7Verifier p7v = PKCS7.PKCS7Verifier.from(block, this); - if (p7v == null) return null; - if (data == null) { - try { - data = block.getContentInfo().getContentBytes(); - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); + try { + + ContentInfo content = block.getContentInfo(); + if (data == null) { + data = content.getContentBytes(); } + + String digestAlgname = getDigestAlgorithmId().getName(); + + byte[] dataSigned; + + // if there are authenticate attributes, get the message + // digest and compare it with the digest of data + if (authenticatedAttributes == null) { + dataSigned = data; + } else { + + // first, check content type + ObjectIdentifier contentType = (ObjectIdentifier) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.CONTENT_TYPE_OID); + if (contentType == null || + !contentType.equals(content.contentType)) + return null; // contentType does not match, bad SignerInfo + + // now, check message digest + byte[] messageDigest = (byte[]) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.MESSAGE_DIGEST_OID); + + if (messageDigest == null) // fail if there is no message digest + return null; + + MessageDigest md = MessageDigest.getInstance(digestAlgname); + byte[] computedMessageDigest = md.digest(data); + + if (messageDigest.length != computedMessageDigest.length) + return null; + for (int i = 0; i < messageDigest.length; i++) { + if (messageDigest[i] != computedMessageDigest[i]) + return null; + } + + // message digest attribute matched + // digest of original data + + // the data actually signed is the DER encoding of + // the authenticated attributes (tagged with + // the "SET OF" tag, not 0xA0). + dataSigned = authenticatedAttributes.getDerEncoding(); + } + + // put together digest algorithm and encryption algorithm + // to form signing algorithm + String encryptionAlgname = + getDigestEncryptionAlgorithmId().getName(); + + // Workaround: sometimes the encryptionAlgname is actually + // a signature name + String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); + if (tmp != null) encryptionAlgname = tmp; + String algname = AlgorithmId.makeSigAlg( + digestAlgname, encryptionAlgname); + + Signature sig = Signature.getInstance(algname); + X509Certificate cert = getCertificate(block); + + if (cert == null) { + return null; + } + if (cert.hasUnsupportedCriticalExtension()) { + throw new SignatureException("Certificate has unsupported " + + "critical extension(s)"); + } + + // Make sure that if the usage of the key in the certificate is + // restricted, it can be used for digital signatures. + // XXX We may want to check for additional extensions in the + // future. + boolean[] keyUsageBits = cert.getKeyUsage(); + if (keyUsageBits != null) { + KeyUsageExtension keyUsage; + try { + // We don't care whether or not this extension was marked + // critical in the certificate. + // We're interested only in its value (i.e., the bits set) + // and treat the extension as critical. + keyUsage = new KeyUsageExtension(keyUsageBits); + } catch (IOException ioe) { + throw new SignatureException("Failed to parse keyUsage " + + "extension"); + } + + boolean digSigAllowed = ((Boolean)keyUsage.get( + KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue(); + + boolean nonRepuAllowed = ((Boolean)keyUsage.get( + KeyUsageExtension.NON_REPUDIATION)).booleanValue(); + + if (!digSigAllowed && !nonRepuAllowed) { + throw new SignatureException("Key usage restricted: " + + "cannot be used for " + + "digital signatures"); + } + } + + PublicKey key = cert.getPublicKey(); + sig.initVerify(key); + + sig.update(dataSigned); + + if (sig.verify(encryptedDigest)) { + return this; + } + + } catch (IOException e) { + throw new SignatureException("IO error verifying signature:\n" + + e.getMessage()); + + } catch (InvalidKeyException e) { + throw new SignatureException("InvalidKey: " + e.getMessage()); + } - p7v.update(data, 0, data.length); - return p7v.verify(); + return null; } /* Verify the content of the pkcs7 block. */ diff --git a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java index 4fa1826cb37..3d1b4733c30 100644 --- a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java +++ b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java @@ -191,8 +191,8 @@ public class ManifestEntryVerifier { * * */ - public CodeSigner[] verify(Map verifiedSigners, - Map sigFileSigners) + public CodeSigner[] verify(Hashtable verifiedSigners, + Hashtable sigFileSigners) throws JarException { if (skip) { diff --git a/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java b/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java deleted file mode 100644 index fd00c1299a3..00000000000 --- a/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ - -package sun.security.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -/** - * This class provides streaming mode reading of manifest files. - * Used by {@link SignatureFileVerifier}. - */ -class SignatureFileManifest extends Manifest { - - /* - * Reading a manifest into this object by calling update(byte[]) on chunks. - * During the reading, the bytes are saved in (@code current} until a line - * is complete and the key-value pair is saved in {@code currentAttr}. When - * a section is complete, {@code consumeAttr} is called to merge - * {@code currentAttr} into main attributes or a named entry. - */ - - // Internal state during update() style reading - // 0. not in update mode - // 1, in update mode but main attributes not completed yet - // 2. main attributes completed, still reading the entries - private int state = 0; - - // The partial line read - private byte[] current; - - // Number of bytes in current - private int currentPos = 0; - - // The current Attribute - private Attributes currentAttr; - - /** - * Reads a manifest in chunks. - *

- * This method must be called in a row, reading chunks from a single - * manifest file by order. After all chunks are read, caller must call - * {@code update(null)} to fully consume the manifest. - *

- * The entry names and attributes read will be merged in with the current - * manifest entries. The {@link #read} method cannot be called inside a - * row of update calls. - *

- * Along with the calls, caller can call {@link #getMainAttributes()}, - * {@link #getAttributes(java.lang.String)} or {@link #getEntries()} - * to get already available contents. However, in order not to return - * partial result, when the main attributes in the new manifest is not - * consumed completely, {@link #getMainAttributes()} throws an - * {@code IllegalStateException}. When a certain named entry is not - * consumed completely, {@link #getAttributes(java.lang.String)} - * returns the old {@code Attributes} for the name (if it exists). - * - * @param data null for last call, otherwise, feeding chunks - * @param offset offset into data to begin read - * @param length length of data after offset to read - * @exception IOException if an I/O error has occurred - * @exception IllegalStateException if {@code update(null)} is called - * without any previous {@code update(non-null)} call - */ - public void update(byte[] data, int offset, int length) throws IOException { - - // The last call - if (data == null) { - if (state == 0) { - throw new IllegalStateException("No data to update"); - } - // We accept manifest not ended with \n or \n\n - if (hasLastByte()) { - consumeCurrent(); - } - // We accept empty lines at the end - if (!currentAttr.isEmpty()) { - consumeAttr(); - } - state = 0; // back to non-update state - current = null; - currentAttr = null; - return; - } - - // The first call - if (state == 0) { - current = new byte[1024]; - currentAttr = super.getMainAttributes(); // the main attribute - state = 1; - } - - int end = offset + length; - - while (offset < end) { - switch (data[offset]) { - case '\r': - break; // always skip - case '\n': - if (hasLastByte() && lastByte() == '\n') { // new section - consumeCurrent(); - consumeAttr(); - if (state == 1) { - state = 2; - } - currentAttr = new Attributes(2); - } else { - if (hasLastByte()) { - // save \n into current but do not parse, - // there might be a continuation later - ensureCapacity(); - current[currentPos++] = data[offset]; - } else if (state == 1) { - // there can be multiple empty lines between - // sections, but cannot be at the beginning - throw new IOException("invalid manifest format"); - } - } - break; - case ' ': - if (!hasLastByte()) { - throw new IOException("invalid manifest format"); - } else if (lastByte() == '\n') { - currentPos--; // continuation, remove last \n - } else { // a very normal ' ' - ensureCapacity(); - current[currentPos++] = data[offset]; - } - break; - default: - if (hasLastByte() && lastByte() == '\n') { - // The start of a new pair, not continuation - consumeCurrent(); // the last line read - } - ensureCapacity(); - current[currentPos++] = data[offset]; - break; - } - offset++; - } - } - - /** - * Returns the main Attributes for the Manifest. - * @exception IllegalStateException the main attributes is being read - * @return the main Attributes for the Manifest - */ - public Attributes getMainAttributes() { - if (state == 1) { - throw new IllegalStateException(); - } - return super.getMainAttributes(); - } - - /** - * Reads the Manifest from the specified InputStream. The entry - * names and attributes read will be merged in with the current - * manifest entries. - * - * @param is the input stream - * @exception IOException if an I/O error has occurred - * @exception IllegalStateException if called between two {@link #update} - * calls - */ - public void read(InputStream is) throws IOException { - if (state != 0) { - throw new IllegalStateException("Cannot call read between updates"); - } - super.read(is); - } - - /* - * ---------- Helper methods ----------------- - */ - - private void ensureCapacity() { - if (currentPos >= current.length-1) { - current = Arrays.copyOf(current, current.length*2); - } - } - - private boolean hasLastByte() { - return currentPos > 0; - } - - private byte lastByte() { - return current[currentPos-1]; - } - - // Parse current as key:value and save into currentAttr. - // There MUST be something inside current. - private void consumeCurrent() throws IOException { - // current normally has a \n end, except for the last line - if (current[currentPos-1] == '\n') currentPos--; - for (int i=0; i createdDigests; @@ -86,7 +83,6 @@ public class SignatureFileVerifier { * @param rawBytes the raw bytes of the signature block file */ public SignatureFileVerifier(ArrayList signerCache, - Manifest man, ManifestDigester md, String name, byte rawBytes[]) @@ -98,18 +94,13 @@ public class SignatureFileVerifier { try { obj = Providers.startJarVerification(); block = new PKCS7(rawBytes); - byte[] contentData = block.getContentInfo().getData(); - if (contentData != null) { - sfStream = new ByteArrayInputStream(contentData); - } + sfBytes = block.getContentInfo().getData(); certificateFactory = CertificateFactory.getInstance("X509"); } finally { Providers.stopJarVerification(obj); } this.name = name.substring(0, name.lastIndexOf(".")) .toUpperCase(Locale.ENGLISH); - - this.man = man; this.md = md; this.signerCache = signerCache; } @@ -117,13 +108,31 @@ public class SignatureFileVerifier { /** * returns true if we need the .SF file */ - public boolean needSignatureFile() + public boolean needSignatureFileBytes() { - return sfStream == null; + + return sfBytes == null; } - public void setSignatureFile(InputStream ins) { - this.sfStream = ins; + + /** + * returns true if we need this .SF file. + * + * @param name the name of the .SF file without the extension + * + */ + public boolean needSignatureFile(String name) + { + return this.name.equalsIgnoreCase(name); + } + + /** + * used to set the raw bytes of the .SF file when it + * is external to the signature block file. + */ + public void setSignatureFile(byte sfBytes[]) + { + this.sfBytes = sfBytes; } /** @@ -136,18 +145,12 @@ public class SignatureFileVerifier { * Signature File or PKCS7 block file name */ public static boolean isBlockOrSF(String s) { - return s.endsWith(".SF") || isBlock(s); - } - - /** - * Utility method used by JarVerifier to determine PKCS7 block - * files names that are supported - * - * @param s file name - * @return true if the input file name is a PKCS7 block file name - */ - public static boolean isBlock(String s) { - return s.endsWith(".DSA") || s.endsWith(".RSA") || s.endsWith(".EC"); + // we currently only support DSA and RSA PKCS7 blocks + if (s.endsWith(".SF") || s.endsWith(".DSA") || + s.endsWith(".RSA") || s.endsWith(".EC")) { + return true; + } + return false; } /** get digest from cache */ @@ -177,7 +180,7 @@ public class SignatureFileVerifier { * * */ - public void process(Map signers, + public void process(Hashtable signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException @@ -194,86 +197,31 @@ public class SignatureFileVerifier { } - private void processImpl(Map signers, + private void processImpl(Hashtable signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException { - SignatureFileManifest sf = new SignatureFileManifest(); - InputStream ins = sfStream; + Manifest sf = new Manifest(); + sf.read(new ByteArrayInputStream(sfBytes)); - byte[] buffer = new byte[4096]; - int sLen = block.getSignerInfos().length; - boolean mainOK = false; // main attributes of SF is available... - boolean manifestSigned = false; // and it matches MANIFEST.MF - BASE64Decoder decoder = new BASE64Decoder(); + String version = + sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION); - PKCS7.PKCS7Verifier[] pvs = new PKCS7.PKCS7Verifier[sLen]; - for (int i=0; i intResult = new ArrayList<>(sLen); - for (int i = 0; i < sLen; i++) { - if (pvs[i] != null) { - SignerInfo signerInfo = pvs[i].verify(); - if (signerInfo != null) { - intResult.add(signerInfo); - } - } - } - if (intResult.isEmpty()) { + if (infos == null) { throw new SecurityException("cannot verify signature block file " + name); } - SignerInfo[] infos = - intResult.toArray(new SignerInfo[intResult.size()]); + BASE64Decoder decoder = new BASE64Decoder(); CodeSigner[] newSigners = getSigners(infos, block); @@ -281,37 +229,26 @@ public class SignatureFileVerifier { if (newSigners == null) return; + Iterator> entries = + sf.getEntries().entrySet().iterator(); + + // see if we can verify the whole manifest first + boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests); + // verify manifest main attributes if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) { throw new SecurityException ("Invalid signature file digest for Manifest main attributes"); } - Iterator> entries; - - if (manifestSigned) { - if (debug != null) { - debug.println("full manifest signature match, " - + "update signer info from MANIFEST.MF"); - } - entries = man.getEntries().entrySet().iterator(); - } else { - if (debug != null) { - debug.println("full manifest signature unmatch, " - + "update signer info from SF file"); - } - entries = sf.getEntries().entrySet().iterator(); - } - - // go through each section - + // go through each section in the signature file while(entries.hasNext()) { Map.Entry e = entries.next(); String name = e.getKey(); if (manifestSigned || - (verifySection(e.getValue(), name, md, decoder))) { + (verifySection(e.getValue(), name, md, decoder))) { if (name.startsWith("./")) name = name.substring(2); @@ -656,6 +593,7 @@ public class SignatureFileVerifier { if (set == subset) return true; + boolean match; for (int i = 0; i < subset.length; i++) { if (!contains(set, subset[i])) return false; @@ -675,6 +613,8 @@ public class SignatureFileVerifier { if ((oldSigners == null) && (signers == newSigners)) return true; + boolean match; + // make sure all oldSigners are in signers if ((oldSigners != null) && !isSubSet(oldSigners, signers)) return false; @@ -698,7 +638,7 @@ public class SignatureFileVerifier { } void updateSigners(CodeSigner[] newSigners, - Map signers, String name) { + Hashtable signers, String name) { CodeSigner[] oldSigners = signers.get(name); diff --git a/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java b/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java index 425e5659715..86dbf793e74 100644 --- a/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java +++ b/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, 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 @@ -27,11 +27,9 @@ * @summary Confirm that JarEntry.getCertificates identifies signed entries. */ -import java.io.*; import java.net.URL; import java.security.CodeSigner; import java.security.cert.Certificate; -import java.util.Enumeration; import java.util.jar.*; /* @@ -72,6 +70,9 @@ public class ScanSignedJar { if (signers == null && certificates == null) { System.out.println("[unsigned]\t" + name + "\t(" + size + " bytes)"); + if (name.equals("Count.class")) { + throw new Exception("Count.class should be signed"); + } } else if (signers != null && certificates != null) { System.out.println("[" + signers.length + (signers.length == 1 ? " signer" : " signers") + "]\t" + diff --git a/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java b/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java index 977c10121da..2e74eb10069 100644 --- a/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java +++ b/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, 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 @@ -37,7 +37,7 @@ public class TestIndexedJarWithBadSignature { public static void main(String...args) throws Throwable { try (JarInputStream jis = new JarInputStream( - new FileInputStream(System.getProperty("tst.src", ".") + + new FileInputStream(System.getProperty("test.src", ".") + System.getProperty("file.separator") + "BadSignedJar.jar"))) { From 1003e3e74421ba6cd6ae291a4784341316c8fa9e Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Mon, 2 May 2011 14:38:22 -0700 Subject: [PATCH 31/32] 6563734: Path2D.Float and Path2D.Double should have final getPathIterator methods Reviewed-by: prr --- jdk/src/share/classes/java/awt/geom/Path2D.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/awt/geom/Path2D.java b/jdk/src/share/classes/java/awt/geom/Path2D.java index c84948c8ee9..39f7d992b28 100644 --- a/jdk/src/share/classes/java/awt/geom/Path2D.java +++ b/jdk/src/share/classes/java/awt/geom/Path2D.java @@ -732,7 +732,7 @@ public abstract class Path2D implements Shape, Cloneable { * * @since 1.6 */ - public PathIterator getPathIterator(AffineTransform at) { + public final PathIterator getPathIterator(AffineTransform at) { if (at == null) { return new CopyIterator(this); } else { @@ -1461,7 +1461,7 @@ public abstract class Path2D implements Shape, Cloneable { * of this {@code Shape}'s outline * @since 1.6 */ - public PathIterator getPathIterator(AffineTransform at) { + public final PathIterator getPathIterator(AffineTransform at) { if (at == null) { return new CopyIterator(this); } else { @@ -2342,8 +2342,8 @@ public abstract class Path2D implements Shape, Cloneable { * * @since 1.6 */ - public PathIterator getPathIterator(AffineTransform at, - double flatness) + public final PathIterator getPathIterator(AffineTransform at, + double flatness) { return new FlatteningPathIterator(getPathIterator(at), flatness); } From 2b767e1070b9a77798dd9152afba9f0243a0640e Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 3 May 2011 15:19:04 +0400 Subject: [PATCH 32/32] 7016528: Deadlock during mutual initialization of DataTransferer and DataTransferer$DataFlavorComparator Reviewed-by: dav, art, denis --- .../sun/awt/datatransfer/DataTransferer.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index e8fe5859b2d..82ff8899349 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -29,12 +29,10 @@ import java.awt.AWTError; import java.awt.EventQueue; import java.awt.Image; import java.awt.Graphics; -import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.FlavorMap; import java.awt.datatransfer.FlavorTable; -import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; @@ -66,8 +64,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessControlContext; -import java.security.AccessControlException; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; @@ -171,7 +167,26 @@ public abstract class DataTransferer { */ public static final DataFlavor javaTextEncodingFlavor; - private static SortedSet standardEncodings; + /** + * Lazy initialization of Standard Encodings. + */ + private static class StandardEncodingsHolder { + private static final SortedSet standardEncodings = load(); + + private static SortedSet load() { + final Comparator comparator = + new CharsetComparator(IndexedComparator.SELECT_WORST); + final SortedSet tempSet = new TreeSet(comparator); + tempSet.add("US-ASCII"); + tempSet.add("ISO-8859-1"); + tempSet.add("UTF-8"); + tempSet.add("UTF-16BE"); + tempSet.add("UTF-16LE"); + tempSet.add("UTF-16"); + tempSet.add(getDefaultTextCharset()); + return Collections.unmodifiableSortedSet(tempSet); + } + } /** * Tracks whether a particular text/* MIME type supports the charset @@ -509,18 +524,7 @@ public abstract class DataTransferer { * non-standard, character sets are not included. */ public static Iterator standardEncodings() { - if (standardEncodings == null) { - TreeSet tempSet = new TreeSet(defaultCharsetComparator); - tempSet.add("US-ASCII"); - tempSet.add("ISO-8859-1"); - tempSet.add("UTF-8"); - tempSet.add("UTF-16BE"); - tempSet.add("UTF-16LE"); - tempSet.add("UTF-16"); - tempSet.add(getDefaultTextCharset()); - standardEncodings = Collections.unmodifiableSortedSet(tempSet); - } - return standardEncodings.iterator(); + return StandardEncodingsHolder.standardEncodings.iterator(); } /** @@ -2398,7 +2402,9 @@ search: public static DataFlavor[] setToSortedDataFlavorArray(Set flavorsSet) { DataFlavor[] flavors = new DataFlavor[flavorsSet.size()]; flavorsSet.toArray(flavors); - Arrays.sort(flavors, defaultFlavorComparator); + final Comparator comparator = + new DataFlavorComparator(IndexedComparator.SELECT_WORST); + Arrays.sort(flavors, comparator); return flavors; } @@ -2455,11 +2461,6 @@ search: return new ArrayList(); } - private static CharsetComparator defaultCharsetComparator = - new CharsetComparator(IndexedComparator.SELECT_WORST); - private static DataFlavorComparator defaultFlavorComparator = - new DataFlavorComparator(IndexedComparator.SELECT_WORST); - /** * A Comparator which includes a helper function for comparing two Objects * which are likely to be keys in the specified Map.