This commit is contained in:
Daniel D. Daugherty 2011-12-06 05:28:17 -08:00
commit 66ebef88a0
209 changed files with 8260 additions and 3291 deletions

View file

@ -134,3 +134,5 @@ fbf3cabc9e3bb1fcf710941d777cb0400505fbe6 jdk8-b09
f651ce87127980c58e3599daba964eba2f3b4026 jdk8-b10 f651ce87127980c58e3599daba964eba2f3b4026 jdk8-b10
cc1f5ce8e504d350e0b0c28c5f84333f8d540132 jdk8-b11 cc1f5ce8e504d350e0b0c28c5f84333f8d540132 jdk8-b11
86db042b3385c338e17f7664447fdc7d406dd19e jdk8-b12 86db042b3385c338e17f7664447fdc7d406dd19e jdk8-b12
4cc0ef72c812943743ef4765f1100e2fbe2b1a08 jdk8-b13
9ffaa48dbfb0f5936c2b789867d0785faec7071d jdk8-b14

View file

@ -134,3 +134,5 @@ fb1bc13260d76447e269e843859eb593fe2a8ab2 jdk8-b08
a6c4c248e8fa350c35014fa94bab5ac1a1ac3299 jdk8-b10 a6c4c248e8fa350c35014fa94bab5ac1a1ac3299 jdk8-b10
1defbc57940a56f0aa41e9dee87b71e8c8b71103 jdk8-b11 1defbc57940a56f0aa41e9dee87b71e8c8b71103 jdk8-b11
8e2104d565baee473895d5eba20e39f85ab4bf9f jdk8-b12 8e2104d565baee473895d5eba20e39f85ab4bf9f jdk8-b12
26fb81a1e9ceb9baffba216acd9ded62e9e9d5ab jdk8-b13
23aa7f2c80a2fa354c80decf03e7c2018177ef4e jdk8-b14

View file

@ -134,3 +134,5 @@ a891732c1a83082177ff7a4cf1506068d9cc0a47 jdk8-b09
cda87f7fefcee3b89742a57ce5ad9b03a54c210d jdk8-b10 cda87f7fefcee3b89742a57ce5ad9b03a54c210d jdk8-b10
0199e4fef5cc2bd234c65b93220459ef7a3bb3b1 jdk8-b11 0199e4fef5cc2bd234c65b93220459ef7a3bb3b1 jdk8-b11
31d70911b712c6b4e580a3110363d5f044cfed7a jdk8-b12 31d70911b712c6b4e580a3110363d5f044cfed7a jdk8-b12
5b9d9b839d3d7fe02347827221c97c6d242a6f96 jdk8-b13
e59c47de1ad8982ff3b0e843773a6902b36c2337 jdk8-b14

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -423,6 +423,13 @@ public abstract class CDRInputStream
impl.setByteBufferWithInfo(bbwi); impl.setByteBufferWithInfo(bbwi);
} }
/**
* return true if our ByteBuffer is sharing/equal to bb
*/
protected final boolean isSharing(ByteBuffer bb) {
return (getByteBuffer() == bb);
}
public final int getBufferLength() { public final int getBufferLength() {
return impl.getBufferLength(); return impl.getBufferLength();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -2412,7 +2412,6 @@ public class CDRInputStream_1_0 extends CDRInputStreamBase
if (bbwi != null && getByteBuffer() != null) if (bbwi != null && getByteBuffer() != null)
{ {
int bbHash = System.identityHashCode(bbwi.byteBuffer);
MessageMediator messageMediator = parent.getMessageMediator(); MessageMediator messageMediator = parent.getMessageMediator();
if (messageMediator != null) if (messageMediator != null)
{ {
@ -2420,13 +2419,7 @@ public class CDRInputStream_1_0 extends CDRInputStreamBase
(CDROutputObject)messageMediator.getOutputObject(); (CDROutputObject)messageMediator.getOutputObject();
if (outputObj != null) if (outputObj != null)
{ {
ByteBuffer outputBb = outputObj.getByteBuffer(); if (outputObj.isSharing(getByteBuffer()))
int oBbHash = 0;
if (outputBb != null)
{
oBbHash = System.identityHashCode(outputBb);
if (bbHash == oBbHash) // shared?
{ {
// Set OutputStream's ByteBuffer and bbwi to null // Set OutputStream's ByteBuffer and bbwi to null
// so its ByteBuffer cannot be released to the pool // so its ByteBuffer cannot be released to the pool
@ -2435,7 +2428,6 @@ public class CDRInputStream_1_0 extends CDRInputStreamBase
} }
} }
} }
}
// release this stream's ByteBuffer to the pool // release this stream's ByteBuffer to the pool
ByteBufferPool byteBufferPool = orb.getByteBufferPool(); ByteBufferPool byteBufferPool = orb.getByteBufferPool();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -357,6 +357,13 @@ public abstract class CDROutputStream
impl.setByteBuffer(byteBuffer); impl.setByteBuffer(byteBuffer);
} }
/**
* return true if our ByteBuffer is sharing/equal to bb
*/
protected final boolean isSharing(ByteBuffer bb) {
return (getByteBuffer() == bb);
}
public final boolean isLittleEndian() { public final boolean isLittleEndian() {
return impl.isLittleEndian(); return impl.isLittleEndian();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1902,7 +1902,6 @@ public class CDROutputStream_1_0 extends CDROutputStreamBase
if (getByteBufferWithInfo() != null && getByteBuffer() != null) if (getByteBufferWithInfo() != null && getByteBuffer() != null)
{ {
int bbHash = System.identityHashCode(bbwi.byteBuffer);
MessageMediator messageMediator = parent.getMessageMediator(); MessageMediator messageMediator = parent.getMessageMediator();
if (messageMediator != null) if (messageMediator != null)
{ {
@ -1910,13 +1909,7 @@ public class CDROutputStream_1_0 extends CDROutputStreamBase
(CDRInputObject)messageMediator.getInputObject(); (CDRInputObject)messageMediator.getInputObject();
if (inputObj != null) if (inputObj != null)
{ {
ByteBuffer inputBb = inputObj.getByteBuffer(); if (inputObj.isSharing(getByteBuffer()))
int iBbHash = 0;
if (inputBb != null)
{
iBbHash = System.identityHashCode(inputBb);
if (bbHash == iBbHash) // shared?
{ {
// Set InputStream's ByteBuffer and bbwi to null // Set InputStream's ByteBuffer and bbwi to null
// so its ByteBuffer cannot be released to the pool // so its ByteBuffer cannot be released to the pool
@ -1925,7 +1918,6 @@ public class CDROutputStream_1_0 extends CDROutputStreamBase
} }
} }
} }
}
// release this stream's ByteBuffer to the pool // release this stream's ByteBuffer to the pool
ByteBufferPool byteBufferPool = orb.getByteBufferPool(); ByteBufferPool byteBufferPool = orb.getByteBufferPool();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -2243,6 +2243,10 @@ public class IIOPInputStream
} }
try { try {
Class fieldCl = fields[i].getClazz();
if (objectValue != null && !fieldCl.isInstance(objectValue)) {
throw new IllegalArgumentException();
}
bridge.putObject( o, fields[i].getFieldID(), objectValue ) ; bridge.putObject( o, fields[i].getFieldID(), objectValue ) ;
// reflective code: fields[i].getField().set( o, objectValue ) ; // reflective code: fields[i].getField().set( o, objectValue ) ;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -2553,6 +2557,10 @@ public class IIOPInputStream
{ {
try { try {
Field fld = c.getDeclaredField( fieldName ) ; Field fld = c.getDeclaredField( fieldName ) ;
Class fieldCl = fld.getType();
if(v != null && !fieldCl.isInstance(v)) {
throw new Exception();
}
long key = bridge.objectFieldOffset( fld ) ; long key = bridge.objectFieldOffset( fld ) ;
bridge.putObject( o, key, v ) ; bridge.putObject( o, key, v ) ;
} catch (Exception e) { } catch (Exception e) {

View file

@ -197,3 +197,6 @@ d815de2e85e511b7deab2a83cf80c0224d011da9 jdk8-b10
6534482ff68ad79066dfe15dfb6d8905f09681bd hs23-b04 6534482ff68ad79066dfe15dfb6d8905f09681bd hs23-b04
1d3900713a67a0a39faf4e12c9c158d55aebef87 jdk8-b12 1d3900713a67a0a39faf4e12c9c158d55aebef87 jdk8-b12
3e609627e780736f372eb14d29bb9b5e53b21fbf hs23-b05 3e609627e780736f372eb14d29bb9b5e53b21fbf hs23-b05
b92ca8e229d29004f840c67e620833d23a346761 jdk8-b13
088d09a130ff02d8f5f05e92256baabe412f0439 jdk8-b14
6c2a55d4902f202e1c2de1df17b7da083a2c31e8 hs23-b06

View file

@ -55,6 +55,9 @@
# The makefiles are split this way so that "make foo" will run faster by not # The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm. # having to read the dependency files for the vm.
# needs to be set here since this Makefile doesn't include defs.make
OS_VENDOR:=$(shell uname -s)
include $(GAMMADIR)/make/scm.make include $(GAMMADIR)/make/scm.make
include $(GAMMADIR)/make/altsrc.make include $(GAMMADIR)/make/altsrc.make
@ -159,8 +162,15 @@ ifndef HOTSPOT_VM_DISTRO
endif endif
endif endif
# MACOSX FIXME: we should be able to run test_gamma (see MACOSX_PORT-214) ifeq ($(OS_VENDOR), Darwin)
ifdef ALWAYS_PASS_TEST_GAMMA # MACOSX FIXME: we should be able to run test_gamma (see MACOSX_PORT-214)
ifeq ($(ALWAYS_PASS_TEST_GAMMA),)
# ALWAYS_PASS_TEST_GAMMA wasn't set so we default to true on MacOS X
# until MACOSX_PORT-214 is fixed
ALWAYS_PASS_TEST_GAMMA=true
endif
endif
ifeq ($(ALWAYS_PASS_TEST_GAMMA), true)
TEST_GAMMA_STATUS= echo 'exit 0'; TEST_GAMMA_STATUS= echo 'exit 0';
else else
TEST_GAMMA_STATUS= TEST_GAMMA_STATUS=

View file

@ -37,11 +37,24 @@ include $(GAMMADIR)/make/sa.files
TOPDIR = $(shell echo `pwd`) TOPDIR = $(shell echo `pwd`)
GENERATED = $(TOPDIR)/../generated GENERATED = $(TOPDIR)/../generated
# tools.jar is needed by the JDI - SA binding # SA-JDI depends on the standard JDI classes.
ifeq ($(SA_APPLE_BOOT_JAVA),true) # Default SA_CLASSPATH location:
SA_CLASSPATH = $(BOOT_JAVA_HOME)/bundle/Classes/classes.jar DEF_SA_CLASSPATH=$(BOOT_JAVA_HOME)/lib/tools.jar
ifeq ($(ALT_SA_CLASSPATH),)
# no alternate specified; see if default exists
SA_CLASSPATH=$(shell test -f $(DEF_SA_CLASSPATH) && echo $(DEF_SA_CLASSPATH))
ifeq ($(SA_CLASSPATH),)
# the default doesn't exist
ifeq ($(OS_VENDOR), Darwin)
# A JDK from Apple doesn't have tools.jar; the JDI classes are
# are in the regular classes.jar file.
APPLE_JAR=$(BOOT_JAVA_HOME)/bundle/Classes/classes.jar
SA_CLASSPATH=$(shell test -f $(APPLE_JAR) && echo $(APPLE_JAR))
endif
endif
else else
SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar _JUNK_ := $(shell echo >&2 "INFO: ALT_SA_CLASSPATH=$(ALT_SA_CLASSPATH)")
SA_CLASSPATH=$(shell test -f $(ALT_SA_CLASSPATH) && echo $(ALT_SA_CLASSPATH))
endif endif
# TODO: if it's a modules image, check if SA module is installed. # TODO: if it's a modules image, check if SA module is installed.
@ -72,8 +85,8 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
exit 1; \ exit 1; \
fi fi
$(QUIETLY) if [ ! -f $(SA_CLASSPATH) -a ! -d $(MODULELIB_PATH) ] ; then \ $(QUIETLY) if [ ! -f "$(SA_CLASSPATH)" -a ! -d $(MODULELIB_PATH) ] ; then \
echo "Missing $(SA_CLASSPATH) file. Use 1.6.0 or later version of JDK";\ echo "Cannot find JDI classes. Use 1.6.0 or later version of JDK."; \
echo ""; \ echo ""; \
exit 1; \ exit 1; \
fi fi

View file

@ -134,3 +134,5 @@ de4794dd69c48b08029d158a972993ff9d5627df jdk8-b08
d21a4d5141c04bc9e88f2c0253121d449b66d667 jdk8-b10 d21a4d5141c04bc9e88f2c0253121d449b66d667 jdk8-b10
d1b7a4f6dd2065fdeafbcdfd9dcc0072da8c6881 jdk8-b11 d1b7a4f6dd2065fdeafbcdfd9dcc0072da8c6881 jdk8-b11
ca977d167697a561c04894187fc1c4d927582ffa jdk8-b12 ca977d167697a561c04894187fc1c4d927582ffa jdk8-b12
bcc739229f6384786c7ac0b52c1822c85674dcf1 jdk8-b13
9d0c9d638757cb09de18933b946fa04b4f3fb94f jdk8-b14

View file

@ -134,3 +134,5 @@ acffff22a9465005e8eb206224fae9f2ea4fd469 jdk8-b06
8e7fdc8e3c758644ca6d0fd70bb255e9d2e64cda jdk8-b10 8e7fdc8e3c758644ca6d0fd70bb255e9d2e64cda jdk8-b10
a12ab897a249feb7859a6e6cd84b49411f4c06ac jdk8-b11 a12ab897a249feb7859a6e6cd84b49411f4c06ac jdk8-b11
e6eed2ff5d5f62bdc815beb5276d23347600c760 jdk8-b12 e6eed2ff5d5f62bdc815beb5276d23347600c760 jdk8-b12
adf2a6b5fde14090beb9ebc40c4114132ddee731 jdk8-b13
54c4bf4b83ecc191351747d5d28da849d34c0243 jdk8-b14

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2007, 2010, 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -25,15 +25,15 @@
drops.master.copy.base=${drops.dir} drops.master.copy.base=${drops.dir}
jaxws_src.bundle.name=jdk7-jaxws2_2_4-b03-2011_05_27.zip jaxws_src.bundle.name=jdk8-jaxws2_2_4-b01-2011_07_22.zip
jaxws_src.bundle.md5.checksum=2f5b829ade70f67fe272d0b322e3e702 jaxws_src.bundle.md5.checksum=f64bedd3c512e6b1ca265fda2feb0905
jaxws_src.master.bundle.dir=${drops.master.copy.base} jaxws_src.master.bundle.dir=${drops.master.copy.base}
jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk7 jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk8
jaf_src.bundle.name=jdk7-jaf-2010_08_19.zip jaf_src.bundle.name=jdk8-jaf-2011_07_22.zip
jaf_src.bundle.md5.checksum=18d15dfd71117daadb332af003d08212 jaf_src.bundle.md5.checksum=18d15dfd71117daadb332af003d08212
jaf_src.master.bundle.dir=${drops.master.copy.base} jaf_src.master.bundle.dir=${drops.master.copy.base}
jaf_src.master.bundle.url.base=https://java.net/downloads/jax-ws/JDK7 jaf_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk8
#jaxws_tests.bundle.name=jdk7-jaxws-tests-2009_08_28.zip #jaxws_tests.bundle.name=jdk7-jaxws-tests-2009_08_28.zip
#jaxws_tests.master.bundle.dir=${drops.master.copy.base} #jaxws_tests.master.bundle.dir=${drops.master.copy.base}

View file

@ -134,3 +134,5 @@ f1ec21b8142168ff40f3278d2f6b5fe4bd5f3b26 jdk8-b09
4788745572ef2bde34924ef34e7e4d55ba07e979 jdk8-b10 4788745572ef2bde34924ef34e7e4d55ba07e979 jdk8-b10
7ab0d613cd1a271a9763ffb894dc1f0a5b95a7e4 jdk8-b11 7ab0d613cd1a271a9763ffb894dc1f0a5b95a7e4 jdk8-b11
09fd2067f715e4505c44b01c301258a4e8f8964e jdk8-b12 09fd2067f715e4505c44b01c301258a4e8f8964e jdk8-b12
4cb2e8679b27432854690cb688ea06d3b2d8e008 jdk8-b13
99632935785e2038b2fc836da9f2ede69dea294b jdk8-b14

View file

@ -71,7 +71,7 @@ include $(BUILDDIR)/common/internal/ImportComponents.gmk
ifeq ($(ARCH_DATA_MODEL),64) ifeq ($(ARCH_DATA_MODEL),64)
MAX_VM_MEMORY = 1024 MAX_VM_MEMORY = 1024
else else
MAX_VM_MEMORY = 512 MAX_VM_MEMORY = 612
endif endif
# List of all possible directories for javadoc to look for sources # List of all possible directories for javadoc to look for sources

View file

@ -232,6 +232,7 @@ FILES_src = \
sun/nio/cs/UTF_16BE.java \ sun/nio/cs/UTF_16BE.java \
sun/nio/cs/UTF_16LE.java \ sun/nio/cs/UTF_16LE.java \
sun/nio/cs/UTF_8.java \ sun/nio/cs/UTF_8.java \
sun/nio/cs/CESU_8.java \
sun/nio/cs/Unicode.java \ sun/nio/cs/Unicode.java \
sun/nio/cs/UnicodeDecoder.java \ sun/nio/cs/UnicodeDecoder.java \
sun/nio/cs/UnicodeEncoder.java \ sun/nio/cs/UnicodeEncoder.java \

View file

@ -28,6 +28,7 @@ PACKAGE = sun.net
PRODUCT = sun PRODUCT = sun
SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true
SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true
SUBDIRS_MAKEFLAGS += JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation,-path
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
SUBDIRS = others spi SUBDIRS = others spi

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -179,6 +179,12 @@ class HttpsURLConnection extends HttpURLConnection
throw new IllegalArgumentException( throw new IllegalArgumentException(
"no SSLSocketFactory specified"); "no SSLSocketFactory specified");
} }
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkSetFactory();
}
sslSocketFactory = sf; sslSocketFactory = sf;
} }

View file

@ -250,6 +250,8 @@ public class IdResolver {
int index=s==null ? elementIndex : names.indexOf(n.getNamespaceURI()); int index=s==null ? elementIndex : names.indexOf(n.getNamespaceURI());
index=(index<0) ? namesLength : index; index=(index<0) ? namesLength : index;
String name=n.getLocalName(); String name=n.getLocalName();
if (name == null)
name = n.getName();
if (name.length()>2) if (name.length()>2)
continue; continue;
String value=n.getNodeValue(); String value=n.getNodeValue();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package java.awt; package java.awt;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import sun.awt.AppContext;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -66,9 +67,6 @@ import java.lang.reflect.Field;
public class AWTKeyStroke implements Serializable { public class AWTKeyStroke implements Serializable {
static final long serialVersionUID = -6430539691155161871L; static final long serialVersionUID = -6430539691155161871L;
private static Map cache;
private static AWTKeyStroke cacheKey;
private static Constructor ctor = getCtor(AWTKeyStroke.class);
private static Map modifierKeywords; private static Map modifierKeywords;
/** /**
* Associates VK_XXX (as a String) with code (as Integer). This is * Associates VK_XXX (as a String) with code (as Integer). This is
@ -77,6 +75,25 @@ public class AWTKeyStroke implements Serializable {
*/ */
private static VKCollection vks; private static VKCollection vks;
//A key for the collection of AWTKeyStrokes within AppContext.
private static Object APP_CONTEXT_CACHE_KEY = new Object();
//A key withing the cache
private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke();
/*
* Reads keystroke class from AppContext and if null, puts there the
* AWTKeyStroke class.
* Must be called under locked AWTKeyStro
*/
private static Class getAWTKeyStrokeClass() {
Class clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
if (clazz == null) {
clazz = AWTKeyStroke.class;
AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class);
}
return clazz;
}
private char keyChar = KeyEvent.CHAR_UNDEFINED; private char keyChar = KeyEvent.CHAR_UNDEFINED;
private int keyCode = KeyEvent.VK_UNDEFINED; private int keyCode = KeyEvent.VK_UNDEFINED;
private int modifiers; private int modifiers;
@ -164,10 +181,13 @@ public class AWTKeyStroke implements Serializable {
if (subclass == null) { if (subclass == null) {
throw new IllegalArgumentException("subclass cannot be null"); throw new IllegalArgumentException("subclass cannot be null");
} }
if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) { synchronized (AWTKeyStroke.class) {
Class keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
// Already registered // Already registered
return; return;
} }
}
if (!AWTKeyStroke.class.isAssignableFrom(subclass)) { if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
throw new ClassCastException("subclass is not derived from AWTKeyStroke"); throw new ClassCastException("subclass is not derived from AWTKeyStroke");
} }
@ -197,9 +217,9 @@ public class AWTKeyStroke implements Serializable {
} }
synchronized (AWTKeyStroke.class) { synchronized (AWTKeyStroke.class) {
AWTKeyStroke.ctor = ctor; AppContext.getAppContext().put(AWTKeyStroke.class, subclass);
cache = null; AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY);
cacheKey = null; AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
} }
} }
@ -229,13 +249,19 @@ public class AWTKeyStroke implements Serializable {
private static synchronized AWTKeyStroke getCachedStroke private static synchronized AWTKeyStroke getCachedStroke
(char keyChar, int keyCode, int modifiers, boolean onKeyRelease) (char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
{ {
Map cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY);
AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY);
if (cache == null) { if (cache == null) {
cache = new HashMap(); cache = new HashMap();
AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache);
} }
if (cacheKey == null) { if (cacheKey == null) {
try { try {
cacheKey = (AWTKeyStroke)ctor.newInstance((Object[]) null); Class clazz = getAWTKeyStrokeClass();
cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null);
AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey);
} catch (InstantiationException e) { } catch (InstantiationException e) {
assert(false); assert(false);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
@ -253,9 +279,8 @@ public class AWTKeyStroke implements Serializable {
if (stroke == null) { if (stroke == null) {
stroke = cacheKey; stroke = cacheKey;
cache.put(stroke, stroke); cache.put(stroke, stroke);
cacheKey = null; AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
} }
return stroke; return stroke;
} }

View file

@ -124,7 +124,7 @@ class FileInputStream extends InputStream
throw new NullPointerException(); throw new NullPointerException();
} }
fd = new FileDescriptor(); fd = new FileDescriptor();
fd.incrementAndGetUseCount(); fd.attach(this);
open(name); open(name);
} }
@ -164,10 +164,9 @@ class FileInputStream extends InputStream
/* /*
* FileDescriptor is being shared by streams. * FileDescriptor is being shared by streams.
* Ensure that it's GC'ed only when all the streams/channels are done * Register this stream with FileDescriptor tracker.
* using it.
*/ */
fd.incrementAndGetUseCount(); fd.attach(this);
} }
/** /**
@ -294,27 +293,14 @@ class FileInputStream extends InputStream
closed = true; closed = true;
} }
if (channel != null) { if (channel != null) {
/*
* Decrement the FD use count associated with the channel
* The use count is incremented whenever a new channel
* is obtained from this stream.
*/
fd.decrementAndGetUseCount();
channel.close(); channel.close();
} }
/* fd.closeAll(new Closeable() {
* Decrement the FD use count associated with this stream public void close() throws IOException {
*/
int useCount = fd.decrementAndGetUseCount();
/*
* If FileDescriptor is still in use by another stream, we
* will not close it.
*/
if (useCount <= 0) {
close0(); close0();
} }
});
} }
/** /**
@ -328,7 +314,9 @@ class FileInputStream extends InputStream
* @see java.io.FileDescriptor * @see java.io.FileDescriptor
*/ */
public final FileDescriptor getFD() throws IOException { public final FileDescriptor getFD() throws IOException {
if (fd != null) return fd; if (fd != null) {
return fd;
}
throw new IOException(); throw new IOException();
} }
@ -352,13 +340,6 @@ class FileInputStream extends InputStream
synchronized (this) { synchronized (this) {
if (channel == null) { if (channel == null) {
channel = FileChannelImpl.open(fd, true, false, this); channel = FileChannelImpl.open(fd, true, false, this);
/*
* Increment fd's use count. Invoking the channel's close()
* method will result in decrementing the use count set for
* the channel.
*/
fd.incrementAndGetUseCount();
} }
return channel; return channel;
} }
@ -381,6 +362,11 @@ class FileInputStream extends InputStream
*/ */
protected void finalize() throws IOException { protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) { if ((fd != null) && (fd != FileDescriptor.in)) {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close(); close();
} }
} }

View file

@ -197,9 +197,9 @@ class FileOutputStream extends OutputStream
throw new NullPointerException(); throw new NullPointerException();
} }
this.fd = new FileDescriptor(); this.fd = new FileDescriptor();
fd.attach(this);
this.append = append; this.append = append;
fd.incrementAndGetUseCount();
open(name, append); open(name, append);
} }
@ -237,12 +237,7 @@ class FileOutputStream extends OutputStream
this.fd = fdObj; this.fd = fdObj;
this.append = false; this.append = false;
/* fd.attach(this);
* FileDescriptor is being shared by streams.
* Ensure that it's GC'ed only when all the streams/channels are done
* using it.
*/
fd.incrementAndGetUseCount();
} }
/** /**
@ -331,27 +326,14 @@ class FileOutputStream extends OutputStream
} }
if (channel != null) { if (channel != null) {
/*
* Decrement FD use count associated with the channel
* The use count is incremented whenever a new channel
* is obtained from this stream.
*/
fd.decrementAndGetUseCount();
channel.close(); channel.close();
} }
/* fd.closeAll(new Closeable() {
* Decrement FD use count associated with this stream public void close() throws IOException {
*/
int useCount = fd.decrementAndGetUseCount();
/*
* If FileDescriptor is still in use by another stream, we
* will not close it.
*/
if (useCount <= 0) {
close0(); close0();
} }
});
} }
/** /**
@ -365,7 +347,9 @@ class FileOutputStream extends OutputStream
* @see java.io.FileDescriptor * @see java.io.FileDescriptor
*/ */
public final FileDescriptor getFD() throws IOException { public final FileDescriptor getFD() throws IOException {
if (fd != null) return fd; if (fd != null) {
return fd;
}
throw new IOException(); throw new IOException();
} }
@ -390,13 +374,6 @@ class FileOutputStream extends OutputStream
synchronized (this) { synchronized (this) {
if (channel == null) { if (channel == null) {
channel = FileChannelImpl.open(fd, false, true, append, this); channel = FileChannelImpl.open(fd, false, true, append, this);
/*
* Increment fd's use count. Invoking the channel's close()
* method will result in decrementing the use count set for
* the channel.
*/
fd.incrementAndGetUseCount();
} }
return channel; return channel;
} }
@ -415,6 +392,11 @@ class FileOutputStream extends OutputStream
if (fd == FileDescriptor.out || fd == FileDescriptor.err) { if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush(); flush();
} else { } else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close(); close();
} }
} }

View file

@ -44,10 +44,9 @@ package java.io;
*/ */
public abstract class InputStream implements Closeable { public abstract class InputStream implements Closeable {
// SKIP_BUFFER_SIZE is used to determine the size of skipBuffer // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
private static final int SKIP_BUFFER_SIZE = 2048; // use when skipping.
// skipBuffer is initialized in skip(long), if needed. private static final int MAX_SKIP_BUFFER_SIZE = 2048;
private static byte[] skipBuffer;
/** /**
* Reads the next byte of data from the input stream. The value byte is * Reads the next byte of data from the input stream. The value byte is
@ -212,18 +211,15 @@ public abstract class InputStream implements Closeable {
long remaining = n; long remaining = n;
int nr; int nr;
if (skipBuffer == null)
skipBuffer = new byte[SKIP_BUFFER_SIZE];
byte[] localSkipBuffer = skipBuffer;
if (n <= 0) { if (n <= 0) {
return 0; return 0;
} }
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte[] skipBuffer = new byte[size];
while (remaining > 0) { while (remaining > 0) {
nr = read(localSkipBuffer, 0, nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
(int) Math.min(SKIP_BUFFER_SIZE, remaining));
if (nr < 0) { if (nr < 0) {
break; break;
} }

View file

@ -229,7 +229,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
throw new NullPointerException(); throw new NullPointerException();
} }
fd = new FileDescriptor(); fd = new FileDescriptor();
fd.incrementAndGetUseCount(); fd.attach(this);
open(name, imode); open(name, imode);
} }
@ -242,7 +242,9 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
* @see java.io.FileDescriptor * @see java.io.FileDescriptor
*/ */
public final FileDescriptor getFD() throws IOException { public final FileDescriptor getFD() throws IOException {
if (fd != null) return fd; if (fd != null) {
return fd;
}
throw new IOException(); throw new IOException();
} }
@ -268,17 +270,6 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
synchronized (this) { synchronized (this) {
if (channel == null) { if (channel == null) {
channel = FileChannelImpl.open(fd, true, rw, this); channel = FileChannelImpl.open(fd, true, rw, this);
/*
* FileDescriptor could be shared by FileInputStream or
* FileOutputStream.
* Ensure that FD is GC'ed only when all the streams/channels
* are done using it.
* Increment fd's use count. Invoking the channel's close()
* method will result in decrementing the use count set for
* the channel.
*/
fd.incrementAndGetUseCount();
} }
return channel; return channel;
} }
@ -577,28 +568,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
closed = true; closed = true;
} }
if (channel != null) { if (channel != null) {
/*
* Decrement FD use count associated with the channel. The FD use
* count is incremented whenever a new channel is obtained from
* this stream.
*/
fd.decrementAndGetUseCount();
channel.close(); channel.close();
} }
/* fd.closeAll(new Closeable() {
* Decrement FD use count associated with this stream. public void close() throws IOException {
* The count got incremented by FileDescriptor during its construction.
*/
int useCount = fd.decrementAndGetUseCount();
/*
* If FileDescriptor is still in use by another stream, we
* will not close it.
*/
if (useCount <= 0) {
close0(); close0();
} }
});
} }
// //

View file

@ -57,7 +57,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
/** /**
* Size of writeBuffer, must be >= 1 * Size of writeBuffer, must be >= 1
*/ */
private final int writeBufferSize = 1024; private static final int WRITE_BUFFER_SIZE = 1024;
/** /**
* The object used to synchronize operations on this stream. For * The object used to synchronize operations on this stream. For
@ -107,7 +107,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
public void write(int c) throws IOException { public void write(int c) throws IOException {
synchronized (lock) { synchronized (lock) {
if (writeBuffer == null){ if (writeBuffer == null){
writeBuffer = new char[writeBufferSize]; writeBuffer = new char[WRITE_BUFFER_SIZE];
} }
writeBuffer[0] = (char) c; writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1); write(writeBuffer, 0, 1);
@ -180,9 +180,9 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
public void write(String str, int off, int len) throws IOException { public void write(String str, int off, int len) throws IOException {
synchronized (lock) { synchronized (lock) {
char cbuf[]; char cbuf[];
if (len <= writeBufferSize) { if (len <= WRITE_BUFFER_SIZE) {
if (writeBuffer == null) { if (writeBuffer == null) {
writeBuffer = new char[writeBufferSize]; writeBuffer = new char[WRITE_BUFFER_SIZE];
} }
cbuf = writeBuffer; cbuf = writeBuffer;
} else { // Don't permanently allocate very large buffers. } else { // Don't permanently allocate very large buffers.

View file

@ -71,7 +71,7 @@ public class AssertionError extends Error {
* @see Throwable#getCause() * @see Throwable#getCause()
*/ */
public AssertionError(Object detailMessage) { public AssertionError(Object detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
if (detailMessage instanceof Throwable) if (detailMessage instanceof Throwable)
initCause((Throwable) detailMessage); initCause((Throwable) detailMessage);
} }
@ -85,7 +85,7 @@ public class AssertionError extends Error {
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
*/ */
public AssertionError(boolean detailMessage) { public AssertionError(boolean detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
} }
/** /**
@ -97,7 +97,7 @@ public class AssertionError extends Error {
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
*/ */
public AssertionError(char detailMessage) { public AssertionError(char detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
} }
/** /**
@ -109,7 +109,7 @@ public class AssertionError extends Error {
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
*/ */
public AssertionError(int detailMessage) { public AssertionError(int detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
} }
/** /**
@ -121,7 +121,7 @@ public class AssertionError extends Error {
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
*/ */
public AssertionError(long detailMessage) { public AssertionError(long detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
} }
/** /**
@ -133,7 +133,7 @@ public class AssertionError extends Error {
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
*/ */
public AssertionError(float detailMessage) { public AssertionError(float detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
} }
/** /**
@ -145,7 +145,7 @@ public class AssertionError extends Error {
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
*/ */
public AssertionError(double detailMessage) { public AssertionError(double detailMessage) {
this("" + detailMessage); this(String.valueOf(detailMessage));
} }
/** /**

View file

@ -3008,7 +3008,7 @@ public final
/** /**
* Casts this {@code Class} object to represent a subclass of the class * Casts this {@code Class} object to represent a subclass of the class
* represented by the specified class object. Checks that that the cast * represented by the specified class object. Checks that the cast
* is valid, and throws a {@code ClassCastException} if it is not. If * is valid, and throws a {@code ClassCastException} if it is not. If
* this method succeeds, it always returns a reference to this class object. * this method succeeds, it always returns a reference to this class object.
* *

View file

@ -607,8 +607,7 @@ public final class Double extends Number implements Comparable<Double> {
* @see java.lang.Double#valueOf(java.lang.String) * @see java.lang.Double#valueOf(java.lang.String)
*/ */
public Double(String s) throws NumberFormatException { public Double(String s) throws NumberFormatException {
// REMIND: this is inefficient value = parseDouble(s);
this(valueOf(s).doubleValue());
} }
/** /**

View file

@ -529,8 +529,7 @@ public final class Float extends Number implements Comparable<Float> {
* @see java.lang.Float#valueOf(java.lang.String) * @see java.lang.Float#valueOf(java.lang.String)
*/ */
public Float(String s) throws NumberFormatException { public Float(String s) throws NumberFormatException {
// REMIND: this is inefficient value = parseFloat(s);
this(valueOf(s).floatValue());
} }
/** /**

View file

@ -266,7 +266,7 @@ public class CallSite {
/*package-private*/ /*package-private*/
void setTargetNormal(MethodHandle newTarget) { void setTargetNormal(MethodHandle newTarget) {
target = newTarget; MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
} }
/*package-private*/ /*package-private*/
MethodHandle getTargetVolatile() { MethodHandle getTargetVolatile() {
@ -274,7 +274,7 @@ public class CallSite {
} }
/*package-private*/ /*package-private*/
void setTargetVolatile(MethodHandle newTarget) { void setTargetVolatile(MethodHandle newTarget) {
unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget); MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
} }
// this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite: // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:

View file

@ -934,12 +934,4 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return THROW_EXCEPTION; return THROW_EXCEPTION;
} }
static <T extends Throwable> Empty throwException(T t) throws T { throw t; } static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
// Linkage support:
static void registerBootstrap(Class<?> callerClass, MethodHandle bootstrapMethod) {
MethodHandleNatives.registerBootstrap(callerClass, bootstrapMethod);
}
static MethodHandle getBootstrap(Class<?> callerClass) {
return MethodHandleNatives.getBootstrap(callerClass);
}
} }

View file

@ -61,15 +61,6 @@ class MethodHandleNatives {
/** Initialize a method type, once per form. */ /** Initialize a method type, once per form. */
static native void init(MethodType self); static native void init(MethodType self);
/** Tell the JVM about a class's bootstrap method. */
static native void registerBootstrap(Class<?> caller, MethodHandle bootstrapMethod);
/** Ask the JVM about a class's bootstrap method. */
static native MethodHandle getBootstrap(Class<?> caller);
/** Tell the JVM that we need to change the target of an invokedynamic. */
static native void setCallSiteTarget(CallSite site, MethodHandle target);
/** Fetch the vmtarget field. /** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references. * It will be sanitized as necessary to avoid exposing non-Java references.
* This routine is for debugging and reflection. * This routine is for debugging and reflection.
@ -122,6 +113,12 @@ class MethodHandleNatives {
static final boolean COUNT_GWT; static final boolean COUNT_GWT;
/// CallSite support
/** Tell the JVM that we need to change the target of a CallSite. */
static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
private static native void registerNatives(); private static native void registerNatives();
static { static {
registerNatives(); registerNatives();

View file

@ -27,7 +27,6 @@ package java.lang.ref;
import sun.misc.Cleaner; import sun.misc.Cleaner;
/** /**
* Abstract base class for reference objects. This class defines the * Abstract base class for reference objects. This class defines the
* operations common to all reference objects. Because reference objects are * operations common to all reference objects. Because reference objects are
@ -69,7 +68,7 @@ public abstract class Reference<T> {
* null. * null.
* *
* Pending: queue = ReferenceQueue with which instance is registered; * Pending: queue = ReferenceQueue with which instance is registered;
* next = Following instance in queue, or this if at end of list. * next = this
* *
* Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance * Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
* in queue, or this if at end of list. * in queue, or this if at end of list.
@ -81,17 +80,28 @@ public abstract class Reference<T> {
* the next field is null then the instance is active; if it is non-null, * the next field is null then the instance is active; if it is non-null,
* then the collector should treat the instance normally. * then the collector should treat the instance normally.
* *
* To ensure that concurrent collector can discover active Reference * To ensure that a concurrent collector can discover active Reference
* objects without interfering with application threads that may apply * objects without interfering with application threads that may apply
* the enqueue() method to those objects, collectors should link * the enqueue() method to those objects, collectors should link
* discovered objects through the discovered field. * discovered objects through the discovered field. The discovered
* field is also used for linking Reference objects in the pending list.
*/ */
private T referent; /* Treated specially by GC */ private T referent; /* Treated specially by GC */
ReferenceQueue<? super T> queue; ReferenceQueue<? super T> queue;
/* When active: NULL
* pending: this
* Enqueued: next reference in queue (or this if last)
* Inactive: this
*/
Reference next; Reference next;
/* When active: next element in a discovered reference list maintained by GC (or this if last)
* pending: next element in the pending list (or null if last)
* otherwise: NULL
*/
transient private Reference<T> discovered; /* used by VM */ transient private Reference<T> discovered; /* used by VM */
@ -106,7 +116,8 @@ public abstract class Reference<T> {
/* List of References waiting to be enqueued. The collector adds /* List of References waiting to be enqueued. The collector adds
* References to this list, while the Reference-handler thread removes * References to this list, while the Reference-handler thread removes
* them. This list is protected by the above lock object. * them. This list is protected by the above lock object. The
* list uses the discovered field to link its elements.
*/ */
private static Reference pending = null; private static Reference pending = null;
@ -120,14 +131,12 @@ public abstract class Reference<T> {
public void run() { public void run() {
for (;;) { for (;;) {
Reference r; Reference r;
synchronized (lock) { synchronized (lock) {
if (pending != null) { if (pending != null) {
r = pending; r = pending;
Reference rn = r.next; pending = r.discovered;
pending = (rn == r) ? null : rn; r.discovered = null;
r.next = r;
} else { } else {
try { try {
lock.wait(); lock.wait();
@ -201,10 +210,8 @@ public abstract class Reference<T> {
* been enqueued * been enqueued
*/ */
public boolean isEnqueued() { public boolean isEnqueued() {
/* In terms of the internal states, this predicate actually tests
whether the instance is either Pending or Enqueued */
synchronized (this) { synchronized (this) {
return (this.queue != ReferenceQueue.NULL) && (this.next != null); return (this.next != null && this.queue == ReferenceQueue.ENQUEUED);
} }
} }

View file

@ -876,10 +876,12 @@ class InetAddress implements java.io.Serializable {
nameService = java.security.AccessController.doPrivileged( nameService = java.security.AccessController.doPrivileged(
new java.security.PrivilegedExceptionAction<NameService>() { new java.security.PrivilegedExceptionAction<NameService>() {
public NameService run() { public NameService run() {
Iterator itr = Service.providers(NameServiceDescriptor.class); // sun.misc.Service.providers returns a raw Iterator
@SuppressWarnings("unchecked")
Iterator<NameServiceDescriptor> itr =
Service.providers(NameServiceDescriptor.class);
while (itr.hasNext()) { while (itr.hasNext()) {
NameServiceDescriptor nsd NameServiceDescriptor nsd = itr.next();
= (NameServiceDescriptor)itr.next();
if (providerName. if (providerName.
equalsIgnoreCase(nsd.getType()+"," equalsIgnoreCase(nsd.getType()+","
+nsd.getProviderName())) { +nsd.getProviderName())) {

View file

@ -267,10 +267,9 @@ class ServerSocket implements java.io.Closeable {
AccessController.doPrivileged( AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() { new PrivilegedExceptionAction<Void>() {
public Void run() throws NoSuchMethodException { public Void run() throws NoSuchMethodException {
Class[] cl = new Class[2]; impl.getClass().getDeclaredMethod("connect",
cl[0] = SocketAddress.class; SocketAddress.class,
cl[1] = Integer.TYPE; int.class);
impl.getClass().getDeclaredMethod("connect", cl);
return null; return null;
} }
}); });

View file

@ -435,7 +435,7 @@ public abstract class Charset
AccessController.doPrivileged(new PrivilegedAction<Object>() { AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() { public Object run() {
try { try {
Class epc Class<?> epc
= Class.forName("sun.nio.cs.ext.ExtendedCharsets"); = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
extendedProvider = (CharsetProvider)epc.newInstance(); extendedProvider = (CharsetProvider)epc.newInstance();
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {

View file

@ -363,6 +363,17 @@ public final class Files {
// -- Directories -- // -- Directories --
private static class AcceptAllFilter
implements DirectoryStream.Filter<Path>
{
private AcceptAllFilter() { }
@Override
public boolean accept(Path entry) { return true; }
static final AcceptAllFilter FILTER = new AcceptAllFilter();
}
/** /**
* Opens a directory, returning a {@link DirectoryStream} to iterate over * Opens a directory, returning a {@link DirectoryStream} to iterate over
* all entries in the directory. The elements returned by the directory * all entries in the directory. The elements returned by the directory
@ -397,12 +408,7 @@ public final class Files {
public static DirectoryStream<Path> newDirectoryStream(Path dir) public static DirectoryStream<Path> newDirectoryStream(Path dir)
throws IOException throws IOException
{ {
return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() { return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER);
@Override
public boolean accept(Path entry) {
return true;
}
});
} }
/** /**

View file

@ -28,6 +28,7 @@ package java.security;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicReference;
import sun.security.jca.GetInstance; import sun.security.jca.GetInstance;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
@ -60,8 +61,8 @@ import sun.security.util.SecurityConstants;
* with a standard type. The default policy type is "JavaPolicy". * with a standard type. The default policy type is "JavaPolicy".
* *
* <p> Once a Policy instance has been installed (either by default, or by * <p> Once a Policy instance has been installed (either by default, or by
* calling <code>setPolicy</code>), * calling <code>setPolicy</code>), the Java runtime invokes its
* the Java runtime invokes its <code>implies</code> when it needs to * <code>implies</code> method when it needs to
* determine whether executing code (encapsulated in a ProtectionDomain) * determine whether executing code (encapsulated in a ProtectionDomain)
* can perform SecurityManager-protected operations. How a Policy object * can perform SecurityManager-protected operations. How a Policy object
* retrieves its policy data is up to the Policy implementation itself. * retrieves its policy data is up to the Policy implementation itself.
@ -94,18 +95,33 @@ public abstract class Policy {
public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION =
new UnsupportedEmptyCollection(); new UnsupportedEmptyCollection();
/** the system-wide policy. */ // Information about the system-wide policy.
private static Policy policy; // package private for AccessControlContext private static class PolicyInfo {
// the system-wide policy
final Policy policy;
// a flag indicating if the system-wide policy has been initialized
final boolean initialized;
PolicyInfo(Policy policy, boolean initialized) {
this.policy = policy;
this.initialized = initialized;
}
}
// PolicyInfo is stored in an AtomicReference
private static AtomicReference<PolicyInfo> policy =
new AtomicReference<>(new PolicyInfo(null, false));
private static final Debug debug = Debug.getInstance("policy"); private static final Debug debug = Debug.getInstance("policy");
// Cache mapping ProtectionDomain.Key to PermissionCollection // Cache mapping ProtectionDomain.Key to PermissionCollection
private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping; private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping;
/** package private for AccessControlContext */ /** package private for AccessControlContext and ProtectionDomain */
static boolean isSet() static boolean isSet()
{ {
return policy != null; PolicyInfo pi = policy.get();
return pi.policy != null && pi.initialized == true;
} }
private static void checkPermission(String type) { private static void checkPermission(String type) {
@ -143,16 +159,20 @@ public abstract class Policy {
/** /**
* Returns the installed Policy object, skipping the security check. * Returns the installed Policy object, skipping the security check.
* Used by SecureClassLoader and getPolicy. * Used by ProtectionDomain and getPolicy.
* *
* @return the installed Policy. * @return the installed Policy.
*
*/ */
static synchronized Policy getPolicyNoCheck() static Policy getPolicyNoCheck()
{ {
if (policy == null) { PolicyInfo pi = policy.get();
String policy_class = null; // Use double-check idiom to avoid locking if system-wide policy is
policy_class = AccessController.doPrivileged( // already initialized
if (pi.initialized == false || pi.policy == null) {
synchronized (Policy.class) {
PolicyInfo pinfo = policy.get();
if (pinfo.policy == null) {
String policy_class = AccessController.doPrivileged(
new PrivilegedAction<String>() { new PrivilegedAction<String>() {
public String run() { public String run() {
return Security.getProperty("policy.provider"); return Security.getProperty("policy.provider");
@ -163,22 +183,25 @@ public abstract class Policy {
} }
try { try {
policy = (Policy) pinfo = new PolicyInfo(
Class.forName(policy_class).newInstance(); (Policy) Class.forName(policy_class).newInstance(),
true);
} catch (Exception e) { } catch (Exception e) {
/* /*
* The policy_class seems to be an extension * The policy_class seems to be an extension
* so we have to bootstrap loading it via a policy * so we have to bootstrap loading it via a policy
* provider that is on the bootclasspath * provider that is on the bootclasspath.
* If it loads then shift gears to using the configured * If it loads then shift gears to using the configured
* provider. * provider.
*/ */
// install the bootstrap provider to avoid recursion // install the bootstrap provider to avoid recursion
policy = new sun.security.provider.PolicyFile(); Policy polFile = new sun.security.provider.PolicyFile();
pinfo = new PolicyInfo(polFile, false);
policy.set(pinfo);
final String pc = policy_class; final String pc = policy_class;
Policy p = AccessController.doPrivileged( Policy pol = AccessController.doPrivileged(
new PrivilegedAction<Policy>() { new PrivilegedAction<Policy>() {
public Policy run() { public Policy run() {
try { try {
@ -207,16 +230,21 @@ public abstract class Policy {
* if it loaded install it as the policy provider. Otherwise * if it loaded install it as the policy provider. Otherwise
* continue to use the system default implementation * continue to use the system default implementation
*/ */
if (p != null) { if (pol != null) {
policy = p; pinfo = new PolicyInfo(pol, true);
} else { } else {
if (debug != null) { if (debug != null) {
debug.println("using sun.security.provider.PolicyFile"); debug.println("using sun.security.provider.PolicyFile");
} }
pinfo = new PolicyInfo(polFile, true);
} }
} }
policy.set(pinfo);
} }
return policy; return pinfo.policy;
}
}
return pi.policy;
} }
/** /**
@ -245,7 +273,7 @@ public abstract class Policy {
initPolicy(p); initPolicy(p);
} }
synchronized (Policy.class) { synchronized (Policy.class) {
Policy.policy = p; policy.set(new PolicyInfo(p, p != null));
} }
} }
@ -292,14 +320,14 @@ public abstract class Policy {
PermissionCollection policyPerms = null; PermissionCollection policyPerms = null;
synchronized (p) { synchronized (p) {
if (p.pdMapping == null) { if (p.pdMapping == null) {
p.pdMapping = p.pdMapping = new WeakHashMap<>();
new WeakHashMap<ProtectionDomain.Key, PermissionCollection>();
} }
} }
if (policyDomain.getCodeSource() != null) { if (policyDomain.getCodeSource() != null) {
if (Policy.isSet()) { Policy pol = policy.get().policy;
policyPerms = policy.getPermissions(policyDomain); if (pol != null) {
policyPerms = pol.getPermissions(policyDomain);
} }
if (policyPerms == null) { // assume it has all if (policyPerms == null) { // assume it has all
@ -434,7 +462,7 @@ public abstract class Policy {
type, type,
params); params);
} catch (NoSuchAlgorithmException nsae) { } catch (NoSuchAlgorithmException nsae) {
return handleException (nsae); return handleException(nsae);
} }
} }
@ -494,7 +522,7 @@ public abstract class Policy {
type, type,
params); params);
} catch (NoSuchAlgorithmException nsae) { } catch (NoSuchAlgorithmException nsae) {
return handleException (nsae); return handleException(nsae);
} }
} }

View file

@ -814,7 +814,7 @@ public final class Security {
public Void run() { public Void run() {
try { try {
/* Get the class via the bootstrap class loader. */ /* Get the class via the bootstrap class loader. */
Class cl = Class.forName( Class<?> cl = Class.forName(
"java.lang.SecurityManager", false, null); "java.lang.SecurityManager", false, null);
Field f = null; Field f = null;
boolean accessible = false; boolean accessible = false;

View file

@ -767,7 +767,7 @@ public interface PreparedStatement extends Statement {
/** /**
* Sets the designated paramter to the given <code>String</code> object. * Sets the designated parameter to the given <code>String</code> object.
* The driver converts this to a SQL <code>NCHAR</code> or * The driver converts this to a SQL <code>NCHAR</code> or
* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
* (depending on the argument's * (depending on the argument's

View file

@ -991,7 +991,7 @@ public interface Statement extends Wrapper, AutoCloseable {
/** /**
* Requests that a <code>Statement</code> be pooled or not pooled. The value * Requests that a <code>Statement</code> be pooled or not pooled. The value
* specified is a hint to the statement pool implementation indicating * specified is a hint to the statement pool implementation indicating
* whether the applicaiton wants the statement to be pooled. It is up to * whether the application wants the statement to be pooled. It is up to
* the statement pool manager as to whether the hint is used. * the statement pool manager as to whether the hint is used.
* <p> * <p>
* The poolable value of a statement is applicable to both internal * The poolable value of a statement is applicable to both internal

View file

@ -443,7 +443,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#word">word breaks</a> * for <a href="BreakIterator.html#word">word breaks</a>
* for the {@linkplain Locale#getDefault() default locale}. * for the {@linkplain Locale#getDefault() default locale}.
* @return A break iterator for word breaks * @return A break iterator for word breaks
*/ */
@ -454,7 +454,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#word">word breaks</a> * for <a href="BreakIterator.html#word">word breaks</a>
* for the given locale. * for the given locale.
* @param locale the desired locale * @param locale the desired locale
* @return A break iterator for word breaks * @return A break iterator for word breaks
@ -470,7 +470,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#line">line breaks</a> * for <a href="BreakIterator.html#line">line breaks</a>
* for the {@linkplain Locale#getDefault() default locale}. * for the {@linkplain Locale#getDefault() default locale}.
* @return A break iterator for line breaks * @return A break iterator for line breaks
*/ */
@ -481,7 +481,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#line">line breaks</a> * for <a href="BreakIterator.html#line">line breaks</a>
* for the given locale. * for the given locale.
* @param locale the desired locale * @param locale the desired locale
* @return A break iterator for line breaks * @return A break iterator for line breaks
@ -497,7 +497,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#character">character breaks</a> * for <a href="BreakIterator.html#character">character breaks</a>
* for the {@linkplain Locale#getDefault() default locale}. * for the {@linkplain Locale#getDefault() default locale}.
* @return A break iterator for character breaks * @return A break iterator for character breaks
*/ */
@ -508,7 +508,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#character">character breaks</a> * for <a href="BreakIterator.html#character">character breaks</a>
* for the given locale. * for the given locale.
* @param locale the desired locale * @param locale the desired locale
* @return A break iterator for character breaks * @return A break iterator for character breaks
@ -524,7 +524,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#sentence">sentence breaks</a> * for <a href="BreakIterator.html#sentence">sentence breaks</a>
* for the {@linkplain Locale#getDefault() default locale}. * for the {@linkplain Locale#getDefault() default locale}.
* @return A break iterator for sentence breaks * @return A break iterator for sentence breaks
*/ */
@ -535,7 +535,7 @@ public abstract class BreakIterator implements Cloneable
/** /**
* Returns a new <code>BreakIterator</code> instance * Returns a new <code>BreakIterator</code> instance
* for <a href="#sentence">sentence breaks</a> * for <a href="BreakIterator.html#sentence">sentence breaks</a>
* for the given locale. * for the given locale.
* @param locale the desired locale * @param locale the desired locale
* @return A break iterator for sentence breaks * @return A break iterator for sentence breaks

View file

@ -3201,6 +3201,102 @@ public class Collections {
} }
} }
/**
* Returns the empty sorted set (immutable). This set is serializable.
*
* <p>This example illustrates the type-safe way to obtain an empty sorted
* set:
* <pre>
* SortedSet&lt;String&gt; s = Collections.emptySortedSet();
* </pre>
* Implementation note: Implementations of this method need not
* create a separate <tt>SortedSet</tt> object for each call.
*
* @since 1.8
*/
@SuppressWarnings("unchecked")
public static final <E> SortedSet<E> emptySortedSet() {
return (SortedSet<E>) new EmptySortedSet<>();
}
/**
* @serial include
*/
private static class EmptySortedSet<E>
extends AbstractSet<E>
implements SortedSet<E>, Serializable
{
private static final long serialVersionUID = 6316515401502265487L;
public Iterator<E> iterator() { return emptyIterator(); }
public int size() {return 0;}
public boolean isEmpty() {return true;}
public boolean contains(Object obj) {return false;}
public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
public Object[] toArray() { return new Object[0]; }
public <E> E[] toArray(E[] a) {
if (a.length > 0)
a[0] = null;
return a;
}
// Preserves singleton property
private Object readResolve() {
return new EmptySortedSet<>();
}
public Comparator comparator() {
return null;
}
public SortedSet<E> subSet(Object fromElement, Object toElement) {
Objects.requireNonNull(fromElement);
Objects.requireNonNull(toElement);
if (!(fromElement instanceof Comparable) ||
!(toElement instanceof Comparable))
{
throw new ClassCastException();
}
if ((((Comparable)fromElement).compareTo(toElement) >= 0) ||
(((Comparable)toElement).compareTo(fromElement) < 0))
{
throw new IllegalArgumentException();
}
return emptySortedSet();
}
public SortedSet<E> headSet(Object toElement) {
Objects.requireNonNull(toElement);
if (!(toElement instanceof Comparable)) {
throw new ClassCastException();
}
return emptySortedSet();
}
public SortedSet<E> tailSet(Object fromElement) {
Objects.requireNonNull(fromElement);
if (!(fromElement instanceof Comparable)) {
throw new ClassCastException();
}
return emptySortedSet();
}
public E first() {
throw new NoSuchElementException();
}
public E last() {
throw new NoSuchElementException();
}
}
/** /**
* The empty list (immutable). This list is serializable. * The empty list (immutable). This list is serializable.
* *

View file

@ -742,6 +742,8 @@ public class LinkedBlockingDeque<E>
throw new NullPointerException(); throw new NullPointerException();
if (c == this) if (c == this)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {

View file

@ -332,7 +332,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
// Note: convention in all put/take/etc is to preset local var // Note: convention in all put/take/etc is to preset local var
// holding count negative to indicate failure unless set. // holding count negative to indicate failure unless set.
int c = -1; int c = -1;
Node<E> node = new Node(e); Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock; final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count; final AtomicInteger count = this.count;
putLock.lockInterruptibly(); putLock.lockInterruptibly();
@ -412,7 +412,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
if (count.get() == capacity) if (count.get() == capacity)
return false; return false;
int c = -1; int c = -1;
Node<E> node = new Node(e); Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock; final ReentrantLock putLock = this.putLock;
putLock.lock(); putLock.lock();
try { try {
@ -728,6 +728,8 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
throw new NullPointerException(); throw new NullPointerException();
if (c == this) if (c == this)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
boolean signalNotFull = false; boolean signalNotFull = false;
final ReentrantLock takeLock = this.takeLock; final ReentrantLock takeLock = this.takeLock;
takeLock.lock(); takeLock.lock();

View file

@ -629,7 +629,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id"); public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id");
/** /**
* <code>Name</code> object for <code>Implementation-Vendor-URL</code> * <code>Name</code> object for <code>Implementation-URL</code>
* manifest attribute used for package versioning. * manifest attribute used for package versioning.
* @see <a href="../../../../technotes/guides/versioning/spec/versioning2.html#wp90779"> * @see <a href="../../../../technotes/guides/versioning/spec/versioning2.html#wp90779">
* Java Product Versioning Specification</a> * Java Product Versioning Specification</a>

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -347,6 +347,9 @@ class HttpsURLConnection extends HttpURLConnection
* @param sf the SSL socket factory * @param sf the SSL socket factory
* @throws IllegalArgumentException if the <code>SSLSocketFactory</code> * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
* parameter is null. * parameter is null.
* @throws SecurityException if a security manager exists and its
* <code>checkSetFactory</code> method does not allow
* a socket factory to be specified.
* @see #getSSLSocketFactory() * @see #getSSLSocketFactory()
*/ */
public void setSSLSocketFactory(SSLSocketFactory sf) { public void setSSLSocketFactory(SSLSocketFactory sf) {
@ -355,6 +358,10 @@ class HttpsURLConnection extends HttpURLConnection
"no SSLSocketFactory specified"); "no SSLSocketFactory specified");
} }
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkSetFactory();
}
sslSocketFactory = sf; sslSocketFactory = sf;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -538,7 +538,7 @@ public abstract class SSLEngine {
* If this <code>SSLEngine</code> has not yet started its initial * If this <code>SSLEngine</code> has not yet started its initial
* handshake, this method will automatically start the handshake. * handshake, this method will automatically start the handshake.
* <P> * <P>
* This method will attempt to produce one SSL/TLS packet, and will * This method will attempt to produce SSL/TLS records, and will
* consume as much source data as possible, but will never consume * consume as much source data as possible, but will never consume
* more than the sum of the bytes remaining in each buffer. Each * more than the sum of the bytes remaining in each buffer. Each
* <code>ByteBuffer</code>'s position is updated to reflect the * <code>ByteBuffer</code>'s position is updated to reflect the

View file

@ -1828,6 +1828,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* table. While the {@code autoCreateRowSorter} property remains * table. While the {@code autoCreateRowSorter} property remains
* {@code true}, every time the model is changed, a new {@code * {@code true}, every time the model is changed, a new {@code
* TableRowSorter} is created and set as the table's row sorter. * TableRowSorter} is created and set as the table's row sorter.
* The default value for the {@code autoCreateRowSorter}
* property is {@code false}.
* *
* @param autoCreateRowSorter whether or not a {@code RowSorter} * @param autoCreateRowSorter whether or not a {@code RowSorter}
* should be automatically created * should be automatically created

View file

@ -1838,7 +1838,9 @@ public class JTree extends JComponent implements Scrollable, Accessible
* nodes, or <code>null</code> if nothing is currently selected * nodes, or <code>null</code> if nothing is currently selected
*/ */
public TreePath[] getSelectionPaths() { public TreePath[] getSelectionPaths() {
return getSelectionModel().getSelectionPaths(); TreePath[] selectionPaths = getSelectionModel().getSelectionPaths();
return (selectionPaths != null && selectionPaths.length > 0) ? selectionPaths : null;
} }
/** /**

View file

@ -1326,7 +1326,7 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou
if ( ! SwingUtilities2.canCurrentEventAccessSystemClipboard() ) { if ( ! SwingUtilities2.canCurrentEventAccessSystemClipboard() ) {
return; return;
} }
if (this.dot != this.mark && component != null) { if (this.dot != this.mark && component != null && component.hasFocus()) {
Clipboard clip = getSystemSelection(); Clipboard clip = getSystemSelection();
if (clip != null) { if (clip != null) {
String selectedText; String selectedText;

View file

@ -1181,7 +1181,12 @@ public class HTMLDocument extends DefaultStyledDocument {
public void insertAfterStart(Element elem, String htmlText) throws public void insertAfterStart(Element elem, String htmlText) throws
BadLocationException, IOException { BadLocationException, IOException {
verifyParser(); verifyParser();
if (elem != null && elem.isLeaf()) {
if (elem == null || htmlText == null) {
return;
}
if (elem.isLeaf()) {
throw new IllegalArgumentException throw new IllegalArgumentException
("Can not insert HTML after start of a leaf"); ("Can not insert HTML after start of a leaf");
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -185,7 +185,7 @@ public class OffScreenImageSource implements ImageProducer {
theConsumer.setDimensions(image.getWidth(), image.getHeight()); theConsumer.setDimensions(image.getWidth(), image.getHeight());
theConsumer.setProperties(properties); theConsumer.setProperties(properties);
sendPixels(); sendPixels();
theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE); theConsumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
} catch (NullPointerException e) { } catch (NullPointerException e) {
if (theConsumer != null) { if (theConsumer != null) {
theConsumer.imageComplete(ImageConsumer.IMAGEERROR); theConsumer.imageComplete(ImageConsumer.IMAGEERROR);

View file

@ -41,13 +41,14 @@ public class ResourceManager {
/* default maximum number of udp sockets per VM /* default maximum number of udp sockets per VM
* when a security manager is enabled. * when a security manager is enabled.
* The default is 1024 which is high enough to be useful * The default is 25 which is high enough to be useful
* but low enough to be well below the maximum number * but low enough to be well below the maximum number
* of port numbers actually available on all OSes for * of port numbers actually available on all OSes
* such sockets (5000 on some versions of windows) * when multiplied by the maximum feasible number of VM processes
* that could practically be spawned.
*/ */
private static final int DEFAULT_MAX_SOCKETS = 1024; private static final int DEFAULT_MAX_SOCKETS = 25;
private static final int maxSockets; private static final int maxSockets;
private static final AtomicInteger numSockets; private static final AtomicInteger numSockets;

View file

@ -402,10 +402,10 @@ class ServerImpl implements TimeSource {
} catch (IOException e) { } catch (IOException e) {
logger.log (Level.FINER, "Dispatcher (4)", e); logger.log (Level.FINER, "Dispatcher (4)", e);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
logger.log (Level.FINER, "Dispatcher (7)", e); logger.log (Level.FINER, "Dispatcher (7)", e);
} }
} }
try {selector.close(); } catch (Exception e) {}
} }
private void handleException (SelectionKey key, Exception e) { private void handleException (SelectionKey key, Exception e) {

View file

@ -363,7 +363,7 @@ class Util {
try { try {
Class<?> cl = Class.forName("java.nio.DirectByteBuffer"); Class<?> cl = Class.forName("java.nio.DirectByteBuffer");
Constructor<?> ctor = cl.getDeclaredConstructor( Constructor<?> ctor = cl.getDeclaredConstructor(
new Class[] { int.class, new Class<?>[] { int.class,
long.class, long.class,
FileDescriptor.class, FileDescriptor.class,
Runnable.class }); Runnable.class });
@ -408,7 +408,7 @@ class Util {
try { try {
Class<?> cl = Class.forName("java.nio.DirectByteBufferR"); Class<?> cl = Class.forName("java.nio.DirectByteBufferR");
Constructor<?> ctor = cl.getDeclaredConstructor( Constructor<?> ctor = cl.getDeclaredConstructor(
new Class[] { int.class, new Class<?>[] { int.class,
long.class, long.class,
FileDescriptor.class, FileDescriptor.class,
Runnable.class }); Runnable.class });

View file

@ -0,0 +1,604 @@
/*
* 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.nio.cs;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
/* Legal CESU-8 Byte Sequences
*
* # Code Points Bits Bit/Byte pattern
* 1 7 0xxxxxxx
* U+0000..U+007F 00..7F
*
* 2 11 110xxxxx 10xxxxxx
* U+0080..U+07FF C2..DF 80..BF
*
* 3 16 1110xxxx 10xxxxxx 10xxxxxx
* U+0800..U+0FFF E0 A0..BF 80..BF
* U+1000..U+FFFF E1..EF 80..BF 80..BF
*
*/
class CESU_8 extends Unicode
{
public CESU_8() {
super("CESU-8", StandardCharsets.aliases_CESU_8);
}
public String historicalName() {
return "CESU8";
}
public CharsetDecoder newDecoder() {
return new Decoder(this);
}
public CharsetEncoder newEncoder() {
return new Encoder(this);
}
private static final void updatePositions(Buffer src, int sp,
Buffer dst, int dp) {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
private static class Decoder extends CharsetDecoder
implements ArrayDecoder {
private Decoder(Charset cs) {
super(cs, 1.0f, 1.0f);
}
private static boolean isNotContinuation(int b) {
return (b & 0xc0) != 0x80;
}
// [E0] [A0..BF] [80..BF]
// [E1..EF] [80..BF] [80..BF]
private static boolean isMalformed3(int b1, int b2, int b3) {
return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
(b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
}
// only used when there is only one byte left in src buffer
private static boolean isMalformed3_2(int b1, int b2) {
return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
(b2 & 0xc0) != 0x80;
}
// [F0] [90..BF] [80..BF] [80..BF]
// [F1..F3] [80..BF] [80..BF] [80..BF]
// [F4] [80..8F] [80..BF] [80..BF]
// only check 80-be range here, the [0xf0,0x80...] and [0xf4,0x90-...]
// will be checked by Character.isSupplementaryCodePoint(uc)
private static boolean isMalformed4(int b2, int b3, int b4) {
return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
(b4 & 0xc0) != 0x80;
}
// only used when there is less than 4 bytes left in src buffer
private static boolean isMalformed4_2(int b1, int b2) {
return (b1 == 0xf0 && b2 == 0x90) ||
(b2 & 0xc0) != 0x80;
}
private static boolean isMalformed4_3(int b3) {
return (b3 & 0xc0) != 0x80;
}
private static CoderResult malformedN(ByteBuffer src, int nb) {
switch (nb) {
case 1:
case 2: // always 1
return CoderResult.malformedForLength(1);
case 3:
int b1 = src.get();
int b2 = src.get(); // no need to lookup b3
return CoderResult.malformedForLength(
((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
isNotContinuation(b2)) ? 1 : 2);
case 4: // we don't care the speed here
b1 = src.get() & 0xff;
b2 = src.get() & 0xff;
if (b1 > 0xf4 ||
(b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
(b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
isNotContinuation(b2))
return CoderResult.malformedForLength(1);
if (isNotContinuation(src.get()))
return CoderResult.malformedForLength(2);
return CoderResult.malformedForLength(3);
default:
assert false;
return null;
}
}
private static CoderResult malformed(ByteBuffer src, int sp,
CharBuffer dst, int dp,
int nb)
{
src.position(sp - src.arrayOffset());
CoderResult cr = malformedN(src, nb);
updatePositions(src, sp, dst, dp);
return cr;
}
private static CoderResult malformed(ByteBuffer src,
int mark, int nb)
{
src.position(mark);
CoderResult cr = malformedN(src, nb);
src.position(mark);
return cr;
}
private static CoderResult malformedForLength(ByteBuffer src,
int sp,
CharBuffer dst,
int dp,
int malformedNB)
{
updatePositions(src, sp, dst, dp);
return CoderResult.malformedForLength(malformedNB);
}
private static CoderResult malformedForLength(ByteBuffer src,
int mark,
int malformedNB)
{
src.position(mark);
return CoderResult.malformedForLength(malformedNB);
}
private static CoderResult xflow(Buffer src, int sp, int sl,
Buffer dst, int dp, int nb) {
updatePositions(src, sp, dst, dp);
return (nb == 0 || sl - sp < nb)
? CoderResult.UNDERFLOW : CoderResult.OVERFLOW;
}
private static CoderResult xflow(Buffer src, int mark, int nb) {
src.position(mark);
return (nb == 0 || src.remaining() < nb)
? CoderResult.UNDERFLOW : CoderResult.OVERFLOW;
}
private CoderResult decodeArrayLoop(ByteBuffer src,
CharBuffer dst)
{
// This method is optimized for ASCII input.
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
int dlASCII = dp + Math.min(sl - sp, dl - dp);
// ASCII only loop
while (dp < dlASCII && sa[sp] >= 0)
da[dp++] = (char) sa[sp++];
while (sp < sl) {
int b1 = sa[sp];
if (b1 >= 0) {
// 1 byte, 7 bits: 0xxxxxxx
if (dp >= dl)
return xflow(src, sp, sl, dst, dp, 1);
da[dp++] = (char) b1;
sp++;
} else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx
if (sl - sp < 2 || dp >= dl)
return xflow(src, sp, sl, dst, dp, 2);
int b2 = sa[sp + 1];
if (isNotContinuation(b2))
return malformedForLength(src, sp, dst, dp, 1);
da[dp++] = (char) (((b1 << 6) ^ b2)
^
(((byte) 0xC0 << 6) ^
((byte) 0x80 << 0)));
sp += 2;
} else if ((b1 >> 4) == -2) {
// 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
int srcRemaining = sl - sp;
if (srcRemaining < 3 || dp >= dl) {
if (srcRemaining > 1 && isMalformed3_2(b1, sa[sp + 1]))
return malformedForLength(src, sp, dst, dp, 1);
return xflow(src, sp, sl, dst, dp, 3);
}
int b2 = sa[sp + 1];
int b3 = sa[sp + 2];
if (isMalformed3(b1, b2, b3))
return malformed(src, sp, dst, dp, 3);
da[dp++] = (char)
((b1 << 12) ^
(b2 << 6) ^
(b3 ^
(((byte) 0xE0 << 12) ^
((byte) 0x80 << 6) ^
((byte) 0x80 << 0))));
sp += 3;
} else {
return malformed(src, sp, dst, dp, 1);
}
}
return xflow(src, sp, sl, dst, dp, 0);
}
private CoderResult decodeBufferLoop(ByteBuffer src,
CharBuffer dst)
{
int mark = src.position();
int limit = src.limit();
while (mark < limit) {
int b1 = src.get();
if (b1 >= 0) {
// 1 byte, 7 bits: 0xxxxxxx
if (dst.remaining() < 1)
return xflow(src, mark, 1); // overflow
dst.put((char) b1);
mark++;
} else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx
if (limit - mark < 2|| dst.remaining() < 1)
return xflow(src, mark, 2);
int b2 = src.get();
if (isNotContinuation(b2))
return malformedForLength(src, mark, 1);
dst.put((char) (((b1 << 6) ^ b2)
^
(((byte) 0xC0 << 6) ^
((byte) 0x80 << 0))));
mark += 2;
} else if ((b1 >> 4) == -2) {
// 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
int srcRemaining = limit - mark;
if (srcRemaining < 3 || dst.remaining() < 1) {
if (srcRemaining > 1 && isMalformed3_2(b1, src.get()))
return malformedForLength(src, mark, 1);
return xflow(src, mark, 3);
}
int b2 = src.get();
int b3 = src.get();
if (isMalformed3(b1, b2, b3))
return malformed(src, mark, 3);
dst.put((char)
((b1 << 12) ^
(b2 << 6) ^
(b3 ^
(((byte) 0xE0 << 12) ^
((byte) 0x80 << 6) ^
((byte) 0x80 << 0)))));
mark += 3;
} else {
return malformed(src, mark, 1);
}
}
return xflow(src, mark, 0);
}
protected CoderResult decodeLoop(ByteBuffer src,
CharBuffer dst)
{
if (src.hasArray() && dst.hasArray())
return decodeArrayLoop(src, dst);
else
return decodeBufferLoop(src, dst);
}
private static ByteBuffer getByteBuffer(ByteBuffer bb, byte[] ba, int sp)
{
if (bb == null)
bb = ByteBuffer.wrap(ba);
bb.position(sp);
return bb;
}
// returns -1 if there is/are malformed byte(s) and the
// "action" for malformed input is not REPLACE.
public int decode(byte[] sa, int sp, int len, char[] da) {
final int sl = sp + len;
int dp = 0;
int dlASCII = Math.min(len, da.length);
ByteBuffer bb = null; // only necessary if malformed
// ASCII only optimized loop
while (dp < dlASCII && sa[sp] >= 0)
da[dp++] = (char) sa[sp++];
while (sp < sl) {
int b1 = sa[sp++];
if (b1 >= 0) {
// 1 byte, 7 bits: 0xxxxxxx
da[dp++] = (char) b1;
} else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx
if (sp < sl) {
int b2 = sa[sp++];
if (isNotContinuation(b2)) {
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
da[dp++] = replacement().charAt(0);
sp--; // malformedN(bb, 2) always returns 1
} else {
da[dp++] = (char) (((b1 << 6) ^ b2)^
(((byte) 0xC0 << 6) ^
((byte) 0x80 << 0)));
}
continue;
}
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
da[dp++] = replacement().charAt(0);
return dp;
} else if ((b1 >> 4) == -2) {
// 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
if (sp + 1 < sl) {
int b2 = sa[sp++];
int b3 = sa[sp++];
if (isMalformed3(b1, b2, b3)) {
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
da[dp++] = replacement().charAt(0);
sp -=3;
bb = getByteBuffer(bb, sa, sp);
sp += malformedN(bb, 3).length();
} else {
da[dp++] = (char)((b1 << 12) ^
(b2 << 6) ^
(b3 ^
(((byte) 0xE0 << 12) ^
((byte) 0x80 << 6) ^
((byte) 0x80 << 0))));
}
continue;
}
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
if (sp < sl && isMalformed3_2(b1, sa[sp])) {
da[dp++] = replacement().charAt(0);
continue;
}
da[dp++] = replacement().charAt(0);
return dp;
} else {
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
da[dp++] = replacement().charAt(0);
}
}
return dp;
}
}
private static class Encoder extends CharsetEncoder
implements ArrayEncoder {
private Encoder(Charset cs) {
super(cs, 1.1f, 3.0f);
}
public boolean canEncode(char c) {
return !Character.isSurrogate(c);
}
public boolean isLegalReplacement(byte[] repl) {
return ((repl.length == 1 && repl[0] >= 0) ||
super.isLegalReplacement(repl));
}
private static CoderResult overflow(CharBuffer src, int sp,
ByteBuffer dst, int dp) {
updatePositions(src, sp, dst, dp);
return CoderResult.OVERFLOW;
}
private static CoderResult overflow(CharBuffer src, int mark) {
src.position(mark);
return CoderResult.OVERFLOW;
}
private static void to3Bytes(byte[] da, int dp, char c) {
da[dp] = (byte)(0xe0 | ((c >> 12)));
da[dp + 1] = (byte)(0x80 | ((c >> 6) & 0x3f));
da[dp + 2] = (byte)(0x80 | (c & 0x3f));
}
private static void to3Bytes(ByteBuffer dst, char c) {
dst.put((byte)(0xe0 | ((c >> 12))));
dst.put((byte)(0x80 | ((c >> 6) & 0x3f)));
dst.put((byte)(0x80 | (c & 0x3f)));
}
private Surrogate.Parser sgp;
private char[] c2;
private CoderResult encodeArrayLoop(CharBuffer src,
ByteBuffer dst)
{
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
int dlASCII = dp + Math.min(sl - sp, dl - dp);
// ASCII only loop
while (dp < dlASCII && sa[sp] < '\u0080')
da[dp++] = (byte) sa[sp++];
while (sp < sl) {
char c = sa[sp];
if (c < 0x80) {
// Have at most seven bits
if (dp >= dl)
return overflow(src, sp, dst, dp);
da[dp++] = (byte)c;
} else if (c < 0x800) {
// 2 bytes, 11 bits
if (dl - dp < 2)
return overflow(src, sp, dst, dp);
da[dp++] = (byte)(0xc0 | (c >> 6));
da[dp++] = (byte)(0x80 | (c & 0x3f));
} else if (Character.isSurrogate(c)) {
// Have a surrogate pair
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse(c, sa, sp, sl);
if (uc < 0) {
updatePositions(src, sp, dst, dp);
return sgp.error();
}
if (dl - dp < 6)
return overflow(src, sp, dst, dp);
to3Bytes(da, dp, Character.highSurrogate(uc));
dp += 3;
to3Bytes(da, dp, Character.lowSurrogate(uc));
dp += 3;
sp++; // 2 chars
} else {
// 3 bytes, 16 bits
if (dl - dp < 3)
return overflow(src, sp, dst, dp);
to3Bytes(da, dp, c);
dp += 3;
}
sp++;
}
updatePositions(src, sp, dst, dp);
return CoderResult.UNDERFLOW;
}
private CoderResult encodeBufferLoop(CharBuffer src,
ByteBuffer dst)
{
int mark = src.position();
while (src.hasRemaining()) {
char c = src.get();
if (c < 0x80) {
// Have at most seven bits
if (!dst.hasRemaining())
return overflow(src, mark);
dst.put((byte)c);
} else if (c < 0x800) {
// 2 bytes, 11 bits
if (dst.remaining() < 2)
return overflow(src, mark);
dst.put((byte)(0xc0 | (c >> 6)));
dst.put((byte)(0x80 | (c & 0x3f)));
} else if (Character.isSurrogate(c)) {
// Have a surrogate pair
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse(c, src);
if (uc < 0) {
src.position(mark);
return sgp.error();
}
if (dst.remaining() < 6)
return overflow(src, mark);
to3Bytes(dst, Character.highSurrogate(uc));
to3Bytes(dst, Character.lowSurrogate(uc));
mark++; // 2 chars
} else {
// 3 bytes, 16 bits
if (dst.remaining() < 3)
return overflow(src, mark);
to3Bytes(dst, c);
}
mark++;
}
src.position(mark);
return CoderResult.UNDERFLOW;
}
protected final CoderResult encodeLoop(CharBuffer src,
ByteBuffer dst)
{
if (src.hasArray() && dst.hasArray())
return encodeArrayLoop(src, dst);
else
return encodeBufferLoop(src, dst);
}
// returns -1 if there is malformed char(s) and the
// "action" for malformed input is not REPLACE.
public int encode(char[] sa, int sp, int len, byte[] da) {
int sl = sp + len;
int dp = 0;
int dlASCII = dp + Math.min(len, da.length);
// ASCII only optimized loop
while (dp < dlASCII && sa[sp] < '\u0080')
da[dp++] = (byte) sa[sp++];
while (sp < sl) {
char c = sa[sp++];
if (c < 0x80) {
// Have at most seven bits
da[dp++] = (byte)c;
} else if (c < 0x800) {
// 2 bytes, 11 bits
da[dp++] = (byte)(0xc0 | (c >> 6));
da[dp++] = (byte)(0x80 | (c & 0x3f));
} else if (Character.isSurrogate(c)) {
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse(c, sa, sp - 1, sl);
if (uc < 0) {
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
da[dp++] = replacement()[0];
} else {
to3Bytes(da, dp, Character.highSurrogate(uc));
dp += 3;
to3Bytes(da, dp, Character.lowSurrogate(uc));
dp += 3;
sp++; // 2 chars
}
} else {
// 3 bytes, 16 bits
to3Bytes(da, dp, c);
dp += 3;
}
}
return dp;
}
}
}

View file

@ -72,7 +72,7 @@ class UTF_8 extends Unicode
return new Encoder(this); return new Encoder(this);
} }
static final void updatePositions(Buffer src, int sp, private static final void updatePositions(Buffer src, int sp,
Buffer dst, int dp) { Buffer dst, int dp) {
src.position(sp - src.arrayOffset()); src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset()); dst.position(dp - dst.arrayOffset());
@ -88,11 +88,6 @@ class UTF_8 extends Unicode
return (b & 0xc0) != 0x80; return (b & 0xc0) != 0x80;
} }
// [C2..DF] [80..BF]
private static boolean isMalformed2(int b1, int b2) {
return (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80;
}
// [E0] [A0..BF] [80..BF] // [E0] [A0..BF] [80..BF]
// [E1..EF] [80..BF] [80..BF] // [E1..EF] [80..BF] [80..BF]
private static boolean isMalformed3(int b1, int b2, int b3) { private static boolean isMalformed3(int b1, int b2, int b3) {
@ -100,6 +95,12 @@ class UTF_8 extends Unicode
(b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
} }
// only used when there is only one byte left in src buffer
private static boolean isMalformed3_2(int b1, int b2) {
return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
(b2 & 0xc0) != 0x80;
}
// [F0] [90..BF] [80..BF] [80..BF] // [F0] [90..BF] [80..BF] [80..BF]
// [F1..F3] [80..BF] [80..BF] [80..BF] // [F1..F3] [80..BF] [80..BF] [80..BF]
// [F4] [80..8F] [80..BF] [80..BF] // [F4] [80..8F] [80..BF] [80..BF]
@ -110,6 +111,16 @@ class UTF_8 extends Unicode
(b4 & 0xc0) != 0x80; (b4 & 0xc0) != 0x80;
} }
// only used when there is less than 4 bytes left in src buffer
private static boolean isMalformed4_2(int b1, int b2) {
return (b1 == 0xf0 && b2 == 0x90) ||
(b2 & 0xc0) != 0x80;
}
private static boolean isMalformed4_3(int b3) {
return (b3 & 0xc0) != 0x80;
}
private static CoderResult lookupN(ByteBuffer src, int n) private static CoderResult lookupN(ByteBuffer src, int n)
{ {
for (int i = 1; i < n; i++) { for (int i = 1; i < n; i++) {
@ -122,28 +133,14 @@ class UTF_8 extends Unicode
private static CoderResult malformedN(ByteBuffer src, int nb) { private static CoderResult malformedN(ByteBuffer src, int nb) {
switch (nb) { switch (nb) {
case 1: case 1:
int b1 = src.get();
if ((b1 >> 2) == -2) {
// 5 bytes 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
if (src.remaining() < 4)
return CoderResult.UNDERFLOW;
return lookupN(src, 5);
}
if ((b1 >> 1) == -2) {
// 6 bytes 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
if (src.remaining() < 5)
return CoderResult.UNDERFLOW;
return lookupN(src, 6);
}
return CoderResult.malformedForLength(1);
case 2: // always 1 case 2: // always 1
return CoderResult.malformedForLength(1); return CoderResult.malformedForLength(1);
case 3: case 3:
b1 = src.get(); int b1 = src.get();
int b2 = src.get(); // no need to lookup b3 int b2 = src.get(); // no need to lookup b3
return CoderResult.malformedForLength( return CoderResult.malformedForLength(
((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
isNotContinuation(b2))?1:2); isNotContinuation(b2)) ? 1 : 2);
case 4: // we don't care the speed here case 4: // we don't care the speed here
b1 = src.get() & 0xff; b1 = src.get() & 0xff;
b2 = src.get() & 0xff; b2 = src.get() & 0xff;
@ -171,6 +168,7 @@ class UTF_8 extends Unicode
return cr; return cr;
} }
private static CoderResult malformed(ByteBuffer src, private static CoderResult malformed(ByteBuffer src,
int mark, int nb) int mark, int nb)
{ {
@ -180,18 +178,36 @@ class UTF_8 extends Unicode
return cr; return cr;
} }
private static CoderResult malformedForLength(ByteBuffer src,
int sp,
CharBuffer dst,
int dp,
int malformedNB)
{
updatePositions(src, sp, dst, dp);
return CoderResult.malformedForLength(malformedNB);
}
private static CoderResult malformedForLength(ByteBuffer src,
int mark,
int malformedNB)
{
src.position(mark);
return CoderResult.malformedForLength(malformedNB);
}
private static CoderResult xflow(Buffer src, int sp, int sl, private static CoderResult xflow(Buffer src, int sp, int sl,
Buffer dst, int dp, int nb) { Buffer dst, int dp, int nb) {
updatePositions(src, sp, dst, dp); updatePositions(src, sp, dst, dp);
return (nb == 0 || sl - sp < nb) return (nb == 0 || sl - sp < nb)
?CoderResult.UNDERFLOW:CoderResult.OVERFLOW; ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW;
} }
private static CoderResult xflow(Buffer src, int mark, int nb) { private static CoderResult xflow(Buffer src, int mark, int nb) {
CoderResult cr = (nb == 0 || src.remaining() < (nb - 1))
?CoderResult.UNDERFLOW:CoderResult.OVERFLOW;
src.position(mark); src.position(mark);
return cr; return (nb == 0 || src.remaining() < nb)
? CoderResult.UNDERFLOW : CoderResult.OVERFLOW;
} }
private CoderResult decodeArrayLoop(ByteBuffer src, private CoderResult decodeArrayLoop(ByteBuffer src,
@ -210,7 +226,6 @@ class UTF_8 extends Unicode
// ASCII only loop // ASCII only loop
while (dp < dlASCII && sa[sp] >= 0) while (dp < dlASCII && sa[sp] >= 0)
da[dp++] = (char) sa[sp++]; da[dp++] = (char) sa[sp++];
while (sp < sl) { while (sp < sl) {
int b1 = sa[sp]; int b1 = sa[sp];
if (b1 >= 0) { if (b1 >= 0) {
@ -219,13 +234,20 @@ class UTF_8 extends Unicode
return xflow(src, sp, sl, dst, dp, 1); return xflow(src, sp, sl, dst, dp, 1);
da[dp++] = (char) b1; da[dp++] = (char) b1;
sp++; sp++;
} else if ((b1 >> 5) == -2) { } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
// [C2..DF] [80..BF]
if (sl - sp < 2 || dp >= dl) if (sl - sp < 2 || dp >= dl)
return xflow(src, sp, sl, dst, dp, 2); return xflow(src, sp, sl, dst, dp, 2);
int b2 = sa[sp + 1]; int b2 = sa[sp + 1];
if (isMalformed2(b1, b2)) // Now we check the first byte of 2-byte sequence as
return malformed(src, sp, dst, dp, 2); // if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0)
// no longer need to check b1 against c1 & c0 for
// malformed as we did in previous version
// (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80;
// only need to check the second byte b2.
if (isNotContinuation(b2))
return malformedForLength(src, sp, dst, dp, 1);
da[dp++] = (char) (((b1 << 6) ^ b2) da[dp++] = (char) (((b1 << 6) ^ b2)
^ ^
(((byte) 0xC0 << 6) ^ (((byte) 0xC0 << 6) ^
@ -233,24 +255,37 @@ class UTF_8 extends Unicode
sp += 2; sp += 2;
} else if ((b1 >> 4) == -2) { } else if ((b1 >> 4) == -2) {
// 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
if (sl - sp < 3 || dp >= dl) int srcRemaining = sl - sp;
if (srcRemaining < 3 || dp >= dl) {
if (srcRemaining > 1 && isMalformed3_2(b1, sa[sp + 1]))
return malformedForLength(src, sp, dst, dp, 1);
return xflow(src, sp, sl, dst, dp, 3); return xflow(src, sp, sl, dst, dp, 3);
}
int b2 = sa[sp + 1]; int b2 = sa[sp + 1];
int b3 = sa[sp + 2]; int b3 = sa[sp + 2];
if (isMalformed3(b1, b2, b3)) if (isMalformed3(b1, b2, b3))
return malformed(src, sp, dst, dp, 3); return malformed(src, sp, dst, dp, 3);
da[dp++] = (char) char c = (char)
((b1 << 12) ^ ((b1 << 12) ^
(b2 << 6) ^ (b2 << 6) ^
(b3 ^ (b3 ^
(((byte) 0xE0 << 12) ^ (((byte) 0xE0 << 12) ^
((byte) 0x80 << 6) ^ ((byte) 0x80 << 6) ^
((byte) 0x80 << 0)))); ((byte) 0x80 << 0))));
if (Character.isSurrogate(c))
return malformedForLength(src, sp, dst, dp, 3);
da[dp++] = c;
sp += 3; sp += 3;
} else if ((b1 >> 3) == -2) { } else if ((b1 >> 3) == -2) {
// 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
if (sl - sp < 4 || dl - dp < 2) int srcRemaining = sl - sp;
if (srcRemaining < 4 || dl - dp < 2) {
if (srcRemaining > 1 && isMalformed4_2(b1, sa[sp + 1]))
return malformedForLength(src, sp, dst, dp, 1);
if (srcRemaining > 2 && isMalformed4_3(sa[sp + 2]))
return malformedForLength(src, sp, dst, dp, 2);
return xflow(src, sp, sl, dst, dp, 4); return xflow(src, sp, sl, dst, dp, 4);
}
int b2 = sa[sp + 1]; int b2 = sa[sp + 1];
int b3 = sa[sp + 2]; int b3 = sa[sp + 2];
int b4 = sa[sp + 3]; int b4 = sa[sp + 3];
@ -289,13 +324,13 @@ class UTF_8 extends Unicode
return xflow(src, mark, 1); // overflow return xflow(src, mark, 1); // overflow
dst.put((char) b1); dst.put((char) b1);
mark++; mark++;
} else if ((b1 >> 5) == -2) { } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
if (limit - mark < 2|| dst.remaining() < 1) if (limit - mark < 2|| dst.remaining() < 1)
return xflow(src, mark, 2); return xflow(src, mark, 2);
int b2 = src.get(); int b2 = src.get();
if (isMalformed2(b1, b2)) if (isNotContinuation(b2))
return malformed(src, mark, 2); return malformedForLength(src, mark, 1);
dst.put((char) (((b1 << 6) ^ b2) dst.put((char) (((b1 << 6) ^ b2)
^ ^
(((byte) 0xC0 << 6) ^ (((byte) 0xC0 << 6) ^
@ -303,24 +338,37 @@ class UTF_8 extends Unicode
mark += 2; mark += 2;
} else if ((b1 >> 4) == -2) { } else if ((b1 >> 4) == -2) {
// 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
if (limit - mark < 3 || dst.remaining() < 1) int srcRemaining = limit - mark;
if (srcRemaining < 3 || dst.remaining() < 1) {
if (srcRemaining > 1 && isMalformed3_2(b1, src.get()))
return malformedForLength(src, mark, 1);
return xflow(src, mark, 3); return xflow(src, mark, 3);
}
int b2 = src.get(); int b2 = src.get();
int b3 = src.get(); int b3 = src.get();
if (isMalformed3(b1, b2, b3)) if (isMalformed3(b1, b2, b3))
return malformed(src, mark, 3); return malformed(src, mark, 3);
dst.put((char) char c = (char)
((b1 << 12) ^ ((b1 << 12) ^
(b2 << 6) ^ (b2 << 6) ^
(b3 ^ (b3 ^
(((byte) 0xE0 << 12) ^ (((byte) 0xE0 << 12) ^
((byte) 0x80 << 6) ^ ((byte) 0x80 << 6) ^
((byte) 0x80 << 0))))); ((byte) 0x80 << 0))));
if (Character.isSurrogate(c))
return malformedForLength(src, mark, 3);
dst.put(c);
mark += 3; mark += 3;
} else if ((b1 >> 3) == -2) { } else if ((b1 >> 3) == -2) {
// 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
if (limit - mark < 4 || dst.remaining() < 2) int srcRemaining = limit - mark;
if (srcRemaining < 4 || dst.remaining() < 2) {
if (srcRemaining > 1 && isMalformed4_2(b1, src.get()))
return malformedForLength(src, mark, 1);
if (srcRemaining > 2 && isMalformed4_3(src.get()))
return malformedForLength(src, mark, 2);
return xflow(src, mark, 4); return xflow(src, mark, 4);
}
int b2 = src.get(); int b2 = src.get();
int b3 = src.get(); int b3 = src.get();
int b4 = src.get(); int b4 = src.get();
@ -364,7 +412,7 @@ class UTF_8 extends Unicode
return bb; return bb;
} }
// returns -1 if there is malformed byte(s) and the // returns -1 if there is/are malformed byte(s) and the
// "action" for malformed input is not REPLACE. // "action" for malformed input is not REPLACE.
public int decode(byte[] sa, int sp, int len, char[] da) { public int decode(byte[] sa, int sp, int len, char[] da) {
final int sl = sp + len; final int sl = sp + len;
@ -381,11 +429,11 @@ class UTF_8 extends Unicode
if (b1 >= 0) { if (b1 >= 0) {
// 1 byte, 7 bits: 0xxxxxxx // 1 byte, 7 bits: 0xxxxxxx
da[dp++] = (char) b1; da[dp++] = (char) b1;
} else if ((b1 >> 5) == -2) { } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
if (sp < sl) { if (sp < sl) {
int b2 = sa[sp++]; int b2 = sa[sp++];
if (isMalformed2(b1, b2)) { if (isNotContinuation(b2)) {
if (malformedInputAction() != CodingErrorAction.REPLACE) if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1; return -1;
da[dp++] = replacement().charAt(0); da[dp++] = replacement().charAt(0);
@ -410,21 +458,33 @@ class UTF_8 extends Unicode
if (malformedInputAction() != CodingErrorAction.REPLACE) if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1; return -1;
da[dp++] = replacement().charAt(0); da[dp++] = replacement().charAt(0);
sp -=3; sp -= 3;
bb = getByteBuffer(bb, sa, sp); bb = getByteBuffer(bb, sa, sp);
sp += malformedN(bb, 3).length(); sp += malformedN(bb, 3).length();
} else { } else {
da[dp++] = (char)((b1 << 12) ^ char c = (char)((b1 << 12) ^
(b2 << 6) ^ (b2 << 6) ^
(b3 ^ (b3 ^
(((byte) 0xE0 << 12) ^ (((byte) 0xE0 << 12) ^
((byte) 0x80 << 6) ^ ((byte) 0x80 << 6) ^
((byte) 0x80 << 0)))); ((byte) 0x80 << 0))));
if (Character.isSurrogate(c)) {
if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1;
da[dp++] = replacement().charAt(0);
} else {
da[dp++] = c;
}
} }
continue; continue;
} }
if (malformedInputAction() != CodingErrorAction.REPLACE) if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1; return -1;
if (sp < sl && isMalformed3_2(b1, sa[sp])) {
da[dp++] = replacement().charAt(0);
continue;
}
da[dp++] = replacement().charAt(0); da[dp++] = replacement().charAt(0);
return dp; return dp;
} else if ((b1 >> 3) == -2) { } else if ((b1 >> 3) == -2) {
@ -458,28 +518,29 @@ class UTF_8 extends Unicode
} }
if (malformedInputAction() != CodingErrorAction.REPLACE) if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1; return -1;
if (sp < sl && isMalformed4_2(b1, sa[sp])) {
da[dp++] = replacement().charAt(0);
continue;
}
sp++;
if (sp < sl && isMalformed4_3(sa[sp])) {
da[dp++] = replacement().charAt(0);
continue;
}
da[dp++] = replacement().charAt(0); da[dp++] = replacement().charAt(0);
return dp; return dp;
} else { } else {
if (malformedInputAction() != CodingErrorAction.REPLACE) if (malformedInputAction() != CodingErrorAction.REPLACE)
return -1; return -1;
da[dp++] = replacement().charAt(0); da[dp++] = replacement().charAt(0);
sp--;
bb = getByteBuffer(bb, sa, sp);
CoderResult cr = malformedN(bb, 1);
if (!cr.isError()) {
// leading byte for 5 or 6-byte, but don't have enough
// bytes in buffer to check. Consumed rest as malformed.
return dp;
}
sp += cr.length();
} }
} }
return dp; return dp;
} }
} }
private static class Encoder extends CharsetEncoder private static final class Encoder extends CharsetEncoder
implements ArrayEncoder { implements ArrayEncoder {
private Encoder(Charset cs) { private Encoder(Charset cs) {

View file

@ -63,6 +63,10 @@ charset UTF-8 UTF_8
alias UTF8 # JDK historical alias UTF8 # JDK historical
alias unicode-1-1-utf-8 alias unicode-1-1-utf-8
charset CESU-8 CESU_8
alias CESU8
alias csCESU-8
charset UTF-16 UTF_16 charset UTF-16 UTF_16
alias UTF_16 # JDK historical alias UTF_16 # JDK historical
alias utf16 alias utf16

View file

@ -68,14 +68,18 @@ import javax.print.attribute.standard.Sides;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.CharConversionException; import java.io.CharConversionException;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException; import java.io.IOException;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
@ -673,15 +677,38 @@ public class PSPrinterJob extends RasterPrinterJob {
private class PrinterSpooler implements java.security.PrivilegedAction { private class PrinterSpooler implements java.security.PrivilegedAction {
PrinterException pex; PrinterException pex;
private void handleProcessFailure(final Process failedProcess,
final String[] execCmd, final int result) throws IOException {
try (StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw)) {
pw.append("error=").append(Integer.toString(result));
pw.append(" running:");
for (String arg: execCmd) {
pw.append(" '").append(arg).append("'");
}
try (InputStream is = failedProcess.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
while (br.ready()) {
pw.println();
pw.append("\t\t").append(br.readLine());
}
} finally {
pw.flush();
throw new IOException(sw.toString());
}
}
}
public Object run() { public Object run() {
try {
/**
* Spool to the printer.
*/
if (spoolFile == null || !spoolFile.exists()) { if (spoolFile == null || !spoolFile.exists()) {
pex = new PrinterException("No spool file"); pex = new PrinterException("No spool file");
return null; return null;
} }
try {
/**
* Spool to the printer.
*/
String fileName = spoolFile.getAbsolutePath(); String fileName = spoolFile.getAbsolutePath();
String execCmd[] = printExecCmd(mDestination, mOptions, String execCmd[] = printExecCmd(mDestination, mOptions,
mNoJobSheet, getJobNameInt(), mNoJobSheet, getJobNameInt(),
@ -689,12 +716,16 @@ public class PSPrinterJob extends RasterPrinterJob {
Process process = Runtime.getRuntime().exec(execCmd); Process process = Runtime.getRuntime().exec(execCmd);
process.waitFor(); process.waitFor();
spoolFile.delete(); final int result = process.exitValue();
if (0 != result) {
handleProcessFailure(process, execCmd, result);
}
} catch (IOException ex) { } catch (IOException ex) {
pex = new PrinterIOException(ex); pex = new PrinterIOException(ex);
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
pex = new PrinterException(ie.toString()); pex = new PrinterException(ie.toString());
} finally {
spoolFile.delete();
} }
return null; return null;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.io.FilePermission;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.*;
import java.rmi.*; import java.rmi.*;
@ -38,8 +39,17 @@ import java.rmi.server.ServerNotActiveException;
import java.rmi.registry.Registry; import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RMIServerSocketFactory;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Policy;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.text.MessageFormat; import java.text.MessageFormat;
import sun.rmi.server.LoaderHandler;
import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2; import sun.rmi.server.UnicastServerRef2;
import sun.rmi.transport.LiveRef; import sun.rmi.transport.LiveRef;
@ -334,11 +344,19 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
Thread.currentThread().setContextClassLoader(cl); Thread.currentThread().setContextClassLoader(cl);
int regPort = Registry.REGISTRY_PORT; final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
if (args.length >= 1) { : Registry.REGISTRY_PORT;
regPort = Integer.parseInt(args[0]); try {
registry = AccessController.doPrivileged(
new PrivilegedExceptionAction<RegistryImpl>() {
public RegistryImpl run() throws RemoteException {
return new RegistryImpl(regPort);
} }
registry = new RegistryImpl(regPort); }, getAccessControlContext());
} catch (PrivilegedActionException ex) {
throw (RemoteException) ex.getException();
}
// prevent registry from exiting // prevent registry from exiting
while (true) { while (true) {
try { try {
@ -358,4 +376,46 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
} }
System.exit(1); System.exit(1);
} }
/**
* Generates an AccessControlContext with minimal permissions.
* The approach used here is taken from the similar method
* getAccessControlContext() in the sun.applet.AppletPanel class.
*/
private static AccessControlContext getAccessControlContext() {
// begin with permissions granted to all code in current policy
PermissionCollection perms = AccessController.doPrivileged(
new java.security.PrivilegedAction<PermissionCollection>() {
public PermissionCollection run() {
CodeSource codesource = new CodeSource(null,
(java.security.cert.Certificate[]) null);
Policy p = java.security.Policy.getPolicy();
if (p != null) {
return p.getPermissions(codesource);
} else {
return new Permissions();
}
}
});
/*
* Anyone can connect to the registry and the registry can connect
* to and possibly download stubs from anywhere. Downloaded stubs and
* related classes themselves are more tightly limited by RMI.
*/
perms.add(new SocketPermission("*", "connect,accept"));
perms.add(new RuntimePermission("accessClassInPackage.sun.*"));
perms.add(new FilePermission("<<ALL FILES>>", "read"));
/*
* Create an AccessControlContext that consists of a single
* protection domain with only the permissions calculated above.
*/
ProtectionDomain pd = new ProtectionDomain(
new CodeSource(null,
(java.security.cert.Certificate[]) null), perms);
return new AccessControlContext(new ProtectionDomain[] { pd });
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View file

@ -390,6 +390,12 @@ public class UnicastServerRef extends UnicastRef
ObjectInput in; ObjectInput in;
try { try {
in = call.getInputStream(); in = call.getInputStream();
try {
Class<?> clazz = Class.forName("sun.rmi.transport.DGCImpl_Skel");
if (clazz.isAssignableFrom(skel.getClass())) {
((MarshalInputStream)in).useCodebaseOnly();
}
} catch (ClassNotFoundException ignore) { }
hash = in.readLong(); hash = in.readLong();
} catch (Exception readEx) { } catch (Exception readEx) {
throw new UnmarshalException("error unmarshalling call header", throw new UnmarshalException("error unmarshalling call header",

View file

@ -68,8 +68,8 @@ public class KerberosTime implements Cloneable {
private int microSeconds; // the last three digits of the microsecond value private int microSeconds; // the last three digits of the microsecond value
// The time when this class is loaded. Used in setNow() // The time when this class is loaded. Used in setNow()
private static final long initMilli = System.currentTimeMillis(); private static long initMilli = System.currentTimeMillis();
private static final long initMicro = System.nanoTime() / 1000; private static long initMicro = System.nanoTime() / 1000;
private static long syncTime; private static long syncTime;
private static boolean DEBUG = Krb5.DEBUG; private static boolean DEBUG = Krb5.DEBUG;
@ -212,10 +212,23 @@ public class KerberosTime implements Cloneable {
} }
public void setNow() { public void setNow() {
long microElapsed = System.nanoTime() / 1000 - initMicro; long newMilli = System.currentTimeMillis();
setTime(initMilli + microElapsed/1000); long newMicro = System.nanoTime() / 1000;
long microElapsed = newMicro - initMicro;
long calcMilli = initMilli + microElapsed/1000;
if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
if (DEBUG) {
System.out.println("System time adjusted");
}
initMilli = newMilli;
initMicro = newMicro;
setTime(newMilli);
microSeconds = 0;
} else {
setTime(calcMilli);
microSeconds = (int)(microElapsed % 1000); microSeconds = (int)(microElapsed % 1000);
} }
}
public int getMicroSeconds() { public int getMicroSeconds() {
Long temp_long = new Long((kerberosTime % 1000L) * 1000L); Long temp_long = new Long((kerberosTime % 1000L) * 1000L);

View file

@ -375,7 +375,7 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC
} }
AuthorizationDataEntry[] auDataEntry = readAuth(); AuthorizationDataEntry[] auDataEntry = readAuth();
AuthorizationData auData = null; AuthorizationData auData = null;
if (auData != null) { if (auDataEntry != null) {
auData = new AuthorizationData(auDataEntry); auData = new AuthorizationData(auDataEntry);
} }
byte[] ticketData = readData(); byte[] ticketData = readData();

View file

@ -209,10 +209,24 @@ public class Credentials {
} }
public sun.security.krb5.Credentials setKrbCreds() { public sun.security.krb5.Credentials setKrbCreds() {
// Note: We will not pass authorizationData to s.s.k.Credentials. The
// field in that class will be passed to Krb5Context as the return
// value of ExtendedGSSContext.inquireSecContext(KRB5_GET_AUTHZ_DATA),
// which is documented as the authData in the service ticket. That
// is on the acceptor side.
//
// This class is for the initiator side. Also, authdata inside a ccache
// is most likely to be the one in Authenticator in PA-TGS-REQ encoded
// in TGS-REQ, therefore only stored with a service ticket. Currently
// in Java, we only reads TGTs.
return new sun.security.krb5.Credentials(ticket, return new sun.security.krb5.Credentials(ticket,
cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr); cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
} }
public KerberosTime getStartTime() {
return starttime;
}
public KerberosTime getAuthTime() { public KerberosTime getAuthTime() {
return authtime; return authtime;
} }
@ -221,6 +235,10 @@ public class Credentials {
return endtime; return endtime;
} }
public KerberosTime getRenewTill() {
return renewTill;
}
public TicketFlags getTicketFlags() { public TicketFlags getTicketFlags() {
return flags; return flags;
} }
@ -228,4 +246,8 @@ public class Credentials {
public int getEType() { public int getEType() {
return key.getEType(); return key.getEType();
} }
public int getTktEType() {
return ticket.encPart.getEType();
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -69,12 +69,38 @@ class AppOutputStream extends OutputStream {
// check if the Socket is invalid (error or closed) // check if the Socket is invalid (error or closed)
c.checkWrite(); c.checkWrite();
/*
* By default, we counter chosen plaintext issues on CBC mode
* ciphersuites in SSLv3/TLS1.0 by sending one byte of application
* data in the first record of every payload, and the rest in
* subsequent record(s). Note that the issues have been solved in
* TLS 1.1 or later.
*
* It is not necessary to split the very first application record of
* a freshly negotiated TLS session, as there is no previous
* application data to guess. To improve compatibility, we will not
* split such records.
*
* This avoids issues in the outbound direction. For a full fix,
* the peer must have similar protections.
*/
boolean isFirstRecordOfThePayload = true;
// Always flush at the end of each application level record. // Always flush at the end of each application level record.
// This lets application synchronize read and write streams // This lets application synchronize read and write streams
// however they like; if we buffered here, they couldn't. // however they like; if we buffered here, they couldn't.
try { try {
do { do {
int howmuch = Math.min(len, r.availableDataBytes()); int howmuch;
if (isFirstRecordOfThePayload && c.needToSplitPayload()) {
howmuch = Math.min(0x01, r.availableDataBytes());
} else {
howmuch = Math.min(len, r.availableDataBytes());
}
if (isFirstRecordOfThePayload && howmuch != 0) {
isFirstRecordOfThePayload = false;
}
// NOTE: *must* call c.writeRecord() even for howmuch == 0 // NOTE: *must* call c.writeRecord() even for howmuch == 0
if (howmuch > 0) { if (howmuch > 0) {

View file

@ -112,6 +112,11 @@ final class CipherBox {
*/ */
private SecureRandom random; private SecureRandom random;
/**
* Is the cipher of CBC mode?
*/
private final boolean isCBCMode;
/** /**
* Fixed masks of various block size, as the initial decryption IVs * Fixed masks of various block size, as the initial decryption IVs
* for TLS 1.1 or later. * for TLS 1.1 or later.
@ -128,6 +133,7 @@ final class CipherBox {
private CipherBox() { private CipherBox() {
this.protocolVersion = ProtocolVersion.DEFAULT; this.protocolVersion = ProtocolVersion.DEFAULT;
this.cipher = null; this.cipher = null;
this.isCBCMode = false;
} }
/** /**
@ -148,6 +154,7 @@ final class CipherBox {
random = JsseJce.getSecureRandom(); random = JsseJce.getSecureRandom();
} }
this.random = random; this.random = random;
this.isCBCMode = bulkCipher.isCBCMode;
/* /*
* RFC 4346 recommends two algorithms used to generated the * RFC 4346 recommends two algorithms used to generated the
@ -694,4 +701,12 @@ final class CipherBox {
} }
} }
/*
* Does the cipher use CBC mode?
*
* @return true if the cipher use CBC mode, false otherwise.
*/
boolean isCBCMode() {
return isCBCMode;
}
} }

View file

@ -420,10 +420,16 @@ final class CipherSuite implements Comparable<CipherSuite> {
// exportable under 512/40 bit rules // exportable under 512/40 bit rules
final boolean exportable; final boolean exportable;
// Is the cipher algorithm of Cipher Block Chaining (CBC) mode?
final boolean isCBCMode;
BulkCipher(String transformation, int keySize, BulkCipher(String transformation, int keySize,
int expandedKeySize, int ivSize, boolean allowed) { int expandedKeySize, int ivSize, boolean allowed) {
this.transformation = transformation; this.transformation = transformation;
this.algorithm = transformation.split("/")[0]; String[] splits = transformation.split("/");
this.algorithm = splits[0];
this.isCBCMode =
splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
this.description = this.algorithm + "/" + (keySize << 3); this.description = this.algorithm + "/" + (keySize << 3);
this.keySize = keySize; this.keySize = keySize;
this.ivSize = ivSize; this.ivSize = ivSize;
@ -436,7 +442,10 @@ final class CipherSuite implements Comparable<CipherSuite> {
BulkCipher(String transformation, int keySize, BulkCipher(String transformation, int keySize,
int ivSize, boolean allowed) { int ivSize, boolean allowed) {
this.transformation = transformation; this.transformation = transformation;
this.algorithm = transformation.split("/")[0]; String[] splits = transformation.split("/");
this.algorithm = splits[0];
this.isCBCMode =
splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
this.description = this.algorithm + "/" + (keySize << 3); this.description = this.algorithm + "/" + (keySize << 3);
this.keySize = keySize; this.keySize = keySize;
this.ivSize = ivSize; this.ivSize = ivSize;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,6 +46,7 @@ import sun.misc.HexDumpEncoder;
*/ */
final class EngineOutputRecord extends OutputRecord { final class EngineOutputRecord extends OutputRecord {
private SSLEngineImpl engine;
private EngineWriter writer; private EngineWriter writer;
private boolean finishedMsg = false; private boolean finishedMsg = false;
@ -62,6 +63,7 @@ final class EngineOutputRecord extends OutputRecord {
*/ */
EngineOutputRecord(byte type, SSLEngineImpl engine) { EngineOutputRecord(byte type, SSLEngineImpl engine) {
super(type, recordSize(type)); super(type, recordSize(type));
this.engine = engine;
writer = engine.writer; writer = engine.writer;
} }
@ -227,11 +229,50 @@ final class EngineOutputRecord extends OutputRecord {
* implementations are fragile and don't like to see empty * implementations are fragile and don't like to see empty
* records, so this increases robustness. * records, so this increases robustness.
*/ */
int length = Math.min(ea.getAppRemaining(), maxDataSize); if (ea.getAppRemaining() == 0) {
if (length == 0) {
return; return;
} }
/*
* By default, we counter chosen plaintext issues on CBC mode
* ciphersuites in SSLv3/TLS1.0 by sending one byte of application
* data in the first record of every payload, and the rest in
* subsequent record(s). Note that the issues have been solved in
* TLS 1.1 or later.
*
* It is not necessary to split the very first application record of
* a freshly negotiated TLS session, as there is no previous
* application data to guess. To improve compatibility, we will not
* split such records.
*
* Because of the compatibility, we'd better produce no more than
* SSLSession.getPacketBufferSize() net data for each wrap. As we
* need a one-byte record at first, the 2nd record size should be
* equal to or less than Record.maxDataSizeMinusOneByteRecord.
*
* This avoids issues in the outbound direction. For a full fix,
* the peer must have similar protections.
*/
int length;
if (engine.needToSplitPayload(writeCipher, protocolVersion)) {
write(ea, writeMAC, writeCipher, 0x01);
ea.resetLim(); // reset application data buffer limit
length = Math.min(ea.getAppRemaining(),
maxDataSizeMinusOneByteRecord);
} else {
length = Math.min(ea.getAppRemaining(), maxDataSize);
}
// Don't bother to really write empty records.
if (length > 0) {
write(ea, writeMAC, writeCipher, length);
}
return;
}
void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher,
int length) throws IOException {
/* /*
* Copy out existing buffer values. * Copy out existing buffer values.
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -172,10 +172,10 @@ final class MAC {
* when there are only 2^8 sequence numbers left. * when there are only 2^8 sequence numbers left.
*/ */
return (block != null && mac != null && return (block != null && mac != null &&
block[0] == 0xFF && block[1] == 0xFF && block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
block[2] == 0xFF && block[3] == 0xFF && block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
block[4] == 0xFF && block[5] == 0xFF && block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
block[6] == 0xFF); block[6] == (byte)0xFF);
} }
/* /*
@ -192,7 +192,7 @@ final class MAC {
* only 2^48 sequence numbers left. * only 2^48 sequence numbers left.
*/ */
return (block != null && mac != null && return (block != null && mac != null &&
block[0] == 0xFF && block[1] == 0xFF); block[0] == (byte)0xFF && block[1] == (byte)0xFF);
} }
// increment the sequence number in the block array // increment the sequence number in the block array

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -67,6 +67,23 @@ interface Record {
+ maxPadding // padding + maxPadding // padding
+ trailerSize; // MAC + trailerSize; // MAC
static final boolean enableCBCProtection =
Debug.getBooleanProperty("jsse.enableCBCProtection", true);
/*
* For CBC protection in SSL3/TLS1, we break some plaintext into two
* packets. Max application data size for the second packet.
*/
static final int maxDataSizeMinusOneByteRecord =
maxDataSize // max data size
- ( // max one byte record size
headerSize // header
+ maxIVLength // iv
+ 1 // one byte data
+ maxPadding // padding
+ trailerSize // MAC
);
/* /*
* The maximum large record size. * The maximum large record size.
* *

View file

@ -771,10 +771,15 @@ public abstract class SSLContextImpl extends SSLContextSpi {
final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
implements X509TrustManager { implements X509TrustManager {
// the delegated trust manager
private final X509TrustManager tm; private final X509TrustManager tm;
// Cache the trusted certificate to optimize the performance.
private final Collection<X509Certificate> trustedCerts = new HashSet<>();
AbstractTrustManagerWrapper(X509TrustManager tm) { AbstractTrustManagerWrapper(X509TrustManager tm) {
this.tm = tm; this.tm = tm;
Collections.addAll(trustedCerts, tm.getAcceptedIssuers());
} }
@Override @Override
@ -863,20 +868,7 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(sslSocket, true); constraints = new SSLAlgorithmConstraints(sslSocket, true);
} }
AlgorithmChecker checker = new AlgorithmChecker(constraints); checkAlgorithmConstraints(chain, constraints);
try {
checker.init(false);
// a forward checker, need to check from trust to target
for (int i = chain.length - 1; i >= 0; i--) {
Certificate cert = chain[i];
// We don't care about the unresolved critical extensions.
checker.check(cert, Collections.<String>emptySet());
}
} catch (CertPathValidatorException cpve) {
throw new CertificateException(
"Certificates does not conform to algorithm constraints");
}
} }
} }
@ -918,22 +910,35 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(engine, true); constraints = new SSLAlgorithmConstraints(engine, true);
} }
AlgorithmChecker checker = new AlgorithmChecker(constraints); checkAlgorithmConstraints(chain, constraints);
}
}
private void checkAlgorithmConstraints(X509Certificate[] chain,
AlgorithmConstraints constraints) throws CertificateException {
try { try {
checker.init(false); // Does the certificate chain end with a trusted certificate?
int checkedLength = chain.length - 1;
if (trustedCerts.contains(chain[checkedLength])) {
checkedLength--;
}
// A forward checker, need to check from trust to target // A forward checker, need to check from trust to target
for (int i = chain.length - 1; i >= 0; i--) { if (checkedLength >= 0) {
AlgorithmChecker checker = new AlgorithmChecker(constraints);
checker.init(false);
for (int i = checkedLength; i >= 0; i--) {
Certificate cert = chain[i]; Certificate cert = chain[i];
// We don't care about the unresolved critical extensions. // We don't care about the unresolved critical extensions.
checker.check(cert, Collections.<String>emptySet()); checker.check(cert, Collections.<String>emptySet());
} }
}
} catch (CertPathValidatorException cpve) { } catch (CertPathValidatorException cpve) {
throw new CertificateException( throw new CertificateException(
"Certificates does not conform to algorithm constraints"); "Certificates does not conform to algorithm constraints");
} }
} }
}
} }
// Dummy X509TrustManager implementation, rejects all peer certificates. // Dummy X509TrustManager implementation, rejects all peer certificates.

View file

@ -308,6 +308,11 @@ final public class SSLEngineImpl extends SSLEngine {
private Object unwrapLock; private Object unwrapLock;
Object writeLock; Object writeLock;
/*
* Is it the first application record to write?
*/
private boolean isFirstAppOutputRecord = true;
/* /*
* Class and subclass dynamic debugging support * Class and subclass dynamic debugging support
*/ */
@ -612,6 +617,9 @@ final public class SSLEngineImpl extends SSLEngine {
// See comment above. // See comment above.
oldCipher.dispose(); oldCipher.dispose();
// reset the flag of the first application record
isFirstAppOutputRecord = true;
} }
/* /*
@ -1286,9 +1294,35 @@ final public class SSLEngineImpl extends SSLEngine {
} }
} }
/*
* turn off the flag of the first application record if we really
* consumed at least byte.
*/
if (isFirstAppOutputRecord && ea.deltaApp() > 0) {
isFirstAppOutputRecord = false;
}
return hsStatus; return hsStatus;
} }
/*
* Need to split the payload except the following cases:
*
* 1. protocol version is TLS 1.1 or later;
* 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
* 3. the payload is the first application record of a freshly
* negotiated TLS session.
* 4. the CBC protection is disabled;
*
* More details, please refer to
* EngineOutputRecord.write(EngineArgs, MAC, CipherBox).
*/
boolean needToSplitPayload(CipherBox cipher, ProtocolVersion protocol) {
return (protocol.v <= ProtocolVersion.TLS10.v) &&
cipher.isCBCMode() && !isFirstAppOutputRecord &&
Record.enableCBCProtection;
}
/* /*
* Non-application OutputRecords go through here. * Non-application OutputRecords go through here.
*/ */

View file

@ -369,6 +369,11 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
/* Class and subclass dynamic debugging support */ /* Class and subclass dynamic debugging support */
private static final Debug debug = Debug.getInstance("ssl"); private static final Debug debug = Debug.getInstance("ssl");
/*
* Is it the first application record to write?
*/
private boolean isFirstAppOutputRecord = true;
// //
// CONSTRUCTORS AND INITIALIZATION CODE // CONSTRUCTORS AND INITIALIZATION CODE
// //
@ -802,8 +807,35 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
if (connectionState < cs_ERROR) { if (connectionState < cs_ERROR) {
checkSequenceNumber(writeMAC, r.contentType()); checkSequenceNumber(writeMAC, r.contentType());
} }
// turn off the flag of the first application record
if (isFirstAppOutputRecord &&
r.contentType() == Record.ct_application_data) {
isFirstAppOutputRecord = false;
}
} }
/*
* Need to split the payload except the following cases:
*
* 1. protocol version is TLS 1.1 or later;
* 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
* 3. the payload is the first application record of a freshly
* negotiated TLS session.
* 4. the CBC protection is disabled;
*
* More details, please refer to AppOutputStream.write(byte[], int, int).
*/
boolean needToSplitPayload() {
writeLock.lock();
try {
return (protocolVersion.v <= ProtocolVersion.TLS10.v) &&
writeCipher.isCBCMode() && !isFirstAppOutputRecord &&
Record.enableCBCProtection;
} finally {
writeLock.unlock();
}
}
/* /*
* Read an application data record. Alerts and handshake * Read an application data record. Alerts and handshake
@ -1453,7 +1485,8 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
private void closeSocket(boolean selfInitiated) throws IOException { private void closeSocket(boolean selfInitiated) throws IOException {
if ((debug != null) && Debug.isOn("ssl")) { if ((debug != null) && Debug.isOn("ssl")) {
System.out.println(threadName() + ", called closeSocket(selfInitiated)"); System.out.println(threadName() +
", called closeSocket(" + selfInitiated + ")");
} }
if (self == this) { if (self == this) {
super.close(); super.close();
@ -2030,6 +2063,9 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
// See comment above. // See comment above.
oldCipher.dispose(); oldCipher.dispose();
// reset the flag of the first application record
isFirstAppOutputRecord = true;
} }
/* /*

View file

@ -33,18 +33,7 @@ import java.security.*;
import java.util.Date; import java.util.Date;
import sun.security.pkcs10.PKCS10; import sun.security.pkcs10.PKCS10;
import sun.security.x509.AlgorithmId; import sun.security.x509.*;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateSubjectName;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
import sun.security.x509.X509Key;
/** /**
@ -165,6 +154,13 @@ public final class CertAndKeyGen {
publicKey = pair.getPublic(); publicKey = pair.getPublic();
privateKey = pair.getPrivate(); privateKey = pair.getPrivate();
// publicKey's format must be X.509 otherwise
// the whole CertGen part of this class is broken.
if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) {
throw new IllegalArgumentException("publicKey's is not X.509, but "
+ publicKey.getFormat());
}
} }
@ -186,6 +182,16 @@ public final class CertAndKeyGen {
return (X509Key)publicKey; return (X509Key)publicKey;
} }
/**
* Always returns the public key of the generated key pair. Used
* by KeyTool only.
*
* The publicKey is not necessarily to be an instance of
* X509Key in some JCA/JCE providers, for example SunPKCS11.
*/
public PublicKey getPublicKeyAnyway() {
return publicKey;
}
/** /**
* Returns the private key of the generated key pair. * Returns the private key of the generated key pair.
@ -200,7 +206,6 @@ public final class CertAndKeyGen {
return privateKey; return privateKey;
} }
/** /**
* Returns a self-signed X.509v3 certificate for the public key. * Returns a self-signed X.509v3 certificate for the public key.
* The certificate is immediately valid. No extensions. * The certificate is immediately valid. No extensions.
@ -224,6 +229,15 @@ public final class CertAndKeyGen {
X500Name myname, Date firstDate, long validity) X500Name myname, Date firstDate, long validity)
throws CertificateException, InvalidKeyException, SignatureException, throws CertificateException, InvalidKeyException, SignatureException,
NoSuchAlgorithmException, NoSuchProviderException NoSuchAlgorithmException, NoSuchProviderException
{
return getSelfCertificate(myname, firstDate, validity, null);
}
// Like above, plus a CertificateExtensions argument, which can be null.
public X509Certificate getSelfCertificate (X500Name myname, Date firstDate,
long validity, CertificateExtensions ext)
throws CertificateException, InvalidKeyException, SignatureException,
NoSuchAlgorithmException, NoSuchProviderException
{ {
X509CertImpl cert; X509CertImpl cert;
Date lastDate; Date lastDate;
@ -248,6 +262,7 @@ public final class CertAndKeyGen {
info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey)); info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
info.set(X509CertInfo.VALIDITY, interval); info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(myname)); info.set(X509CertInfo.ISSUER, new CertificateIssuerName(myname));
if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
cert = new X509CertImpl(info); cert = new X509CertImpl(info);
cert.sign(privateKey, this.sigAlg); cert.sign(privateKey, this.sigAlg);

View file

@ -1518,9 +1518,16 @@ public final class KeyTool {
keypair.generate(keysize); keypair.generate(keysize);
PrivateKey privKey = keypair.getPrivateKey(); PrivateKey privKey = keypair.getPrivateKey();
CertificateExtensions ext = createV3Extensions(
null,
null,
v3ext,
keypair.getPublicKeyAnyway(),
null);
X509Certificate[] chain = new X509Certificate[1]; X509Certificate[] chain = new X509Certificate[1];
chain[0] = keypair.getSelfCertificate( chain[0] = keypair.getSelfCertificate(
x500Name, getStartDate(startDate), validity*24L*60L*60L); x500Name, getStartDate(startDate), validity*24L*60L*60L, ext);
if (verbose) { if (verbose) {
MessageFormat form = new MessageFormat(rb.getString MessageFormat form = new MessageFormat(rb.getString
@ -1537,9 +1544,6 @@ public final class KeyTool {
keyPass = promptForKeyPass(alias, null, storePass); keyPass = promptForKeyPass(alias, null, storePass);
} }
keyStore.setKeyEntry(alias, privKey, keyPass, chain); keyStore.setKeyEntry(alias, privKey, keyPass, chain);
// resign so that -ext are applied.
doSelfCert(alias, null, sigAlgName);
} }
/** /**

View file

@ -524,10 +524,21 @@ public class SwingUtilities2 {
} }
// If we get here we're not printing // If we get here we're not printing
if (g instanceof Graphics2D) {
AATextInfo info = drawTextAntialiased(c); AATextInfo info = drawTextAntialiased(c);
if (info != null && (g instanceof Graphics2D)) {
Graphics2D g2 = (Graphics2D)g; Graphics2D g2 = (Graphics2D)g;
boolean needsTextLayout = ((c != null) &&
(c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
if (needsTextLayout) {
synchronized(charsBufferLock) {
int length = syncCharsBuffer(text);
needsTextLayout = isComplexLayout(charsBuffer, 0, length);
}
}
if (info != null) {
Object oldContrast = null; Object oldContrast = null;
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING); Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
if (info.aaHint != oldAAValue) { if (info.aaHint != oldAAValue) {
@ -545,14 +556,6 @@ public class SwingUtilities2 {
} }
} }
boolean needsTextLayout = ((c != null) &&
(c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
if (needsTextLayout) {
synchronized(charsBufferLock) {
int length = syncCharsBuffer(text);
needsTextLayout = isComplexLayout(charsBuffer, 0, length);
}
}
if (needsTextLayout) { if (needsTextLayout) {
TextLayout layout = createTextLayout(c, text, g2.getFont(), TextLayout layout = createTextLayout(c, text, g2.getFont(),
g2.getFontRenderContext()); g2.getFontRenderContext());
@ -567,12 +570,20 @@ public class SwingUtilities2 {
if (oldContrast != null) { if (oldContrast != null) {
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast); g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);
} }
return;
} }
else {
g.drawString(text, x, y); if (needsTextLayout){
TextLayout layout = createTextLayout(c, text, g2.getFont(),
g2.getFontRenderContext());
layout.draw(g2, x, y);
return;
} }
} }
g.drawString(text, x, y);
}
/** /**
* Draws the string at the specified location underlining the specified * Draws the string at the specified location underlining the specified

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -76,7 +76,7 @@ public class XMLUtils {
} catch (SAXException saxe) { } catch (SAXException saxe) {
throw new InvalidPropertiesFormatException(saxe); throw new InvalidPropertiesFormatException(saxe);
} }
Element propertiesElement = (Element)doc.getChildNodes().item(1); Element propertiesElement = doc.getDocumentElement();
String xmlVersion = propertiesElement.getAttribute("version"); String xmlVersion = propertiesElement.getAttribute("version");
if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
throw new InvalidPropertiesFormatException( throw new InvalidPropertiesFormatException(

View file

@ -1,14 +1,10 @@
To run the Ruler demo: To run the Ruler demo:
java -jar Ruler.jar java -jar TransparentRuler.jar
These instructions assume that this installation's version of the java These instructions assume that this installation's version of the java
command is in your path. If it isn't, then you should either command is in your path. If it isn't, then you should either
specify the complete path to the java command or update your specify the complete path to the java command or update your
PATH environment variable as described in the installation PATH environment variable as described in the installation
instructions for the Java(TM) SE Development Kit. instructions for the Java(TM) SE Development Kit.
KNOWN ISSUES:
Context menu is clipped with the window shape. The issues are:
CR 7027486 JPopupMenu doesn't take window shape into account

View file

@ -1424,7 +1424,8 @@ typedef struct {
*/ */
unsigned int thread_park_blocker : 1; unsigned int thread_park_blocker : 1;
unsigned int post_vm_init_hook_enabled : 1; unsigned int post_vm_init_hook_enabled : 1;
unsigned int : 30; unsigned int pending_list_uses_discovered_field : 1;
unsigned int : 29;
unsigned int : 32; unsigned int : 32;
unsigned int : 32; unsigned int : 32;
} jdk_version_info; } jdk_version_info;

View file

@ -1112,11 +1112,14 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) {
uint size3 = suffix * 3; uint size3 = suffix * 3;
if (suffix == 0) continue; // done with empty string if (suffix == 0) continue; // done with empty string
chars.malloc(size3); chars.malloc(size3);
CHECK;
byte* chp = chars.ptr; byte* chp = chars.ptr;
band saved_band = cp_Utf8_big_chars; band saved_band = cp_Utf8_big_chars;
cp_Utf8_big_chars.readData(suffix); cp_Utf8_big_chars.readData(suffix);
CHECK;
for (int j = 0; j < suffix; j++) { for (int j = 0; j < suffix; j++) {
unsigned short ch = cp_Utf8_big_chars.getInt(); unsigned short ch = cp_Utf8_big_chars.getInt();
CHECK;
chp = store_Utf8_char(chp, ch); chp = store_Utf8_char(chp, ch);
} }
chars.realloc(chp - chars.ptr); chars.realloc(chp - chars.ptr);
@ -1134,10 +1137,12 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) {
CHECK; CHECK;
int prevlen = 0; // previous string length (in chars) int prevlen = 0; // previous string length (in chars)
tmallocs.add(bigbuf.ptr); // free after this block tmallocs.add(bigbuf.ptr); // free after this block
CHECK;
cp_Utf8_prefix.rewind(); cp_Utf8_prefix.rewind();
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
bytes& chars = allsuffixes[i]; bytes& chars = allsuffixes[i];
int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt(); int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
CHECK;
int suffix = (int)chars.len; int suffix = (int)chars.len;
byte* fillp; byte* fillp;
// by induction, the buffer is already filled with the prefix // by induction, the buffer is already filled with the prefix

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -52,7 +52,7 @@ void* must_malloc(size_t size) {
if (msize >= 0 && msize < sizeof(int)) if (msize >= 0 && msize < sizeof(int))
msize = sizeof(int); // see 0xbaadf00d below msize = sizeof(int); // see 0xbaadf00d below
#endif #endif
void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize); void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize);
if (ptr != null) { if (ptr != null) {
memset(ptr, 0, size); memset(ptr, 0, size);
} else { } else {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,7 +33,7 @@ void mtrace(char c, void* ptr, size_t size);
#endif #endif
// overflow management // overflow management
#define OVERFLOW ((size_t)-1) #define OVERFLOW ((uint)-1)
#define PSIZE_MAX (OVERFLOW/2) /* normal size limit */ #define PSIZE_MAX (OVERFLOW/2) /* normal size limit */
inline size_t scale_size(size_t size, size_t scale) { inline size_t scale_size(size_t size, size_t scale) {

View file

@ -101,5 +101,5 @@ JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) {
// Advertise presence of sun.misc.PostVMInitHook: // Advertise presence of sun.misc.PostVMInitHook:
// future optimization: detect if this is enabled. // future optimization: detect if this is enabled.
info->post_vm_init_hook_enabled = 1; info->post_vm_init_hook_enabled = 1;
info->pending_list_uses_discovered_field = 1;
} }

View file

@ -59,13 +59,8 @@ typedef double mlib_d64;
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__) #if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__)
#if defined(__linux__) #include <stdint.h>
#include <stdint.h> /* for uintptr_t */ #include <stddef.h>
#include <malloc.h> /* for ptrdiff_t */
#else
#include <link.h> /* for uintptr_t */
#include <stddef.h> /* for ptrdiff_t */
#endif /* __linux__ */
#ifdef MLIB_OS64BIT #ifdef MLIB_OS64BIT

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -284,7 +284,7 @@ Java_sun_java2d_loops_TransformHelper_Transform
TransformHelperFunc *pHelperFunc; TransformHelperFunc *pHelperFunc;
TransformInterpFunc *pInterpFunc; TransformInterpFunc *pInterpFunc;
jdouble xorig, yorig; jdouble xorig, yorig;
jint numedges; jlong numedges;
jint *pEdges; jint *pEdges;
jint edgebuf[2 + MAXEDGES * 2]; jint edgebuf[2 + MAXEDGES * 2];
union { union {
@ -379,18 +379,43 @@ Java_sun_java2d_loops_TransformHelper_Transform
} }
Region_IntersectBounds(&clipInfo, &dstInfo.bounds); Region_IntersectBounds(&clipInfo, &dstInfo.bounds);
numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1); numedges = (((jlong) dstInfo.bounds.y2) - ((jlong) dstInfo.bounds.y1));
if (numedges > MAXEDGES) { if (numedges <= 0) {
pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges)); pEdges = NULL;
} else if (!JNU_IsNull(env, edgeArray)) {
/*
* Ideally Java should allocate an array large enough, but if
* we ever have a miscommunication about the number of edge
* lines, or if the Java array calculation should overflow to
* a positive number and succeed in allocating an array that
* is too small, we need to verify that it can still hold the
* number of integers that we plan to store to be safe.
*/
jsize edgesize = (*env)->GetArrayLength(env, edgeArray);
/* (edgesize/2 - 1) should avoid any overflow or underflow. */
pEdges = (((edgesize / 2) - 1) >= numedges)
? (*env)->GetPrimitiveArrayCritical(env, edgeArray, NULL)
: NULL;
} else if (numedges > MAXEDGES) {
/* numedges variable (jlong) can be at most ((1<<32)-1) */
/* memsize can overflow a jint, but not a jlong */
jlong memsize = ((numedges * 2) + 2) * sizeof(*pEdges);
pEdges = (memsize == ((size_t) memsize))
? malloc((size_t) memsize)
: NULL;
} else {
pEdges = edgebuf;
}
if (pEdges == NULL) { if (pEdges == NULL) {
if (numedges > 0) {
JNU_ThrowInternalError(env, "Unable to allocate edge list");
}
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
/* edgeArray should already contain zeros for min/maxy */ /* edgeArray should already contain zeros for min/maxy */
return; return;
} }
} else {
pEdges = edgebuf;
}
Transform_GetInfo(env, itxform, &itxInfo); Transform_GetInfo(env, itxform, &itxInfo);
@ -500,14 +525,14 @@ Java_sun_java2d_loops_TransformHelper_Transform
} else { } else {
pEdges[0] = pEdges[1] = 0; pEdges[0] = pEdges[1] = 0;
} }
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
if (!JNU_IsNull(env, edgeArray)) { if (!JNU_IsNull(env, edgeArray)) {
(*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges); (*env)->ReleasePrimitiveArrayCritical(env, edgeArray, pEdges, 0);
} } else if (pEdges != edgebuf) {
if (pEdges != edgebuf) {
free(pEdges); free(pEdges);
} }
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
} }
static void static void

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,8 @@
package java.io; package java.io;
import java.util.concurrent.atomic.AtomicInteger; import java.util.ArrayList;
import java.util.List;
/** /**
* Instances of the file descriptor class serve as an opaque handle * Instances of the file descriptor class serve as an opaque handle
@ -46,12 +47,9 @@ public final class FileDescriptor {
private int fd; private int fd;
/** private Closeable parent;
* A counter for tracking the FIS/FOS/RAF instances that private List<Closeable> otherParents;
* use this FileDescriptor. The FIS/FOS.finalize() will not release private boolean closed;
* the FileDescriptor if it is still under user by a stream.
*/
private AtomicInteger useCount;
/** /**
* Constructs an (invalid) FileDescriptor * Constructs an (invalid) FileDescriptor
@ -59,12 +57,10 @@ public final class FileDescriptor {
*/ */
public /**/ FileDescriptor() { public /**/ FileDescriptor() {
fd = -1; fd = -1;
useCount = new AtomicInteger();
} }
private /* */ FileDescriptor(int fd) { private /* */ FileDescriptor(int fd) {
this.fd = fd; this.fd = fd;
useCount = new AtomicInteger();
} }
/** /**
@ -164,13 +160,67 @@ public final class FileDescriptor {
); );
} }
// package private methods used by FIS, FOS and RAF /*
* Package private methods to track referents.
* If multiple streams point to the same FileDescriptor, we cycle
* through the list of all referents and call close()
*/
int incrementAndGetUseCount() { /**
return useCount.incrementAndGet(); * Attach a Closeable to this FD for tracking.
* parent reference is added to otherParents when
* needed to make closeAll simpler.
*/
synchronized void attach(Closeable c) {
if (parent == null) {
// first caller gets to do this
parent = c;
} else if (otherParents == null) {
otherParents = new ArrayList<>();
otherParents.add(parent);
otherParents.add(c);
} else {
otherParents.add(c);
}
} }
int decrementAndGetUseCount() { /**
return useCount.decrementAndGet(); * Cycle through all Closeables sharing this FD and call
* close() on each one.
*
* The caller closeable gets to call close0().
*/
@SuppressWarnings("try")
synchronized void closeAll(Closeable releaser) throws IOException {
if (!closed) {
closed = true;
IOException ioe = null;
try (Closeable c = releaser) {
if (otherParents != null) {
for (Closeable referent : otherParents) {
try {
referent.close();
} catch(IOException x) {
if (ioe == null) {
ioe = x;
} else {
ioe.addSuppressed(x);
}
}
}
}
} catch(IOException ex) {
/*
* If releaser close() throws IOException
* add other exceptions as suppressed.
*/
if (ioe != null)
ex.addSuppressed(ioe);
ioe = ex;
} finally {
if (ioe != null)
throw ioe;
}
}
} }
} }

View file

@ -466,12 +466,16 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
if (true) { if (true) {
switch(e.getID()) { switch(e.getID()) {
case PaintEvent.UPDATE: case PaintEvent.UPDATE:
if (log.isLoggable(PlatformLogger.FINER)) {
log.finer("XCP coalescePaintEvent : UPDATE : add : x = " + log.finer("XCP coalescePaintEvent : UPDATE : add : x = " +
r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height); r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height);
}
return; return;
case PaintEvent.PAINT: case PaintEvent.PAINT:
if (log.isLoggable(PlatformLogger.FINER)) {
log.finer("XCP coalescePaintEvent : PAINT : add : x = " + log.finer("XCP coalescePaintEvent : PAINT : add : x = " +
r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height); r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height);
}
return; return;
} }
} }
@ -1248,7 +1252,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
* ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify * ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify
*/ */
protected boolean isEventDisabled(XEvent e) { protected boolean isEventDisabled(XEvent e) {
if (enableLog.isLoggable(PlatformLogger.FINEST)) {
enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable")); enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable"));
}
if (!isEnabled()) { if (!isEnabled()) {
switch (e.get_type()) { switch (e.get_type()) {
case XConstants.ButtonPress: case XConstants.ButtonPress:
@ -1258,7 +1264,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
case XConstants.EnterNotify: case XConstants.EnterNotify:
case XConstants.LeaveNotify: case XConstants.LeaveNotify:
case XConstants.MotionNotify: case XConstants.MotionNotify:
if (enableLog.isLoggable(PlatformLogger.FINER)) {
enableLog.finer("Event {0} is disable", e); enableLog.finer("Event {0} is disable", e);
}
return true; return true;
} }
} }

View file

@ -678,7 +678,7 @@ public class WrapperGenerator {
public void writeToString(StructType stp, PrintWriter pw) { public void writeToString(StructType stp, PrintWriter pw) {
int type; int type;
pw.println("\n\n\tString getName() {\n\t\treturn \"" + stp.getName()+ "\"; \n\t}"); pw.println("\n\n\tString getName() {\n\t\treturn \"" + stp.getName()+ "\"; \n\t}");
pw.println("\n\n\tString getFieldsAsString() {\n\t\tString ret=\"\";\n"); pw.println("\n\n\tString getFieldsAsString() {\n\t\tStringBuilder ret = new StringBuilder(" + stp.getNumFields() * 40 + ");\n");
for (Enumeration e = stp.getMembers() ; e.hasMoreElements() ;) { for (Enumeration e = stp.getMembers() ; e.hasMoreElements() ;) {
AtomicType tp = (AtomicType) e.nextElement(); AtomicType tp = (AtomicType) e.nextElement();
@ -688,24 +688,24 @@ public class WrapperGenerator {
if ((name != null) && (name.length() > 0)) if ((name != null) && (name.length() > 0))
{ {
if (type == AtomicType.TYPE_ATOM) { if (type == AtomicType.TYPE_ATOM) {
pw.println("\t\tret += \"\"+\"" + name + " = \" + XAtom.get(get_" + name + "()) +\", \";"); pw.println("\t\tret.append(\"" + name + " = \" ).append( XAtom.get(get_" + name + "()) ).append(\", \");");
} else if (name.equals("type")) { } else if (name.equals("type")) {
pw.println("\t\tret += \"\"+\"type = \" + XlibWrapper.eventToString[get_type()] +\", \";"); pw.println("\t\tret.append(\"type = \").append( XlibWrapper.eventToString[get_type()] ).append(\", \");");
} else if (name.equals("window")){ } else if (name.equals("window")){
pw.println("\t\tret += \"\"+\"window = \" + getWindow(get_window()) + \", \";"); pw.println("\t\tret.append(\"window = \" ).append( getWindow(get_window()) ).append(\", \");");
} else if (type == AtomicType.TYPE_ARRAY) { } else if (type == AtomicType.TYPE_ARRAY) {
pw.print("\t\tret += \"{\""); pw.print("\t\tret.append(\"{\")");
for (int i = 0; i < tp.getArrayLength(); i++) { for (int i = 0; i < tp.getArrayLength(); i++) {
pw.print(" + get_" + name + "(" + i + ") + \" \""); pw.print("\n\t\t.append( get_" + name + "(" + i + ") ).append(\" \")");
} }
pw.println(" + \"}\";"); pw.println(".append( \"}\");");
} else { } else {
pw.println("\t\tret += \"\"+\"" + name +" = \" + get_"+ name+"() +\", \";"); pw.println("\t\tret.append(\"" + name +" = \").append( get_"+ name+"() ).append(\", \");");
} }
} }
} }
pw.println("\t\treturn ret;\n\t}\n\n"); pw.println("\t\treturn ret.toString();\n\t}\n\n");
} }
public void writeStubs(StructType stp, PrintWriter pw) { public void writeStubs(StructType stp, PrintWriter pw) {

View file

@ -38,7 +38,9 @@ import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader; import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Vector; import java.util.Vector;
@ -955,23 +957,49 @@ public class UnixPrintJob implements CancelablePrintJob {
private class PrinterSpooler implements java.security.PrivilegedAction { private class PrinterSpooler implements java.security.PrivilegedAction {
PrintException pex; PrintException pex;
private void handleProcessFailure(final Process failedProcess,
final String[] execCmd, final int result) throws IOException {
try (StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw)) {
pw.append("error=").append(Integer.toString(result));
pw.append(" running:");
for (String arg: execCmd) {
pw.append(" '").append(arg).append("'");
}
try (InputStream is = failedProcess.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
while (br.ready()) {
pw.println();
pw.append("\t\t").append(br.readLine());
}
} finally {
pw.flush();
throw new IOException(sw.toString());
}
}
}
public Object run() { public Object run() {
try {
/**
* Spool to the printer.
*/
if (spoolFile == null || !spoolFile.exists()) { if (spoolFile == null || !spoolFile.exists()) {
pex = new PrintException("No spool file"); pex = new PrintException("No spool file");
notifyEvent(PrintJobEvent.JOB_FAILED); notifyEvent(PrintJobEvent.JOB_FAILED);
return null; return null;
} }
try {
/**
* Spool to the printer.
*/
String fileName = spoolFile.getAbsolutePath(); String fileName = spoolFile.getAbsolutePath();
String execCmd[] = printExecCmd(mDestination, mOptions, String execCmd[] = printExecCmd(mDestination, mOptions,
mNoJobSheet, jobName, copies, fileName); mNoJobSheet, jobName, copies, fileName);
Process process = Runtime.getRuntime().exec(execCmd); Process process = Runtime.getRuntime().exec(execCmd);
process.waitFor(); process.waitFor();
spoolFile.delete(); final int result = process.exitValue();
if (0 != result) {
handleProcessFailure(process, execCmd, result);
}
notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE); notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
} catch (IOException ex) { } catch (IOException ex) {
notifyEvent(PrintJobEvent.JOB_FAILED); notifyEvent(PrintJobEvent.JOB_FAILED);
@ -981,6 +1009,7 @@ public class UnixPrintJob implements CancelablePrintJob {
notifyEvent(PrintJobEvent.JOB_FAILED); notifyEvent(PrintJobEvent.JOB_FAILED);
pex = new PrintException(ie); pex = new PrintException(ie);
} finally { } finally {
spoolFile.delete();
notifyEvent(PrintJobEvent.NO_MORE_EVENTS); notifyEvent(PrintJobEvent.NO_MORE_EVENTS);
} }
return null; return null;

View file

@ -43,8 +43,9 @@
#include "java_net_Inet4AddressImpl.h" #include "java_net_Inet4AddressImpl.h"
/* the initial size of our hostent buffers */ /* the initial size of our hostent buffers */
#define HENT_BUF_SIZE 1024 #ifndef NI_MAXHOST
#define BIG_HENT_BUF_SIZE 10240 /* a jumbo-sized one */ #define NI_MAXHOST 1025
#endif
/************************************************************************ /************************************************************************
* Inet4AddressImpl * Inet4AddressImpl
@ -57,60 +58,36 @@
*/ */
JNIEXPORT jstring JNICALL JNIEXPORT jstring JNICALL
Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) { Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
char hostname[MAXHOSTNAMELEN+1]; char hostname[NI_MAXHOST+1];
hostname[0] = '\0'; hostname[0] = '\0';
if (JVM_GetHostName(hostname, sizeof(hostname))) { if (JVM_GetHostName(hostname, sizeof(hostname))) {
/* Something went wrong, maybe networking is not setup? */ /* Something went wrong, maybe networking is not setup? */
strcpy(hostname, "localhost"); strcpy(hostname, "localhost");
} else { } else {
#ifdef __linux__ struct addrinfo hints, *res;
/* On Linux gethostname() says "host.domain.sun.com". On int error;
* Solaris gethostname() says "host", so extra work is needed.
*/
#else
/* Solaris doesn't want to give us a fully qualified domain name.
* We do a reverse lookup to try and get one. This works
* if DNS occurs before NIS in /etc/resolv.conf, but fails
* if NIS comes first (it still gets only a partial name).
* We use thread-safe system calls.
*/
#endif /* __linux__ */
struct hostent res, res2, *hp;
// these buffers must be pointer-aligned so they are declared
// with pointer type
char *buf[HENT_BUF_SIZE/(sizeof (char *))];
char *buf2[HENT_BUF_SIZE/(sizeof (char *))];
int h_error=0;
// ensure null-terminated hostname[NI_MAXHOST] = '\0';
hostname[MAXHOSTNAMELEN] = '\0'; memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
#ifdef __GLIBC__ error = getaddrinfo(hostname, NULL, &hints, &res);
gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
#else if (error == 0) {/* host is known to name service */
hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error); getnameinfo(res->ai_addr,
#endif res->ai_addrlen,
if (hp) { hostname,
#ifdef __GLIBC__ NI_MAXHOST,
gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET, NULL,
&res2, (char*)buf2, sizeof(buf2), &hp, &h_error); 0,
#else NI_NAMEREQD);
hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
&res2, (char*)buf2, sizeof(buf2), &h_error); /* if getnameinfo fails hostname is still the value
#endif from gethostname */
if (hp) {
/* freeaddrinfo(res);
* If gethostbyaddr_r() found a fully qualified host name,
* returns that name. Otherwise, returns the hostname
* found by gethostname().
*/
char *p = hp->h_name;
if ((strlen(hp->h_name) > strlen(hostname))
&& (strncmp(hostname, hp->h_name, strlen(hostname)) == 0)
&& (*(p + strlen(hostname)) == '.'))
strcpy(hostname, hp->h_name);
}
} }
} }
return (*env)->NewStringUTF(env, hostname); return (*env)->NewStringUTF(env, hostname);
@ -140,14 +117,9 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
jstring host) { jstring host) {
const char *hostname; const char *hostname;
jobjectArray ret = 0; jobjectArray ret = 0;
struct hostent res, *hp = 0; int retLen = 0;
// this buffer must be pointer-aligned so is declared int error = 0;
// with pointer type struct addrinfo hints, *res, *resNew = NULL;
char *buf[HENT_BUF_SIZE/(sizeof (char *))];
/* temporary buffer, on the off chance we need to expand */
char *tmp = NULL;
int h_error=0;
if (!initialized) { if (!initialized) {
ni_iacls = (*env)->FindClass(env, "java/net/InetAddress"); ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
@ -168,6 +140,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE); hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
CHECK_NULL_RETURN(hostname, NULL); CHECK_NULL_RETURN(hostname, NULL);
/* Try once, with our static buffer. */
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
#ifdef __solaris__ #ifdef __solaris__
/* /*
* Workaround for Solaris bug 4160367 - if a hostname contains a * Workaround for Solaris bug 4160367 - if a hostname contains a
@ -181,69 +158,93 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
} }
#endif #endif
/* Try once, with our static buffer. */ error = getaddrinfo(hostname, NULL, &hints, &res);
#ifdef __GLIBC__
gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
#else
hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
#endif
/* With the re-entrant system calls, it's possible that the buffer if (error) {
* we pass to it is not large enough to hold an exceptionally /* report error */
* large DNS entry. This is signaled by errno->ERANGE. We try once ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
* more, with a very big size. JNU_ReleaseStringPlatformChars(env, host, hostname);
*/ return NULL;
if (hp == NULL && errno == ERANGE) { } else {
if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
#ifdef __GLIBC__
gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
&hp, &h_error);
#else
hp = gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
&h_error);
#endif
}
}
if (hp != NULL) {
struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
int i = 0; int i = 0;
struct addrinfo *itr, *last = NULL, *iterator = res;
while (*addrp != (struct in_addr *) 0) { while (iterator != NULL) {
i++; // remove the duplicate one
addrp++; int skip = 0;
itr = resNew;
while (itr != NULL) {
struct sockaddr_in *addr1, *addr2;
addr1 = (struct sockaddr_in *)iterator->ai_addr;
addr2 = (struct sockaddr_in *)itr->ai_addr;
if (addr1->sin_addr.s_addr ==
addr2->sin_addr.s_addr) {
skip = 1;
break;
}
itr = itr->ai_next;
} }
ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL); if (!skip) {
struct addrinfo *next
= (struct addrinfo*) malloc(sizeof(struct addrinfo));
if (!next) {
JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
ret = NULL;
goto cleanupAndReturn;
}
memcpy(next, iterator, sizeof(struct addrinfo));
next->ai_next = NULL;
if (resNew == NULL) {
resNew = next;
} else {
last->ai_next = next;
}
last = next;
i++;
}
iterator = iterator->ai_next;
}
retLen = i;
iterator = resNew;
ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
if (IS_NULL(ret)) { if (IS_NULL(ret)) {
/* we may have memory to free at the end of this */ /* we may have memory to free at the end of this */
goto cleanupAndReturn; goto cleanupAndReturn;
} }
addrp = (struct in_addr **) hp->h_addr_list;
i = 0; i = 0;
while (*addrp) { while (iterator != NULL) {
jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
if (IS_NULL(iaObj)) { if (IS_NULL(iaObj)) {
ret = NULL; ret = NULL;
goto cleanupAndReturn; goto cleanupAndReturn;
} }
(*env)->SetIntField(env, iaObj, ni_iaaddressID, (*env)->SetIntField(env, iaObj, ni_iaaddressID,
ntohl((*addrp)->s_addr)); ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
(*env)->SetObjectField(env, iaObj, ni_iahostID, host); (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
(*env)->SetObjectArrayElement(env, ret, i, iaObj); (*env)->SetObjectArrayElement(env, ret, i++, iaObj);
addrp++; iterator = iterator->ai_next;
i++;
} }
} else {
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
(char *)hostname);
ret = NULL;
} }
cleanupAndReturn: cleanupAndReturn:
JNU_ReleaseStringPlatformChars(env, host, hostname); {
if (tmp != NULL) { struct addrinfo *iterator, *tmp;
iterator = resNew;
while (iterator != NULL) {
tmp = iterator;
iterator = iterator->ai_next;
free(tmp); free(tmp);
} }
JNU_ReleaseStringPlatformChars(env, host, hostname);
}
freeaddrinfo(res);
return ret; return ret;
} }
@ -256,63 +257,38 @@ JNIEXPORT jstring JNICALL
Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this, Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
jbyteArray addrArray) { jbyteArray addrArray) {
jstring ret = NULL; jstring ret = NULL;
jint addr;
struct hostent hent, *hp = 0;
// this buffer must be pointer-aligned so is declared
// with pointer type
char *buf[HENT_BUF_SIZE/(sizeof (char *))];
int h_error = 0;
char *tmp = NULL;
/* char host[NI_MAXHOST+1];
* We are careful here to use the reentrant version of int error = 0;
* gethostbyname because at the Java level this routine is not int len = 0;
* protected by any synchronization.
*
* Still keeping the reentrant platform dependent calls temporarily
* We should probably conform to one interface later.
*
*/
jbyte caddr[4]; jbyte caddr[4];
struct sockaddr_in him4;
struct sockaddr *sa;
jint addr;
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr); (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
addr = ((caddr[0]<<24) & 0xff000000); addr = ((caddr[0]<<24) & 0xff000000);
addr |= ((caddr[1] <<16) & 0xff0000); addr |= ((caddr[1] <<16) & 0xff0000);
addr |= ((caddr[2] <<8) & 0xff00); addr |= ((caddr[2] <<8) & 0xff00);
addr |= (caddr[3] & 0xff); addr |= (caddr[3] & 0xff);
addr = htonl(addr); memset((void *) &him4, 0, sizeof(him4));
#ifdef __GLIBC__ him4.sin_addr.s_addr = (uint32_t) htonl(addr);
gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent, him4.sin_family = AF_INET;
(char*)buf, sizeof(buf), &hp, &h_error); sa = (struct sockaddr *) &him4;
#else len = sizeof(him4);
hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
(char*)buf, sizeof(buf), &h_error); error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
#endif NI_NAMEREQD);
/* With the re-entrant system calls, it's possible that the buffer
* we pass to it is not large enough to hold an exceptionally if (!error) {
* large DNS entry. This is signaled by errno->ERANGE. We try once ret = (*env)->NewStringUTF(env, host);
* more, with a very big size.
*/
if (hp == NULL && errno == ERANGE) {
if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
#ifdef __GLIBC__
gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
&hent, tmp, BIG_HENT_BUF_SIZE, &hp, &h_error);
#else
hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
&hent, tmp, BIG_HENT_BUF_SIZE, &h_error);
#endif
} else {
JNU_ThrowOutOfMemoryError(env, "getHostByAddr");
} }
}
if (hp == NULL) { if (ret == NULL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL); JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
} else {
ret = (*env)->NewStringUTF(env, hp->h_name);
}
if (tmp) {
free(tmp);
} }
return ret; return ret;
} }

View file

@ -82,19 +82,18 @@ Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
* We use thread-safe system calls. * We use thread-safe system calls.
*/ */
#ifdef AF_INET6 #ifdef AF_INET6
if (NET_addrtransAvailable()) {
struct addrinfo hints, *res; struct addrinfo hints, *res;
int error; int error;
bzero(&hints, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME; hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res); error = getaddrinfo(hostname, NULL, &hints, &res);
if (error == 0) { if (error == 0) {
/* host is known to name service */ /* host is known to name service */
error = (*getnameinfo_ptr)(res->ai_addr, error = getnameinfo(res->ai_addr,
res->ai_addrlen, res->ai_addrlen,
hostname, hostname,
NI_MAXHOST, NI_MAXHOST,
@ -105,8 +104,7 @@ Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
/* if getnameinfo fails hostname is still the value /* if getnameinfo fails hostname is still the value
from gethostname */ from gethostname */
(*freeaddrinfo_ptr)(res); freeaddrinfo(res);
}
} }
#endif /* AF_INET6 */ #endif /* AF_INET6 */
#endif /* __linux__ */ #endif /* __linux__ */
@ -173,7 +171,6 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
CHECK_NULL_RETURN(hostname, NULL); CHECK_NULL_RETURN(hostname, NULL);
#ifdef AF_INET6 #ifdef AF_INET6
if (NET_addrtransAvailable()) {
static jfieldID ia_preferIPv6AddressID; static jfieldID ia_preferIPv6AddressID;
if (ia_preferIPv6AddressID == NULL) { if (ia_preferIPv6AddressID == NULL) {
jclass c = (*env)->FindClass(env,"java/net/InetAddress"); jclass c = (*env)->FindClass(env,"java/net/InetAddress");
@ -191,7 +188,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
= (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID); = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
/* Try once, with our static buffer. */ /* Try once, with our static buffer. */
bzero(&hints, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME; hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
@ -208,7 +205,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
} }
#endif #endif
error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res); error = getaddrinfo(hostname, NULL, &hints, &res);
if (error) { if (error) {
/* report error */ /* report error */
@ -355,9 +352,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
iterator = iterator->ai_next; iterator = iterator->ai_next;
} }
} }
}
cleanupAndReturn: cleanupAndReturn:
{ {
struct addrinfo *iterator, *tmp; struct addrinfo *iterator, *tmp;
iterator = resNew; iterator = resNew;
@ -369,8 +365,7 @@ cleanupAndReturn:
JNU_ReleaseStringPlatformChars(env, host, hostname); JNU_ReleaseStringPlatformChars(env, host, hostname);
} }
if (NET_addrtransAvailable()) freeaddrinfo(res);
(*freeaddrinfo_ptr)(res);
#endif /* AF_INET6 */ #endif /* AF_INET6 */
return ret; return ret;
@ -393,7 +388,6 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
int len = 0; int len = 0;
jbyte caddr[16]; jbyte caddr[16];
if (NET_addrtransAvailable()) {
struct sockaddr_in him4; struct sockaddr_in him4;
struct sockaddr_in6 him6; struct sockaddr_in6 him6;
struct sockaddr *sa; struct sockaddr *sa;
@ -425,13 +419,12 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
len = sizeof(him6) ; len = sizeof(him6) ;
} }
error = (*getnameinfo_ptr)(sa, len, host, NI_MAXHOST, NULL, 0, error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
NI_NAMEREQD); NI_NAMEREQD);
if (!error) { if (!error) {
ret = (*env)->NewStringUTF(env, host); ret = (*env)->NewStringUTF(env, host);
} }
}
#endif /* AF_INET6 */ #endif /* AF_INET6 */
if (ret == NULL) { if (ret == NULL) {

View file

@ -377,37 +377,12 @@ jint IPv6_supported()
* we should also check if the APIs are available. * we should also check if the APIs are available.
*/ */
ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton"); ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton");
close(fd);
if (ipv6_fn == NULL ) { if (ipv6_fn == NULL ) {
close(fd);
return JNI_FALSE; return JNI_FALSE;
} } else {
/*
* We've got the library, let's get the pointers to some
* IPV6 specific functions. We have to do that because, at least
* on Solaris we may build on a system without IPV6 networking
* libraries, therefore we can't have a hard link to these
* functions.
*/
getaddrinfo_ptr = (getaddrinfo_f)
JVM_FindLibraryEntry(RTLD_DEFAULT, "getaddrinfo");
freeaddrinfo_ptr = (freeaddrinfo_f)
JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
gai_strerror_ptr = (gai_strerror_f)
JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
getnameinfo_ptr = (getnameinfo_f)
JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
/* We need all 3 of them */
getaddrinfo_ptr = NULL;
}
close(fd);
return JNI_TRUE; return JNI_TRUE;
}
#endif /* AF_INET6 */ #endif /* AF_INET6 */
} }
@ -920,10 +895,6 @@ NET_IsEqual(jbyte* caddr1, jbyte* caddr2) {
return 1; return 1;
} }
jboolean NET_addrtransAvailable() {
return (jboolean)(getaddrinfo_ptr != NULL);
}
/* /*
* Map the Java level socket option to the platform specific * Map the Java level socket option to the platform specific
* level and option name. * level and option name.

View file

@ -102,10 +102,6 @@ void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
const char* hostname, const char* hostname,
int gai_error); int gai_error);
/* do we have address translation support */
extern jboolean NET_addrtransAvailable();
#define NET_WAIT_READ 0x01 #define NET_WAIT_READ 0x01
#define NET_WAIT_WRITE 0x02 #define NET_WAIT_WRITE 0x02
#define NET_WAIT_CONNECT 0x04 #define NET_WAIT_CONNECT 0x04

View file

@ -32,7 +32,7 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <inttypes.h> #include <inttypes.h>

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,8 @@
package java.io; package java.io;
import java.util.concurrent.atomic.AtomicInteger; import java.util.ArrayList;
import java.util.List;
/** /**
* Instances of the file descriptor class serve as an opaque handle * Instances of the file descriptor class serve as an opaque handle
@ -45,13 +46,9 @@ public final class FileDescriptor {
private long handle; private long handle;
/** private Closeable parent;
* A use counter for tracking the FIS/FOS/RAF instances that private List<Closeable> otherParents;
* use this FileDescriptor. The FIS/FOS.finalize() will not release private boolean closed;
* the FileDescriptor if it is still under use by any stream.
*/
private AtomicInteger useCount;
/** /**
* Constructs an (invalid) FileDescriptor * Constructs an (invalid) FileDescriptor
@ -60,7 +57,6 @@ public final class FileDescriptor {
public /**/ FileDescriptor() { public /**/ FileDescriptor() {
fd = -1; fd = -1;
handle = -1; handle = -1;
useCount = new AtomicInteger();
} }
static { static {
@ -168,13 +164,67 @@ public final class FileDescriptor {
return desc; return desc;
} }
// package private methods used by FIS, FOS and RAF. /*
* Package private methods to track referents.
* If multiple streams point to the same FileDescriptor, we cycle
* through the list of all referents and call close()
*/
int incrementAndGetUseCount() { /**
return useCount.incrementAndGet(); * Attach a Closeable to this FD for tracking.
* parent reference is added to otherParents when
* needed to make closeAll simpler.
*/
synchronized void attach(Closeable c) {
if (parent == null) {
// first caller gets to do this
parent = c;
} else if (otherParents == null) {
otherParents = new ArrayList<>();
otherParents.add(parent);
otherParents.add(c);
} else {
otherParents.add(c);
}
} }
int decrementAndGetUseCount() { /**
return useCount.decrementAndGet(); * Cycle through all Closeables sharing this FD and call
* close() on each one.
*
* The caller closeable gets to call close0().
*/
@SuppressWarnings("try")
synchronized void closeAll(Closeable releaser) throws IOException {
if (!closed) {
closed = true;
IOException ioe = null;
try (Closeable c = releaser) {
if (otherParents != null) {
for (Closeable referent : otherParents) {
try {
referent.close();
} catch(IOException x) {
if (ioe == null) {
ioe = x;
} else {
ioe.addSuppressed(x);
}
}
}
}
} catch(IOException ex) {
/*
* If releaser close() throws IOException
* add other exceptions as suppressed.
*/
if (ioe != null)
ex.addSuppressed(ioe);
ioe = ex;
} finally {
if (ioe != null)
throw ioe;
}
}
} }
} }

View file

@ -60,10 +60,11 @@ final class ProcessImpl extends Process {
throws IOException throws IOException
{ {
if (append) { if (append) {
String path = f.getPath();
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) if (sm != null)
sm.checkWrite(f.getPath()); sm.checkWrite(path);
long handle = openForAtomicAppend(f.getPath()); long handle = openForAtomicAppend(path);
final FileDescriptor fd = new FileDescriptor(); final FileDescriptor fd = new FileDescriptor();
fdAccess.setHandle(fd, handle); fdAccess.setHandle(fd, handle);
return AccessController.doPrivileged( return AccessController.doPrivileged(

View file

@ -314,7 +314,7 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
void socketSetOption(int cmd, boolean on, Object value) void socketSetOption(int cmd, boolean on, Object value)
throws SocketException { throws SocketException {
socketSetOption(cmd, on, value); impl.socketSetOption(cmd, on, value);
} }
int socketGetOption(int opt, Object iaContainerObj) throws SocketException { int socketGetOption(int opt, Object iaContainerObj) throws SocketException {

Some files were not shown because too many files have changed in this diff Show more