mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 10:34:38 +02:00
Merge
This commit is contained in:
commit
66ebef88a0
209 changed files with 8260 additions and 3291 deletions
2
.hgtags
2
.hgtags
|
@ -134,3 +134,5 @@ fbf3cabc9e3bb1fcf710941d777cb0400505fbe6 jdk8-b09
|
|||
f651ce87127980c58e3599daba964eba2f3b4026 jdk8-b10
|
||||
cc1f5ce8e504d350e0b0c28c5f84333f8d540132 jdk8-b11
|
||||
86db042b3385c338e17f7664447fdc7d406dd19e jdk8-b12
|
||||
4cc0ef72c812943743ef4765f1100e2fbe2b1a08 jdk8-b13
|
||||
9ffaa48dbfb0f5936c2b789867d0785faec7071d jdk8-b14
|
||||
|
|
|
@ -134,3 +134,5 @@ fb1bc13260d76447e269e843859eb593fe2a8ab2 jdk8-b08
|
|||
a6c4c248e8fa350c35014fa94bab5ac1a1ac3299 jdk8-b10
|
||||
1defbc57940a56f0aa41e9dee87b71e8c8b71103 jdk8-b11
|
||||
8e2104d565baee473895d5eba20e39f85ab4bf9f jdk8-b12
|
||||
26fb81a1e9ceb9baffba216acd9ded62e9e9d5ab jdk8-b13
|
||||
23aa7f2c80a2fa354c80decf03e7c2018177ef4e jdk8-b14
|
||||
|
|
|
@ -134,3 +134,5 @@ a891732c1a83082177ff7a4cf1506068d9cc0a47 jdk8-b09
|
|||
cda87f7fefcee3b89742a57ce5ad9b03a54c210d jdk8-b10
|
||||
0199e4fef5cc2bd234c65b93220459ef7a3bb3b1 jdk8-b11
|
||||
31d70911b712c6b4e580a3110363d5f044cfed7a jdk8-b12
|
||||
5b9d9b839d3d7fe02347827221c97c6d242a6f96 jdk8-b13
|
||||
e59c47de1ad8982ff3b0e843773a6902b36c2337 jdk8-b14
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -423,6 +423,13 @@ public abstract class CDRInputStream
|
|||
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() {
|
||||
return impl.getBufferLength();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
int bbHash = System.identityHashCode(bbwi.byteBuffer);
|
||||
MessageMediator messageMediator = parent.getMessageMediator();
|
||||
if (messageMediator != null)
|
||||
{
|
||||
|
@ -2420,19 +2419,12 @@ public class CDRInputStream_1_0 extends CDRInputStreamBase
|
|||
(CDROutputObject)messageMediator.getOutputObject();
|
||||
if (outputObj != null)
|
||||
{
|
||||
ByteBuffer outputBb = outputObj.getByteBuffer();
|
||||
|
||||
int oBbHash = 0;
|
||||
if (outputBb != null)
|
||||
if (outputObj.isSharing(getByteBuffer()))
|
||||
{
|
||||
oBbHash = System.identityHashCode(outputBb);
|
||||
if (bbHash == oBbHash) // shared?
|
||||
{
|
||||
// Set OutputStream's ByteBuffer and bbwi to null
|
||||
// so its ByteBuffer cannot be released to the pool
|
||||
outputObj.setByteBuffer(null);
|
||||
outputObj.setByteBufferWithInfo(null);
|
||||
}
|
||||
// Set OutputStream's ByteBuffer and bbwi to null
|
||||
// so its ByteBuffer cannot be released to the pool
|
||||
outputObj.setByteBuffer(null);
|
||||
outputObj.setByteBufferWithInfo(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -357,6 +357,13 @@ public abstract class CDROutputStream
|
|||
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() {
|
||||
return impl.isLittleEndian();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
int bbHash = System.identityHashCode(bbwi.byteBuffer);
|
||||
MessageMediator messageMediator = parent.getMessageMediator();
|
||||
if (messageMediator != null)
|
||||
{
|
||||
|
@ -1910,19 +1909,12 @@ public class CDROutputStream_1_0 extends CDROutputStreamBase
|
|||
(CDRInputObject)messageMediator.getInputObject();
|
||||
if (inputObj != null)
|
||||
{
|
||||
ByteBuffer inputBb = inputObj.getByteBuffer();
|
||||
|
||||
int iBbHash = 0;
|
||||
if (inputBb != null)
|
||||
if (inputObj.isSharing(getByteBuffer()))
|
||||
{
|
||||
iBbHash = System.identityHashCode(inputBb);
|
||||
if (bbHash == iBbHash) // shared?
|
||||
{
|
||||
// Set InputStream's ByteBuffer and bbwi to null
|
||||
// so its ByteBuffer cannot be released to the pool
|
||||
inputObj.setByteBuffer(null);
|
||||
inputObj.setByteBufferWithInfo(null);
|
||||
}
|
||||
// Set InputStream's ByteBuffer and bbwi to null
|
||||
// so its ByteBuffer cannot be released to the pool
|
||||
inputObj.setByteBuffer(null);
|
||||
inputObj.setByteBufferWithInfo(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -2243,6 +2243,10 @@ public class IIOPInputStream
|
|||
}
|
||||
|
||||
try {
|
||||
Class fieldCl = fields[i].getClazz();
|
||||
if (objectValue != null && !fieldCl.isInstance(objectValue)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
bridge.putObject( o, fields[i].getFieldID(), objectValue ) ;
|
||||
// reflective code: fields[i].getField().set( o, objectValue ) ;
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
@ -2553,6 +2557,10 @@ public class IIOPInputStream
|
|||
{
|
||||
try {
|
||||
Field fld = c.getDeclaredField( fieldName ) ;
|
||||
Class fieldCl = fld.getType();
|
||||
if(v != null && !fieldCl.isInstance(v)) {
|
||||
throw new Exception();
|
||||
}
|
||||
long key = bridge.objectFieldOffset( fld ) ;
|
||||
bridge.putObject( o, key, v ) ;
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -197,3 +197,6 @@ d815de2e85e511b7deab2a83cf80c0224d011da9 jdk8-b10
|
|||
6534482ff68ad79066dfe15dfb6d8905f09681bd hs23-b04
|
||||
1d3900713a67a0a39faf4e12c9c158d55aebef87 jdk8-b12
|
||||
3e609627e780736f372eb14d29bb9b5e53b21fbf hs23-b05
|
||||
b92ca8e229d29004f840c67e620833d23a346761 jdk8-b13
|
||||
088d09a130ff02d8f5f05e92256baabe412f0439 jdk8-b14
|
||||
6c2a55d4902f202e1c2de1df17b7da083a2c31e8 hs23-b06
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
# The makefiles are split this way so that "make foo" will run faster by not
|
||||
# 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/altsrc.make
|
||||
|
||||
|
@ -159,8 +162,15 @@ ifndef HOTSPOT_VM_DISTRO
|
|||
endif
|
||||
endif
|
||||
|
||||
# MACOSX FIXME: we should be able to run test_gamma (see MACOSX_PORT-214)
|
||||
ifdef ALWAYS_PASS_TEST_GAMMA
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
# 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';
|
||||
else
|
||||
TEST_GAMMA_STATUS=
|
||||
|
|
|
@ -37,11 +37,24 @@ include $(GAMMADIR)/make/sa.files
|
|||
TOPDIR = $(shell echo `pwd`)
|
||||
GENERATED = $(TOPDIR)/../generated
|
||||
|
||||
# tools.jar is needed by the JDI - SA binding
|
||||
ifeq ($(SA_APPLE_BOOT_JAVA),true)
|
||||
SA_CLASSPATH = $(BOOT_JAVA_HOME)/bundle/Classes/classes.jar
|
||||
# SA-JDI depends on the standard JDI classes.
|
||||
# Default SA_CLASSPATH location:
|
||||
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
|
||||
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
|
||||
|
||||
# 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"; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(QUIETLY) if [ ! -f $(SA_CLASSPATH) -a ! -d $(MODULELIB_PATH) ] ; then \
|
||||
echo "Missing $(SA_CLASSPATH) file. Use 1.6.0 or later version of JDK";\
|
||||
$(QUIETLY) if [ ! -f "$(SA_CLASSPATH)" -a ! -d $(MODULELIB_PATH) ] ; then \
|
||||
echo "Cannot find JDI classes. Use 1.6.0 or later version of JDK."; \
|
||||
echo ""; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
|
|
@ -134,3 +134,5 @@ de4794dd69c48b08029d158a972993ff9d5627df jdk8-b08
|
|||
d21a4d5141c04bc9e88f2c0253121d449b66d667 jdk8-b10
|
||||
d1b7a4f6dd2065fdeafbcdfd9dcc0072da8c6881 jdk8-b11
|
||||
ca977d167697a561c04894187fc1c4d927582ffa jdk8-b12
|
||||
bcc739229f6384786c7ac0b52c1822c85674dcf1 jdk8-b13
|
||||
9d0c9d638757cb09de18933b946fa04b4f3fb94f jdk8-b14
|
||||
|
|
|
@ -134,3 +134,5 @@ acffff22a9465005e8eb206224fae9f2ea4fd469 jdk8-b06
|
|||
8e7fdc8e3c758644ca6d0fd70bb255e9d2e64cda jdk8-b10
|
||||
a12ab897a249feb7859a6e6cd84b49411f4c06ac jdk8-b11
|
||||
e6eed2ff5d5f62bdc815beb5276d23347600c760 jdk8-b12
|
||||
adf2a6b5fde14090beb9ebc40c4114132ddee731 jdk8-b13
|
||||
54c4bf4b83ecc191351747d5d28da849d34c0243 jdk8-b14
|
||||
|
|
|
@ -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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,15 +25,15 @@
|
|||
|
||||
drops.master.copy.base=${drops.dir}
|
||||
|
||||
jaxws_src.bundle.name=jdk7-jaxws2_2_4-b03-2011_05_27.zip
|
||||
jaxws_src.bundle.md5.checksum=2f5b829ade70f67fe272d0b322e3e702
|
||||
jaxws_src.bundle.name=jdk8-jaxws2_2_4-b01-2011_07_22.zip
|
||||
jaxws_src.bundle.md5.checksum=f64bedd3c512e6b1ca265fda2feb0905
|
||||
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.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.master.bundle.dir=${drops.master.copy.base}
|
||||
|
|
|
@ -134,3 +134,5 @@ f1ec21b8142168ff40f3278d2f6b5fe4bd5f3b26 jdk8-b09
|
|||
4788745572ef2bde34924ef34e7e4d55ba07e979 jdk8-b10
|
||||
7ab0d613cd1a271a9763ffb894dc1f0a5b95a7e4 jdk8-b11
|
||||
09fd2067f715e4505c44b01c301258a4e8f8964e jdk8-b12
|
||||
4cb2e8679b27432854690cb688ea06d3b2d8e008 jdk8-b13
|
||||
99632935785e2038b2fc836da9f2ede69dea294b jdk8-b14
|
||||
|
|
|
@ -71,7 +71,7 @@ include $(BUILDDIR)/common/internal/ImportComponents.gmk
|
|||
ifeq ($(ARCH_DATA_MODEL),64)
|
||||
MAX_VM_MEMORY = 1024
|
||||
else
|
||||
MAX_VM_MEMORY = 512
|
||||
MAX_VM_MEMORY = 612
|
||||
endif
|
||||
|
||||
# List of all possible directories for javadoc to look for sources
|
||||
|
|
|
@ -232,6 +232,7 @@ FILES_src = \
|
|||
sun/nio/cs/UTF_16BE.java \
|
||||
sun/nio/cs/UTF_16LE.java \
|
||||
sun/nio/cs/UTF_8.java \
|
||||
sun/nio/cs/CESU_8.java \
|
||||
sun/nio/cs/Unicode.java \
|
||||
sun/nio/cs/UnicodeDecoder.java \
|
||||
sun/nio/cs/UnicodeEncoder.java \
|
||||
|
|
|
@ -28,6 +28,7 @@ PACKAGE = sun.net
|
|||
PRODUCT = sun
|
||||
SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true
|
||||
SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true
|
||||
SUBDIRS_MAKEFLAGS += JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation,-path
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
|
||||
SUBDIRS = others spi
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -179,6 +179,12 @@ class HttpsURLConnection extends HttpURLConnection
|
|||
throw new IllegalArgumentException(
|
||||
"no SSLSocketFactory specified");
|
||||
}
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkSetFactory();
|
||||
}
|
||||
|
||||
sslSocketFactory = sf;
|
||||
}
|
||||
|
||||
|
|
|
@ -250,6 +250,8 @@ public class IdResolver {
|
|||
int index=s==null ? elementIndex : names.indexOf(n.getNamespaceURI());
|
||||
index=(index<0) ? namesLength : index;
|
||||
String name=n.getLocalName();
|
||||
if (name == null)
|
||||
name = n.getName();
|
||||
if (name.length()>2)
|
||||
continue;
|
||||
String value=n.getNodeValue();
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,6 +25,7 @@
|
|||
package java.awt;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import sun.awt.AppContext;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -66,9 +67,6 @@ import java.lang.reflect.Field;
|
|||
public class AWTKeyStroke implements Serializable {
|
||||
static final long serialVersionUID = -6430539691155161871L;
|
||||
|
||||
private static Map cache;
|
||||
private static AWTKeyStroke cacheKey;
|
||||
private static Constructor ctor = getCtor(AWTKeyStroke.class);
|
||||
private static Map modifierKeywords;
|
||||
/**
|
||||
* 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;
|
||||
|
||||
//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 int keyCode = KeyEvent.VK_UNDEFINED;
|
||||
private int modifiers;
|
||||
|
@ -164,9 +181,12 @@ public class AWTKeyStroke implements Serializable {
|
|||
if (subclass == null) {
|
||||
throw new IllegalArgumentException("subclass cannot be null");
|
||||
}
|
||||
if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) {
|
||||
// Already registered
|
||||
return;
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
Class keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
|
||||
if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
|
||||
// Already registered
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
|
||||
throw new ClassCastException("subclass is not derived from AWTKeyStroke");
|
||||
|
@ -197,9 +217,9 @@ public class AWTKeyStroke implements Serializable {
|
|||
}
|
||||
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
AWTKeyStroke.ctor = ctor;
|
||||
cache = null;
|
||||
cacheKey = null;
|
||||
AppContext.getAppContext().put(AWTKeyStroke.class, subclass);
|
||||
AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY);
|
||||
AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,13 +249,19 @@ public class AWTKeyStroke implements Serializable {
|
|||
private static synchronized AWTKeyStroke getCachedStroke
|
||||
(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) {
|
||||
cache = new HashMap();
|
||||
AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache);
|
||||
}
|
||||
|
||||
if (cacheKey == null) {
|
||||
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) {
|
||||
assert(false);
|
||||
} catch (IllegalAccessException e) {
|
||||
|
@ -253,9 +279,8 @@ public class AWTKeyStroke implements Serializable {
|
|||
if (stroke == null) {
|
||||
stroke = cacheKey;
|
||||
cache.put(stroke, stroke);
|
||||
cacheKey = null;
|
||||
AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
|
||||
}
|
||||
|
||||
return stroke;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ class FileInputStream extends InputStream
|
|||
throw new NullPointerException();
|
||||
}
|
||||
fd = new FileDescriptor();
|
||||
fd.incrementAndGetUseCount();
|
||||
fd.attach(this);
|
||||
open(name);
|
||||
}
|
||||
|
||||
|
@ -164,10 +164,9 @@ class FileInputStream extends InputStream
|
|||
|
||||
/*
|
||||
* FileDescriptor is being shared by streams.
|
||||
* Ensure that it's GC'ed only when all the streams/channels are done
|
||||
* using it.
|
||||
* Register this stream with FileDescriptor tracker.
|
||||
*/
|
||||
fd.incrementAndGetUseCount();
|
||||
fd.attach(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -294,27 +293,14 @@ class FileInputStream extends InputStream
|
|||
closed = true;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrement the FD use count associated with this stream
|
||||
*/
|
||||
int useCount = fd.decrementAndGetUseCount();
|
||||
|
||||
/*
|
||||
* If FileDescriptor is still in use by another stream, we
|
||||
* will not close it.
|
||||
*/
|
||||
if (useCount <= 0) {
|
||||
close0();
|
||||
}
|
||||
fd.closeAll(new Closeable() {
|
||||
public void close() throws IOException {
|
||||
close0();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -328,7 +314,9 @@ class FileInputStream extends InputStream
|
|||
* @see java.io.FileDescriptor
|
||||
*/
|
||||
public final FileDescriptor getFD() throws IOException {
|
||||
if (fd != null) return fd;
|
||||
if (fd != null) {
|
||||
return fd;
|
||||
}
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
|
@ -352,13 +340,6 @@ class FileInputStream extends InputStream
|
|||
synchronized (this) {
|
||||
if (channel == null) {
|
||||
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;
|
||||
}
|
||||
|
@ -381,7 +362,12 @@ class FileInputStream extends InputStream
|
|||
*/
|
||||
protected void finalize() throws IOException {
|
||||
if ((fd != null) && (fd != FileDescriptor.in)) {
|
||||
close();
|
||||
/* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,9 +197,9 @@ class FileOutputStream extends OutputStream
|
|||
throw new NullPointerException();
|
||||
}
|
||||
this.fd = new FileDescriptor();
|
||||
fd.attach(this);
|
||||
this.append = append;
|
||||
|
||||
fd.incrementAndGetUseCount();
|
||||
open(name, append);
|
||||
}
|
||||
|
||||
|
@ -237,12 +237,7 @@ class FileOutputStream extends OutputStream
|
|||
this.fd = fdObj;
|
||||
this.append = false;
|
||||
|
||||
/*
|
||||
* FileDescriptor is being shared by streams.
|
||||
* Ensure that it's GC'ed only when all the streams/channels are done
|
||||
* using it.
|
||||
*/
|
||||
fd.incrementAndGetUseCount();
|
||||
fd.attach(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,27 +326,14 @@ class FileOutputStream extends OutputStream
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrement FD use count associated with this stream
|
||||
*/
|
||||
int useCount = fd.decrementAndGetUseCount();
|
||||
|
||||
/*
|
||||
* If FileDescriptor is still in use by another stream, we
|
||||
* will not close it.
|
||||
*/
|
||||
if (useCount <= 0) {
|
||||
close0();
|
||||
}
|
||||
fd.closeAll(new Closeable() {
|
||||
public void close() throws IOException {
|
||||
close0();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -365,7 +347,9 @@ class FileOutputStream extends OutputStream
|
|||
* @see java.io.FileDescriptor
|
||||
*/
|
||||
public final FileDescriptor getFD() throws IOException {
|
||||
if (fd != null) return fd;
|
||||
if (fd != null) {
|
||||
return fd;
|
||||
}
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
|
@ -390,13 +374,6 @@ class FileOutputStream extends OutputStream
|
|||
synchronized (this) {
|
||||
if (channel == null) {
|
||||
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;
|
||||
}
|
||||
|
@ -415,7 +392,12 @@ class FileOutputStream extends OutputStream
|
|||
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
|
||||
flush();
|
||||
} else {
|
||||
close();
|
||||
/* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,10 +44,9 @@ package java.io;
|
|||
*/
|
||||
public abstract class InputStream implements Closeable {
|
||||
|
||||
// SKIP_BUFFER_SIZE is used to determine the size of skipBuffer
|
||||
private static final int SKIP_BUFFER_SIZE = 2048;
|
||||
// skipBuffer is initialized in skip(long), if needed.
|
||||
private static byte[] skipBuffer;
|
||||
// MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
|
||||
// use when skipping.
|
||||
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
int nr;
|
||||
if (skipBuffer == null)
|
||||
skipBuffer = new byte[SKIP_BUFFER_SIZE];
|
||||
|
||||
byte[] localSkipBuffer = skipBuffer;
|
||||
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
|
||||
byte[] skipBuffer = new byte[size];
|
||||
while (remaining > 0) {
|
||||
nr = read(localSkipBuffer, 0,
|
||||
(int) Math.min(SKIP_BUFFER_SIZE, remaining));
|
||||
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
|
||||
if (nr < 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
throw new NullPointerException();
|
||||
}
|
||||
fd = new FileDescriptor();
|
||||
fd.incrementAndGetUseCount();
|
||||
fd.attach(this);
|
||||
open(name, imode);
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,9 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
* @see java.io.FileDescriptor
|
||||
*/
|
||||
public final FileDescriptor getFD() throws IOException {
|
||||
if (fd != null) return fd;
|
||||
if (fd != null) {
|
||||
return fd;
|
||||
}
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
|
@ -268,17 +270,6 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
synchronized (this) {
|
||||
if (channel == null) {
|
||||
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;
|
||||
}
|
||||
|
@ -577,28 +568,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
closed = true;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrement FD use count associated with this stream.
|
||||
* 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();
|
||||
}
|
||||
fd.closeAll(new Closeable() {
|
||||
public void close() throws IOException {
|
||||
close0();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -57,7 +57,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
|
|||
/**
|
||||
* 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
|
||||
|
@ -107,7 +107,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
|
|||
public void write(int c) throws IOException {
|
||||
synchronized (lock) {
|
||||
if (writeBuffer == null){
|
||||
writeBuffer = new char[writeBufferSize];
|
||||
writeBuffer = new char[WRITE_BUFFER_SIZE];
|
||||
}
|
||||
writeBuffer[0] = (char) c;
|
||||
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 {
|
||||
synchronized (lock) {
|
||||
char cbuf[];
|
||||
if (len <= writeBufferSize) {
|
||||
if (len <= WRITE_BUFFER_SIZE) {
|
||||
if (writeBuffer == null) {
|
||||
writeBuffer = new char[writeBufferSize];
|
||||
writeBuffer = new char[WRITE_BUFFER_SIZE];
|
||||
}
|
||||
cbuf = writeBuffer;
|
||||
} else { // Don't permanently allocate very large buffers.
|
||||
|
|
|
@ -71,7 +71,7 @@ public class AssertionError extends Error {
|
|||
* @see Throwable#getCause()
|
||||
*/
|
||||
public AssertionError(Object detailMessage) {
|
||||
this("" + detailMessage);
|
||||
this(String.valueOf(detailMessage));
|
||||
if (detailMessage instanceof Throwable)
|
||||
initCause((Throwable) detailMessage);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public class AssertionError extends Error {
|
|||
* @param detailMessage value to be used in constructing detail message
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public AssertionError(double detailMessage) {
|
||||
this("" + detailMessage);
|
||||
this(String.valueOf(detailMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3008,7 +3008,7 @@ public final
|
|||
|
||||
/**
|
||||
* 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
|
||||
* this method succeeds, it always returns a reference to this class object.
|
||||
*
|
||||
|
|
|
@ -607,8 +607,7 @@ public final class Double extends Number implements Comparable<Double> {
|
|||
* @see java.lang.Double#valueOf(java.lang.String)
|
||||
*/
|
||||
public Double(String s) throws NumberFormatException {
|
||||
// REMIND: this is inefficient
|
||||
this(valueOf(s).doubleValue());
|
||||
value = parseDouble(s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -529,8 +529,7 @@ public final class Float extends Number implements Comparable<Float> {
|
|||
* @see java.lang.Float#valueOf(java.lang.String)
|
||||
*/
|
||||
public Float(String s) throws NumberFormatException {
|
||||
// REMIND: this is inefficient
|
||||
this(valueOf(s).floatValue());
|
||||
value = parseFloat(s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -266,7 +266,7 @@ public class CallSite {
|
|||
|
||||
/*package-private*/
|
||||
void setTargetNormal(MethodHandle newTarget) {
|
||||
target = newTarget;
|
||||
MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
|
||||
}
|
||||
/*package-private*/
|
||||
MethodHandle getTargetVolatile() {
|
||||
|
@ -274,7 +274,7 @@ public class CallSite {
|
|||
}
|
||||
/*package-private*/
|
||||
void setTargetVolatile(MethodHandle newTarget) {
|
||||
unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
|
||||
MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
|
||||
}
|
||||
|
||||
// this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
|
||||
|
|
|
@ -934,12 +934,4 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
|||
return THROW_EXCEPTION;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,15 +61,6 @@ class MethodHandleNatives {
|
|||
/** Initialize a method type, once per form. */
|
||||
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.
|
||||
* It will be sanitized as necessary to avoid exposing non-Java references.
|
||||
* This routine is for debugging and reflection.
|
||||
|
@ -122,6 +113,12 @@ class MethodHandleNatives {
|
|||
|
||||
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();
|
||||
static {
|
||||
registerNatives();
|
||||
|
|
|
@ -27,7 +27,6 @@ package java.lang.ref;
|
|||
|
||||
import sun.misc.Cleaner;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract base class for reference objects. This class defines the
|
||||
* operations common to all reference objects. Because reference objects are
|
||||
|
@ -69,7 +68,7 @@ public abstract class Reference<T> {
|
|||
* null.
|
||||
*
|
||||
* 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
|
||||
* 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,
|
||||
* 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
|
||||
* 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 */
|
||||
|
||||
ReferenceQueue<? super T> queue;
|
||||
|
||||
/* When active: NULL
|
||||
* pending: this
|
||||
* Enqueued: next reference in queue (or this if last)
|
||||
* Inactive: this
|
||||
*/
|
||||
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 */
|
||||
|
||||
|
||||
|
@ -106,7 +116,8 @@ public abstract class Reference<T> {
|
|||
|
||||
/* List of References waiting to be enqueued. The collector adds
|
||||
* 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;
|
||||
|
||||
|
@ -120,14 +131,12 @@ public abstract class Reference<T> {
|
|||
|
||||
public void run() {
|
||||
for (;;) {
|
||||
|
||||
Reference r;
|
||||
synchronized (lock) {
|
||||
if (pending != null) {
|
||||
r = pending;
|
||||
Reference rn = r.next;
|
||||
pending = (rn == r) ? null : rn;
|
||||
r.next = r;
|
||||
pending = r.discovered;
|
||||
r.discovered = null;
|
||||
} else {
|
||||
try {
|
||||
lock.wait();
|
||||
|
@ -201,10 +210,8 @@ public abstract class Reference<T> {
|
|||
* been enqueued
|
||||
*/
|
||||
public boolean isEnqueued() {
|
||||
/* In terms of the internal states, this predicate actually tests
|
||||
whether the instance is either Pending or Enqueued */
|
||||
synchronized (this) {
|
||||
return (this.queue != ReferenceQueue.NULL) && (this.next != null);
|
||||
return (this.next != null && this.queue == ReferenceQueue.ENQUEUED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -876,10 +876,12 @@ class InetAddress implements java.io.Serializable {
|
|||
nameService = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedExceptionAction<NameService>() {
|
||||
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()) {
|
||||
NameServiceDescriptor nsd
|
||||
= (NameServiceDescriptor)itr.next();
|
||||
NameServiceDescriptor nsd = itr.next();
|
||||
if (providerName.
|
||||
equalsIgnoreCase(nsd.getType()+","
|
||||
+nsd.getProviderName())) {
|
||||
|
|
|
@ -267,10 +267,9 @@ class ServerSocket implements java.io.Closeable {
|
|||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws NoSuchMethodException {
|
||||
Class[] cl = new Class[2];
|
||||
cl[0] = SocketAddress.class;
|
||||
cl[1] = Integer.TYPE;
|
||||
impl.getClass().getDeclaredMethod("connect", cl);
|
||||
impl.getClass().getDeclaredMethod("connect",
|
||||
SocketAddress.class,
|
||||
int.class);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -435,7 +435,7 @@ public abstract class Charset
|
|||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
try {
|
||||
Class epc
|
||||
Class<?> epc
|
||||
= Class.forName("sun.nio.cs.ext.ExtendedCharsets");
|
||||
extendedProvider = (CharsetProvider)epc.newInstance();
|
||||
} catch (ClassNotFoundException x) {
|
||||
|
|
|
@ -363,6 +363,17 @@ public final class Files {
|
|||
|
||||
// -- 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
|
||||
* 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)
|
||||
throws IOException
|
||||
{
|
||||
return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
|
||||
@Override
|
||||
public boolean accept(Path entry) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@ package java.security;
|
|||
|
||||
import java.util.Enumeration;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import sun.security.jca.GetInstance;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
@ -60,8 +61,8 @@ import sun.security.util.SecurityConstants;
|
|||
* with a standard type. The default policy type is "JavaPolicy".
|
||||
*
|
||||
* <p> Once a Policy instance has been installed (either by default, or by
|
||||
* calling <code>setPolicy</code>),
|
||||
* the Java runtime invokes its <code>implies</code> when it needs to
|
||||
* calling <code>setPolicy</code>), the Java runtime invokes its
|
||||
* <code>implies</code> method when it needs to
|
||||
* determine whether executing code (encapsulated in a ProtectionDomain)
|
||||
* can perform SecurityManager-protected operations. How a Policy object
|
||||
* 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 =
|
||||
new UnsupportedEmptyCollection();
|
||||
|
||||
/** the system-wide policy. */
|
||||
private static Policy policy; // package private for AccessControlContext
|
||||
// Information about the system-wide policy.
|
||||
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");
|
||||
|
||||
// Cache mapping ProtectionDomain.Key to PermissionCollection
|
||||
private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping;
|
||||
|
||||
/** package private for AccessControlContext */
|
||||
/** package private for AccessControlContext and ProtectionDomain */
|
||||
static boolean isSet()
|
||||
{
|
||||
return policy != null;
|
||||
PolicyInfo pi = policy.get();
|
||||
return pi.policy != null && pi.initialized == true;
|
||||
}
|
||||
|
||||
private static void checkPermission(String type) {
|
||||
|
@ -143,80 +159,92 @@ public abstract class Policy {
|
|||
|
||||
/**
|
||||
* Returns the installed Policy object, skipping the security check.
|
||||
* Used by SecureClassLoader and getPolicy.
|
||||
* Used by ProtectionDomain and getPolicy.
|
||||
*
|
||||
* @return the installed Policy.
|
||||
*
|
||||
*/
|
||||
static synchronized Policy getPolicyNoCheck()
|
||||
static Policy getPolicyNoCheck()
|
||||
{
|
||||
if (policy == null) {
|
||||
String policy_class = null;
|
||||
policy_class = AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return Security.getProperty("policy.provider");
|
||||
}
|
||||
});
|
||||
if (policy_class == null) {
|
||||
policy_class = "sun.security.provider.PolicyFile";
|
||||
}
|
||||
|
||||
try {
|
||||
policy = (Policy)
|
||||
Class.forName(policy_class).newInstance();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* The policy_class seems to be an extension
|
||||
* so we have to bootstrap loading it via a policy
|
||||
* provider that is on the bootclasspath
|
||||
* If it loads then shift gears to using the configured
|
||||
* provider.
|
||||
*/
|
||||
|
||||
// install the bootstrap provider to avoid recursion
|
||||
policy = new sun.security.provider.PolicyFile();
|
||||
|
||||
final String pc = policy_class;
|
||||
Policy p = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Policy>() {
|
||||
public Policy run() {
|
||||
try {
|
||||
ClassLoader cl =
|
||||
ClassLoader.getSystemClassLoader();
|
||||
// we want the extension loader
|
||||
ClassLoader extcl = null;
|
||||
while (cl != null) {
|
||||
extcl = cl;
|
||||
cl = cl.getParent();
|
||||
}
|
||||
return (extcl != null ? (Policy)Class.forName(
|
||||
pc, true, extcl).newInstance() : null);
|
||||
} catch (Exception e) {
|
||||
if (debug != null) {
|
||||
debug.println("policy provider " +
|
||||
pc +
|
||||
" not available");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
PolicyInfo pi = policy.get();
|
||||
// Use double-check idiom to avoid locking if system-wide policy is
|
||||
// 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>() {
|
||||
public String run() {
|
||||
return Security.getProperty("policy.provider");
|
||||
}
|
||||
});
|
||||
/*
|
||||
* if it loaded install it as the policy provider. Otherwise
|
||||
* continue to use the system default implementation
|
||||
*/
|
||||
if (p != null) {
|
||||
policy = p;
|
||||
} else {
|
||||
if (debug != null) {
|
||||
debug.println("using sun.security.provider.PolicyFile");
|
||||
if (policy_class == null) {
|
||||
policy_class = "sun.security.provider.PolicyFile";
|
||||
}
|
||||
|
||||
try {
|
||||
pinfo = new PolicyInfo(
|
||||
(Policy) Class.forName(policy_class).newInstance(),
|
||||
true);
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* The policy_class seems to be an extension
|
||||
* so we have to bootstrap loading it via a policy
|
||||
* provider that is on the bootclasspath.
|
||||
* If it loads then shift gears to using the configured
|
||||
* provider.
|
||||
*/
|
||||
|
||||
// install the bootstrap provider to avoid recursion
|
||||
Policy polFile = new sun.security.provider.PolicyFile();
|
||||
pinfo = new PolicyInfo(polFile, false);
|
||||
policy.set(pinfo);
|
||||
|
||||
final String pc = policy_class;
|
||||
Policy pol = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Policy>() {
|
||||
public Policy run() {
|
||||
try {
|
||||
ClassLoader cl =
|
||||
ClassLoader.getSystemClassLoader();
|
||||
// we want the extension loader
|
||||
ClassLoader extcl = null;
|
||||
while (cl != null) {
|
||||
extcl = cl;
|
||||
cl = cl.getParent();
|
||||
}
|
||||
return (extcl != null ? (Policy)Class.forName(
|
||||
pc, true, extcl).newInstance() : null);
|
||||
} catch (Exception e) {
|
||||
if (debug != null) {
|
||||
debug.println("policy provider " +
|
||||
pc +
|
||||
" not available");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
* if it loaded install it as the policy provider. Otherwise
|
||||
* continue to use the system default implementation
|
||||
*/
|
||||
if (pol != null) {
|
||||
pinfo = new PolicyInfo(pol, true);
|
||||
} else {
|
||||
if (debug != null) {
|
||||
debug.println("using sun.security.provider.PolicyFile");
|
||||
}
|
||||
pinfo = new PolicyInfo(polFile, true);
|
||||
}
|
||||
}
|
||||
policy.set(pinfo);
|
||||
}
|
||||
return pinfo.policy;
|
||||
}
|
||||
}
|
||||
return policy;
|
||||
return pi.policy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +273,7 @@ public abstract class Policy {
|
|||
initPolicy(p);
|
||||
}
|
||||
synchronized (Policy.class) {
|
||||
Policy.policy = p;
|
||||
policy.set(new PolicyInfo(p, p != null));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,14 +320,14 @@ public abstract class Policy {
|
|||
PermissionCollection policyPerms = null;
|
||||
synchronized (p) {
|
||||
if (p.pdMapping == null) {
|
||||
p.pdMapping =
|
||||
new WeakHashMap<ProtectionDomain.Key, PermissionCollection>();
|
||||
p.pdMapping = new WeakHashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
if (policyDomain.getCodeSource() != null) {
|
||||
if (Policy.isSet()) {
|
||||
policyPerms = policy.getPermissions(policyDomain);
|
||||
Policy pol = policy.get().policy;
|
||||
if (pol != null) {
|
||||
policyPerms = pol.getPermissions(policyDomain);
|
||||
}
|
||||
|
||||
if (policyPerms == null) { // assume it has all
|
||||
|
@ -434,7 +462,7 @@ public abstract class Policy {
|
|||
type,
|
||||
params);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
return handleException (nsae);
|
||||
return handleException(nsae);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,7 +522,7 @@ public abstract class Policy {
|
|||
type,
|
||||
params);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
return handleException (nsae);
|
||||
return handleException(nsae);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,7 +836,7 @@ public abstract class Policy {
|
|||
*
|
||||
* @param permission the Permission object to compare.
|
||||
*
|
||||
* @return true if "permission" is implied by the permissions in
|
||||
* @return true if "permission" is implied by the permissions in
|
||||
* the collection, false if not.
|
||||
*/
|
||||
@Override public boolean implies(Permission permission) {
|
||||
|
|
|
@ -814,7 +814,7 @@ public final class Security {
|
|||
public Void run() {
|
||||
try {
|
||||
/* Get the class via the bootstrap class loader. */
|
||||
Class cl = Class.forName(
|
||||
Class<?> cl = Class.forName(
|
||||
"java.lang.SecurityManager", false, null);
|
||||
Field f = null;
|
||||
boolean accessible = false;
|
||||
|
|
|
@ -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
|
||||
* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
|
||||
* (depending on the argument's
|
||||
|
|
|
@ -991,7 +991,7 @@ public interface Statement extends Wrapper, AutoCloseable {
|
|||
/**
|
||||
* Requests that a <code>Statement</code> be pooled or not pooled. The value
|
||||
* 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.
|
||||
* <p>
|
||||
* The poolable value of a statement is applicable to both internal
|
||||
|
|
|
@ -443,7 +443,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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}.
|
||||
* @return A break iterator for word breaks
|
||||
*/
|
||||
|
@ -454,7 +454,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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.
|
||||
* @param locale the desired locale
|
||||
* @return A break iterator for word breaks
|
||||
|
@ -470,7 +470,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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}.
|
||||
* @return A break iterator for line breaks
|
||||
*/
|
||||
|
@ -481,7 +481,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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.
|
||||
* @param locale the desired locale
|
||||
* @return A break iterator for line breaks
|
||||
|
@ -497,7 +497,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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}.
|
||||
* @return A break iterator for character breaks
|
||||
*/
|
||||
|
@ -508,7 +508,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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.
|
||||
* @param locale the desired locale
|
||||
* @return A break iterator for character breaks
|
||||
|
@ -524,7 +524,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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}.
|
||||
* @return A break iterator for sentence breaks
|
||||
*/
|
||||
|
@ -535,7 +535,7 @@ public abstract class BreakIterator implements Cloneable
|
|||
|
||||
/**
|
||||
* 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.
|
||||
* @param locale the desired locale
|
||||
* @return A break iterator for sentence breaks
|
||||
|
|
|
@ -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<String> 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.
|
||||
*
|
||||
|
|
|
@ -742,6 +742,8 @@ public class LinkedBlockingDeque<E>
|
|||
throw new NullPointerException();
|
||||
if (c == this)
|
||||
throw new IllegalArgumentException();
|
||||
if (maxElements <= 0)
|
||||
return 0;
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
|
|
|
@ -332,7 +332,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
|||
// Note: convention in all put/take/etc is to preset local var
|
||||
// holding count negative to indicate failure unless set.
|
||||
int c = -1;
|
||||
Node<E> node = new Node(e);
|
||||
Node<E> node = new Node<E>(e);
|
||||
final ReentrantLock putLock = this.putLock;
|
||||
final AtomicInteger count = this.count;
|
||||
putLock.lockInterruptibly();
|
||||
|
@ -412,7 +412,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
|||
if (count.get() == capacity)
|
||||
return false;
|
||||
int c = -1;
|
||||
Node<E> node = new Node(e);
|
||||
Node<E> node = new Node<E>(e);
|
||||
final ReentrantLock putLock = this.putLock;
|
||||
putLock.lock();
|
||||
try {
|
||||
|
@ -728,6 +728,8 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
|||
throw new NullPointerException();
|
||||
if (c == this)
|
||||
throw new IllegalArgumentException();
|
||||
if (maxElements <= 0)
|
||||
return 0;
|
||||
boolean signalNotFull = false;
|
||||
final ReentrantLock takeLock = this.takeLock;
|
||||
takeLock.lock();
|
||||
|
|
|
@ -629,7 +629,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
|||
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.
|
||||
* @see <a href="../../../../technotes/guides/versioning/spec/versioning2.html#wp90779">
|
||||
* Java Product Versioning Specification</a>
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
|
||||
* 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()
|
||||
*/
|
||||
public void setSSLSocketFactory(SSLSocketFactory sf) {
|
||||
|
@ -355,6 +358,10 @@ class HttpsURLConnection extends HttpURLConnection
|
|||
"no SSLSocketFactory specified");
|
||||
}
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkSetFactory();
|
||||
}
|
||||
sslSocketFactory = sf;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* handshake, this method will automatically start the handshake.
|
||||
* <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
|
||||
* more than the sum of the bytes remaining in each buffer. Each
|
||||
* <code>ByteBuffer</code>'s position is updated to reflect the
|
||||
|
|
|
@ -1828,6 +1828,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
|||
* table. While the {@code autoCreateRowSorter} property remains
|
||||
* {@code true}, every time the model is changed, a new {@code
|
||||
* 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}
|
||||
* should be automatically created
|
||||
|
|
|
@ -1838,7 +1838,9 @@ public class JTree extends JComponent implements Scrollable, Accessible
|
|||
* nodes, or <code>null</code> if nothing is currently selected
|
||||
*/
|
||||
public TreePath[] getSelectionPaths() {
|
||||
return getSelectionModel().getSelectionPaths();
|
||||
TreePath[] selectionPaths = getSelectionModel().getSelectionPaths();
|
||||
|
||||
return (selectionPaths != null && selectionPaths.length > 0) ? selectionPaths : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1326,7 +1326,7 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou
|
|||
if ( ! SwingUtilities2.canCurrentEventAccessSystemClipboard() ) {
|
||||
return;
|
||||
}
|
||||
if (this.dot != this.mark && component != null) {
|
||||
if (this.dot != this.mark && component != null && component.hasFocus()) {
|
||||
Clipboard clip = getSystemSelection();
|
||||
if (clip != null) {
|
||||
String selectedText;
|
||||
|
|
|
@ -1181,7 +1181,12 @@ public class HTMLDocument extends DefaultStyledDocument {
|
|||
public void insertAfterStart(Element elem, String htmlText) throws
|
||||
BadLocationException, IOException {
|
||||
verifyParser();
|
||||
if (elem != null && elem.isLeaf()) {
|
||||
|
||||
if (elem == null || htmlText == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (elem.isLeaf()) {
|
||||
throw new IllegalArgumentException
|
||||
("Can not insert HTML after start of a leaf");
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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.setProperties(properties);
|
||||
sendPixels();
|
||||
theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
|
||||
theConsumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
} catch (NullPointerException e) {
|
||||
if (theConsumer != null) {
|
||||
theConsumer.imageComplete(ImageConsumer.IMAGEERROR);
|
||||
|
|
|
@ -41,13 +41,14 @@ public class ResourceManager {
|
|||
|
||||
/* default maximum number of udp sockets per VM
|
||||
* 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
|
||||
* of port numbers actually available on all OSes for
|
||||
* such sockets (5000 on some versions of windows)
|
||||
* of port numbers actually available on all OSes
|
||||
* 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 AtomicInteger numSockets;
|
||||
|
||||
|
|
|
@ -402,10 +402,10 @@ class ServerImpl implements TimeSource {
|
|||
} catch (IOException e) {
|
||||
logger.log (Level.FINER, "Dispatcher (4)", e);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.log (Level.FINER, "Dispatcher (7)", e);
|
||||
}
|
||||
}
|
||||
try {selector.close(); } catch (Exception e) {}
|
||||
}
|
||||
|
||||
private void handleException (SelectionKey key, Exception e) {
|
||||
|
|
|
@ -363,10 +363,10 @@ class Util {
|
|||
try {
|
||||
Class<?> cl = Class.forName("java.nio.DirectByteBuffer");
|
||||
Constructor<?> ctor = cl.getDeclaredConstructor(
|
||||
new Class[] { int.class,
|
||||
long.class,
|
||||
FileDescriptor.class,
|
||||
Runnable.class });
|
||||
new Class<?>[] { int.class,
|
||||
long.class,
|
||||
FileDescriptor.class,
|
||||
Runnable.class });
|
||||
ctor.setAccessible(true);
|
||||
directByteBufferConstructor = ctor;
|
||||
} catch (ClassNotFoundException |
|
||||
|
@ -408,10 +408,10 @@ class Util {
|
|||
try {
|
||||
Class<?> cl = Class.forName("java.nio.DirectByteBufferR");
|
||||
Constructor<?> ctor = cl.getDeclaredConstructor(
|
||||
new Class[] { int.class,
|
||||
long.class,
|
||||
FileDescriptor.class,
|
||||
Runnable.class });
|
||||
new Class<?>[] { int.class,
|
||||
long.class,
|
||||
FileDescriptor.class,
|
||||
Runnable.class });
|
||||
ctor.setAccessible(true);
|
||||
directByteBufferRConstructor = ctor;
|
||||
} catch (ClassNotFoundException |
|
||||
|
|
604
jdk/src/share/classes/sun/nio/cs/CESU_8.java
Normal file
604
jdk/src/share/classes/sun/nio/cs/CESU_8.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -72,8 +72,8 @@ class UTF_8 extends Unicode
|
|||
return new Encoder(this);
|
||||
}
|
||||
|
||||
static final void updatePositions(Buffer src, int sp,
|
||||
Buffer dst, int dp) {
|
||||
private static final void updatePositions(Buffer src, int sp,
|
||||
Buffer dst, int dp) {
|
||||
src.position(sp - src.arrayOffset());
|
||||
dst.position(dp - dst.arrayOffset());
|
||||
}
|
||||
|
@ -88,11 +88,6 @@ class UTF_8 extends Unicode
|
|||
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]
|
||||
// [E1..EF] [80..BF] [80..BF]
|
||||
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;
|
||||
}
|
||||
|
||||
// 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]
|
||||
|
@ -110,6 +111,16 @@ class UTF_8 extends Unicode
|
|||
(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)
|
||||
{
|
||||
for (int i = 1; i < n; i++) {
|
||||
|
@ -122,28 +133,14 @@ class UTF_8 extends Unicode
|
|||
private static CoderResult malformedN(ByteBuffer src, int nb) {
|
||||
switch (nb) {
|
||||
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
|
||||
return CoderResult.malformedForLength(1);
|
||||
case 3:
|
||||
b1 = src.get();
|
||||
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);
|
||||
isNotContinuation(b2)) ? 1 : 2);
|
||||
case 4: // we don't care the speed here
|
||||
b1 = src.get() & 0xff;
|
||||
b2 = src.get() & 0xff;
|
||||
|
@ -171,6 +168,7 @@ class UTF_8 extends Unicode
|
|||
return cr;
|
||||
}
|
||||
|
||||
|
||||
private static CoderResult malformed(ByteBuffer src,
|
||||
int mark, int nb)
|
||||
{
|
||||
|
@ -180,18 +178,36 @@ class UTF_8 extends Unicode
|
|||
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;
|
||||
? CoderResult.UNDERFLOW : CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
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);
|
||||
return cr;
|
||||
return (nb == 0 || src.remaining() < nb)
|
||||
? CoderResult.UNDERFLOW : CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
private CoderResult decodeArrayLoop(ByteBuffer src,
|
||||
|
@ -210,7 +226,6 @@ class UTF_8 extends Unicode
|
|||
// ASCII only loop
|
||||
while (dp < dlASCII && sa[sp] >= 0)
|
||||
da[dp++] = (char) sa[sp++];
|
||||
|
||||
while (sp < sl) {
|
||||
int b1 = sa[sp];
|
||||
if (b1 >= 0) {
|
||||
|
@ -219,13 +234,20 @@ class UTF_8 extends Unicode
|
|||
return xflow(src, sp, sl, dst, dp, 1);
|
||||
da[dp++] = (char) b1;
|
||||
sp++;
|
||||
} else if ((b1 >> 5) == -2) {
|
||||
} else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
|
||||
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx
|
||||
// [C2..DF] [80..BF]
|
||||
if (sl - sp < 2 || dp >= dl)
|
||||
return xflow(src, sp, sl, dst, dp, 2);
|
||||
int b2 = sa[sp + 1];
|
||||
if (isMalformed2(b1, b2))
|
||||
return malformed(src, sp, dst, dp, 2);
|
||||
// Now we check the first byte of 2-byte sequence as
|
||||
// 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)
|
||||
^
|
||||
(((byte) 0xC0 << 6) ^
|
||||
|
@ -233,24 +255,37 @@ class UTF_8 extends Unicode
|
|||
sp += 2;
|
||||
} else if ((b1 >> 4) == -2) {
|
||||
// 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);
|
||||
}
|
||||
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)
|
||||
char c = (char)
|
||||
((b1 << 12) ^
|
||||
(b2 << 6) ^
|
||||
(b3 ^
|
||||
(((byte) 0xE0 << 12) ^
|
||||
((byte) 0x80 << 6) ^
|
||||
((byte) 0x80 << 0))));
|
||||
if (Character.isSurrogate(c))
|
||||
return malformedForLength(src, sp, dst, dp, 3);
|
||||
da[dp++] = c;
|
||||
sp += 3;
|
||||
} else if ((b1 >> 3) == -2) {
|
||||
// 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);
|
||||
}
|
||||
int b2 = sa[sp + 1];
|
||||
int b3 = sa[sp + 2];
|
||||
int b4 = sa[sp + 3];
|
||||
|
@ -289,38 +324,51 @@ class UTF_8 extends Unicode
|
|||
return xflow(src, mark, 1); // overflow
|
||||
dst.put((char) b1);
|
||||
mark++;
|
||||
} else if ((b1 >> 5) == -2) {
|
||||
} 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 (isMalformed2(b1, b2))
|
||||
return malformed(src, mark, 2);
|
||||
dst.put((char) (((b1 << 6) ^ b2)
|
||||
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
|
||||
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);
|
||||
}
|
||||
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)))));
|
||||
char c = (char)
|
||||
((b1 << 12) ^
|
||||
(b2 << 6) ^
|
||||
(b3 ^
|
||||
(((byte) 0xE0 << 12) ^
|
||||
((byte) 0x80 << 6) ^
|
||||
((byte) 0x80 << 0))));
|
||||
if (Character.isSurrogate(c))
|
||||
return malformedForLength(src, mark, 3);
|
||||
dst.put(c);
|
||||
mark += 3;
|
||||
} else if ((b1 >> 3) == -2) {
|
||||
// 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);
|
||||
}
|
||||
int b2 = src.get();
|
||||
int b3 = src.get();
|
||||
int b4 = src.get();
|
||||
|
@ -364,7 +412,7 @@ class UTF_8 extends Unicode
|
|||
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.
|
||||
public int decode(byte[] sa, int sp, int len, char[] da) {
|
||||
final int sl = sp + len;
|
||||
|
@ -381,11 +429,11 @@ class UTF_8 extends Unicode
|
|||
if (b1 >= 0) {
|
||||
// 1 byte, 7 bits: 0xxxxxxx
|
||||
da[dp++] = (char) b1;
|
||||
} else if ((b1 >> 5) == -2) {
|
||||
} else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
|
||||
// 2 bytes, 11 bits: 110xxxxx 10xxxxxx
|
||||
if (sp < sl) {
|
||||
int b2 = sa[sp++];
|
||||
if (isMalformed2(b1, b2)) {
|
||||
if (isNotContinuation(b2)) {
|
||||
if (malformedInputAction() != CodingErrorAction.REPLACE)
|
||||
return -1;
|
||||
da[dp++] = replacement().charAt(0);
|
||||
|
@ -410,21 +458,33 @@ class UTF_8 extends Unicode
|
|||
if (malformedInputAction() != CodingErrorAction.REPLACE)
|
||||
return -1;
|
||||
da[dp++] = replacement().charAt(0);
|
||||
sp -=3;
|
||||
sp -= 3;
|
||||
bb = getByteBuffer(bb, sa, sp);
|
||||
sp += malformedN(bb, 3).length();
|
||||
} else {
|
||||
da[dp++] = (char)((b1 << 12) ^
|
||||
char c = (char)((b1 << 12) ^
|
||||
(b2 << 6) ^
|
||||
(b3 ^
|
||||
(((byte) 0xE0 << 12) ^
|
||||
((byte) 0x80 << 6) ^
|
||||
((byte) 0x80 << 0))));
|
||||
if (Character.isSurrogate(c)) {
|
||||
if (malformedInputAction() != CodingErrorAction.REPLACE)
|
||||
return -1;
|
||||
da[dp++] = replacement().charAt(0);
|
||||
} else {
|
||||
da[dp++] = c;
|
||||
}
|
||||
}
|
||||
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 ((b1 >> 3) == -2) {
|
||||
|
@ -458,28 +518,29 @@ class UTF_8 extends Unicode
|
|||
}
|
||||
if (malformedInputAction() != CodingErrorAction.REPLACE)
|
||||
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);
|
||||
return dp;
|
||||
} else {
|
||||
if (malformedInputAction() != CodingErrorAction.REPLACE)
|
||||
return -1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Encoder extends CharsetEncoder
|
||||
private static final class Encoder extends CharsetEncoder
|
||||
implements ArrayEncoder {
|
||||
|
||||
private Encoder(Charset cs) {
|
||||
|
|
|
@ -63,6 +63,10 @@ charset UTF-8 UTF_8
|
|||
alias UTF8 # JDK historical
|
||||
alias unicode-1-1-utf-8
|
||||
|
||||
charset CESU-8 CESU_8
|
||||
alias CESU8
|
||||
alias csCESU-8
|
||||
|
||||
charset UTF-16 UTF_16
|
||||
alias UTF_16 # JDK historical
|
||||
alias utf16
|
||||
|
|
|
@ -68,14 +68,18 @@ import javax.print.attribute.standard.Sides;
|
|||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.CharConversionException;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
|
@ -673,15 +677,38 @@ public class PSPrinterJob extends RasterPrinterJob {
|
|||
private class PrinterSpooler implements java.security.PrivilegedAction {
|
||||
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() {
|
||||
if (spoolFile == null || !spoolFile.exists()) {
|
||||
pex = new PrinterException("No spool file");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Spool to the printer.
|
||||
*/
|
||||
if (spoolFile == null || !spoolFile.exists()) {
|
||||
pex = new PrinterException("No spool file");
|
||||
return null;
|
||||
}
|
||||
String fileName = spoolFile.getAbsolutePath();
|
||||
String execCmd[] = printExecCmd(mDestination, mOptions,
|
||||
mNoJobSheet, getJobNameInt(),
|
||||
|
@ -689,12 +716,16 @@ public class PSPrinterJob extends RasterPrinterJob {
|
|||
|
||||
Process process = Runtime.getRuntime().exec(execCmd);
|
||||
process.waitFor();
|
||||
spoolFile.delete();
|
||||
|
||||
final int result = process.exitValue();
|
||||
if (0 != result) {
|
||||
handleProcessFailure(process, execCmd, result);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
pex = new PrinterIOException(ex);
|
||||
} catch (InterruptedException ie) {
|
||||
pex = new PrinterException(ie.toString());
|
||||
} finally {
|
||||
spoolFile.delete();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.rmi.*;
|
||||
|
@ -38,8 +39,17 @@ import java.rmi.server.ServerNotActiveException;
|
|||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
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.PrivilegedExceptionAction;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.text.MessageFormat;
|
||||
import sun.rmi.server.LoaderHandler;
|
||||
import sun.rmi.server.UnicastServerRef;
|
||||
import sun.rmi.server.UnicastServerRef2;
|
||||
import sun.rmi.transport.LiveRef;
|
||||
|
@ -334,11 +344,19 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
|
|||
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
|
||||
int regPort = Registry.REGISTRY_PORT;
|
||||
if (args.length >= 1) {
|
||||
regPort = Integer.parseInt(args[0]);
|
||||
final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
|
||||
: Registry.REGISTRY_PORT;
|
||||
try {
|
||||
registry = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<RegistryImpl>() {
|
||||
public RegistryImpl run() throws RemoteException {
|
||||
return new RegistryImpl(regPort);
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw (RemoteException) ex.getException();
|
||||
}
|
||||
registry = new RegistryImpl(regPort);
|
||||
|
||||
// prevent registry from exiting
|
||||
while (true) {
|
||||
try {
|
||||
|
@ -358,4 +376,46 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
|
|||
}
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1032,8 +1032,8 @@ public final class LoaderHandler {
|
|||
* it is not already implied by the collection.
|
||||
*/
|
||||
private static void addPermissionsForURLs(URL[] urls,
|
||||
PermissionCollection perms,
|
||||
boolean forLoader)
|
||||
PermissionCollection perms,
|
||||
boolean forLoader)
|
||||
{
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
URL url = urls[i];
|
||||
|
|
|
@ -390,6 +390,12 @@ public class UnicastServerRef extends UnicastRef
|
|||
ObjectInput in;
|
||||
try {
|
||||
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();
|
||||
} catch (Exception readEx) {
|
||||
throw new UnmarshalException("error unmarshalling call header",
|
||||
|
|
|
@ -68,8 +68,8 @@ public class KerberosTime implements Cloneable {
|
|||
private int microSeconds; // the last three digits of the microsecond value
|
||||
|
||||
// The time when this class is loaded. Used in setNow()
|
||||
private static final long initMilli = System.currentTimeMillis();
|
||||
private static final long initMicro = System.nanoTime() / 1000;
|
||||
private static long initMilli = System.currentTimeMillis();
|
||||
private static long initMicro = System.nanoTime() / 1000;
|
||||
|
||||
private static long syncTime;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
@ -212,9 +212,22 @@ public class KerberosTime implements Cloneable {
|
|||
}
|
||||
|
||||
public void setNow() {
|
||||
long microElapsed = System.nanoTime() / 1000 - initMicro;
|
||||
setTime(initMilli + microElapsed/1000);
|
||||
microSeconds = (int)(microElapsed % 1000);
|
||||
long newMilli = System.currentTimeMillis();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public int getMicroSeconds() {
|
||||
|
|
|
@ -375,7 +375,7 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC
|
|||
}
|
||||
AuthorizationDataEntry[] auDataEntry = readAuth();
|
||||
AuthorizationData auData = null;
|
||||
if (auData != null) {
|
||||
if (auDataEntry != null) {
|
||||
auData = new AuthorizationData(auDataEntry);
|
||||
}
|
||||
byte[] ticketData = readData();
|
||||
|
|
|
@ -209,10 +209,24 @@ public class Credentials {
|
|||
}
|
||||
|
||||
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,
|
||||
cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
|
||||
}
|
||||
|
||||
public KerberosTime getStartTime() {
|
||||
return starttime;
|
||||
}
|
||||
|
||||
public KerberosTime getAuthTime() {
|
||||
return authtime;
|
||||
}
|
||||
|
@ -221,6 +235,10 @@ public class Credentials {
|
|||
return endtime;
|
||||
}
|
||||
|
||||
public KerberosTime getRenewTill() {
|
||||
return renewTill;
|
||||
}
|
||||
|
||||
public TicketFlags getTicketFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
@ -228,4 +246,8 @@ public class Credentials {
|
|||
public int getEType() {
|
||||
return key.getEType();
|
||||
}
|
||||
|
||||
public int getTktEType() {
|
||||
return ticket.encPart.getEType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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)
|
||||
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.
|
||||
// This lets application synchronize read and write streams
|
||||
// however they like; if we buffered here, they couldn't.
|
||||
try {
|
||||
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
|
||||
if (howmuch > 0) {
|
||||
|
|
|
@ -112,6 +112,11 @@ final class CipherBox {
|
|||
*/
|
||||
private SecureRandom random;
|
||||
|
||||
/**
|
||||
* Is the cipher of CBC mode?
|
||||
*/
|
||||
private final boolean isCBCMode;
|
||||
|
||||
/**
|
||||
* Fixed masks of various block size, as the initial decryption IVs
|
||||
* for TLS 1.1 or later.
|
||||
|
@ -128,6 +133,7 @@ final class CipherBox {
|
|||
private CipherBox() {
|
||||
this.protocolVersion = ProtocolVersion.DEFAULT;
|
||||
this.cipher = null;
|
||||
this.isCBCMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,6 +154,7 @@ final class CipherBox {
|
|||
random = JsseJce.getSecureRandom();
|
||||
}
|
||||
this.random = random;
|
||||
this.isCBCMode = bulkCipher.isCBCMode;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -420,10 +420,16 @@ final class CipherSuite implements Comparable<CipherSuite> {
|
|||
// exportable under 512/40 bit rules
|
||||
final boolean exportable;
|
||||
|
||||
// Is the cipher algorithm of Cipher Block Chaining (CBC) mode?
|
||||
final boolean isCBCMode;
|
||||
|
||||
BulkCipher(String transformation, int keySize,
|
||||
int expandedKeySize, int ivSize, boolean allowed) {
|
||||
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.keySize = keySize;
|
||||
this.ivSize = ivSize;
|
||||
|
@ -436,7 +442,10 @@ final class CipherSuite implements Comparable<CipherSuite> {
|
|||
BulkCipher(String transformation, int keySize,
|
||||
int ivSize, boolean allowed) {
|
||||
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.keySize = keySize;
|
||||
this.ivSize = ivSize;
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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 {
|
||||
|
||||
private SSLEngineImpl engine;
|
||||
private EngineWriter writer;
|
||||
|
||||
private boolean finishedMsg = false;
|
||||
|
@ -62,6 +63,7 @@ final class EngineOutputRecord extends OutputRecord {
|
|||
*/
|
||||
EngineOutputRecord(byte type, SSLEngineImpl engine) {
|
||||
super(type, recordSize(type));
|
||||
this.engine = engine;
|
||||
writer = engine.writer;
|
||||
}
|
||||
|
||||
|
@ -227,11 +229,50 @@ final class EngineOutputRecord extends OutputRecord {
|
|||
* implementations are fragile and don't like to see empty
|
||||
* records, so this increases robustness.
|
||||
*/
|
||||
int length = Math.min(ea.getAppRemaining(), maxDataSize);
|
||||
if (length == 0) {
|
||||
if (ea.getAppRemaining() == 0) {
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
return (block != null && mac != null &&
|
||||
block[0] == 0xFF && block[1] == 0xFF &&
|
||||
block[2] == 0xFF && block[3] == 0xFF &&
|
||||
block[4] == 0xFF && block[5] == 0xFF &&
|
||||
block[6] == 0xFF);
|
||||
block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
|
||||
block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
|
||||
block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
|
||||
block[6] == (byte)0xFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -192,7 +192,7 @@ final class MAC {
|
|||
* only 2^48 sequence numbers left.
|
||||
*/
|
||||
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
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -67,6 +67,23 @@ interface Record {
|
|||
+ maxPadding // padding
|
||||
+ 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.
|
||||
*
|
||||
|
|
|
@ -771,10 +771,15 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
|||
final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||
implements X509TrustManager {
|
||||
|
||||
// the delegated trust manager
|
||||
private final X509TrustManager tm;
|
||||
|
||||
// Cache the trusted certificate to optimize the performance.
|
||||
private final Collection<X509Certificate> trustedCerts = new HashSet<>();
|
||||
|
||||
AbstractTrustManagerWrapper(X509TrustManager tm) {
|
||||
this.tm = tm;
|
||||
Collections.addAll(trustedCerts, tm.getAcceptedIssuers());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -863,20 +868,7 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
|||
constraints = new SSLAlgorithmConstraints(sslSocket, true);
|
||||
}
|
||||
|
||||
AlgorithmChecker checker = new AlgorithmChecker(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");
|
||||
}
|
||||
checkAlgorithmConstraints(chain, constraints);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -918,20 +910,33 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
|||
constraints = new SSLAlgorithmConstraints(engine, true);
|
||||
}
|
||||
|
||||
AlgorithmChecker checker = new AlgorithmChecker(constraints);
|
||||
try {
|
||||
checker.init(false);
|
||||
checkAlgorithmConstraints(chain, constraints);
|
||||
}
|
||||
}
|
||||
|
||||
// A forward checker, need to check from trust to target
|
||||
for (int i = chain.length - 1; i >= 0; i--) {
|
||||
private void checkAlgorithmConstraints(X509Certificate[] chain,
|
||||
AlgorithmConstraints constraints) throws CertificateException {
|
||||
|
||||
try {
|
||||
// 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
|
||||
if (checkedLength >= 0) {
|
||||
AlgorithmChecker checker = new AlgorithmChecker(constraints);
|
||||
checker.init(false);
|
||||
for (int i = checkedLength; 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");
|
||||
}
|
||||
} catch (CertPathValidatorException cpve) {
|
||||
throw new CertificateException(
|
||||
"Certificates does not conform to algorithm constraints");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,6 +308,11 @@ final public class SSLEngineImpl extends SSLEngine {
|
|||
private Object unwrapLock;
|
||||
Object writeLock;
|
||||
|
||||
/*
|
||||
* Is it the first application record to write?
|
||||
*/
|
||||
private boolean isFirstAppOutputRecord = true;
|
||||
|
||||
/*
|
||||
* Class and subclass dynamic debugging support
|
||||
*/
|
||||
|
@ -612,6 +617,9 @@ final public class SSLEngineImpl extends SSLEngine {
|
|||
|
||||
// See comment above.
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -369,6 +369,11 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
|
|||
/* Class and subclass dynamic debugging support */
|
||||
private static final Debug debug = Debug.getInstance("ssl");
|
||||
|
||||
/*
|
||||
* Is it the first application record to write?
|
||||
*/
|
||||
private boolean isFirstAppOutputRecord = true;
|
||||
|
||||
//
|
||||
// CONSTRUCTORS AND INITIALIZATION CODE
|
||||
//
|
||||
|
@ -802,8 +807,35 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
|
|||
if (connectionState < cs_ERROR) {
|
||||
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
|
||||
|
@ -1453,7 +1485,8 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
|
|||
|
||||
private void closeSocket(boolean selfInitiated) throws IOException {
|
||||
if ((debug != null) && Debug.isOn("ssl")) {
|
||||
System.out.println(threadName() + ", called closeSocket(selfInitiated)");
|
||||
System.out.println(threadName() +
|
||||
", called closeSocket(" + selfInitiated + ")");
|
||||
}
|
||||
if (self == this) {
|
||||
super.close();
|
||||
|
@ -2030,6 +2063,9 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
|
|||
|
||||
// See comment above.
|
||||
oldCipher.dispose();
|
||||
|
||||
// reset the flag of the first application record
|
||||
isFirstAppOutputRecord = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,18 +33,7 @@ import java.security.*;
|
|||
import java.util.Date;
|
||||
|
||||
import sun.security.pkcs10.PKCS10;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
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;
|
||||
import sun.security.x509.*;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -165,6 +154,13 @@ public final class CertAndKeyGen {
|
|||
|
||||
publicKey = pair.getPublic();
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -200,7 +206,6 @@ public final class CertAndKeyGen {
|
|||
return privateKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a self-signed X.509v3 certificate for the public key.
|
||||
* The certificate is immediately valid. No extensions.
|
||||
|
@ -224,6 +229,15 @@ public final class CertAndKeyGen {
|
|||
X500Name myname, Date firstDate, long validity)
|
||||
throws CertificateException, InvalidKeyException, SignatureException,
|
||||
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;
|
||||
Date lastDate;
|
||||
|
@ -248,6 +262,7 @@ public final class CertAndKeyGen {
|
|||
info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
|
||||
info.set(X509CertInfo.VALIDITY, interval);
|
||||
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(myname));
|
||||
if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
|
||||
|
||||
cert = new X509CertImpl(info);
|
||||
cert.sign(privateKey, this.sigAlg);
|
||||
|
|
|
@ -1518,9 +1518,16 @@ public final class KeyTool {
|
|||
keypair.generate(keysize);
|
||||
PrivateKey privKey = keypair.getPrivateKey();
|
||||
|
||||
CertificateExtensions ext = createV3Extensions(
|
||||
null,
|
||||
null,
|
||||
v3ext,
|
||||
keypair.getPublicKeyAnyway(),
|
||||
null);
|
||||
|
||||
X509Certificate[] chain = new X509Certificate[1];
|
||||
chain[0] = keypair.getSelfCertificate(
|
||||
x500Name, getStartDate(startDate), validity*24L*60L*60L);
|
||||
x500Name, getStartDate(startDate), validity*24L*60L*60L, ext);
|
||||
|
||||
if (verbose) {
|
||||
MessageFormat form = new MessageFormat(rb.getString
|
||||
|
@ -1537,9 +1544,6 @@ public final class KeyTool {
|
|||
keyPass = promptForKeyPass(alias, null, storePass);
|
||||
}
|
||||
keyStore.setKeyEntry(alias, privKey, keyPass, chain);
|
||||
|
||||
// resign so that -ext are applied.
|
||||
doSelfCert(alias, null, sigAlgName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -524,56 +524,67 @@ public class SwingUtilities2 {
|
|||
}
|
||||
|
||||
// If we get here we're not printing
|
||||
AATextInfo info = drawTextAntialiased(c);
|
||||
if (info != null && (g instanceof Graphics2D)) {
|
||||
if (g instanceof Graphics2D) {
|
||||
AATextInfo info = drawTextAntialiased(c);
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
|
||||
Object oldContrast = null;
|
||||
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
|
||||
if (info.aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, info.aaHint);
|
||||
} else {
|
||||
oldAAValue = null;
|
||||
}
|
||||
if (info.lcdContrastHint != null) {
|
||||
oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);
|
||||
if (info.lcdContrastHint.equals(oldContrast)) {
|
||||
oldContrast = null;
|
||||
} else {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
|
||||
info.lcdContrastHint);
|
||||
}
|
||||
}
|
||||
|
||||
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 (info != null) {
|
||||
Object oldContrast = null;
|
||||
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
|
||||
if (info.aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, info.aaHint);
|
||||
} else {
|
||||
oldAAValue = null;
|
||||
}
|
||||
if (info.lcdContrastHint != null) {
|
||||
oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);
|
||||
if (info.lcdContrastHint.equals(oldContrast)) {
|
||||
oldContrast = null;
|
||||
} else {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
|
||||
info.lcdContrastHint);
|
||||
}
|
||||
}
|
||||
|
||||
if (needsTextLayout) {
|
||||
TextLayout layout = createTextLayout(c, text, g2.getFont(),
|
||||
g2.getFontRenderContext());
|
||||
layout.draw(g2, x, y);
|
||||
} else {
|
||||
g.drawString(text, x, y);
|
||||
}
|
||||
|
||||
if (oldAAValue != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
|
||||
}
|
||||
if (oldContrast != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (needsTextLayout){
|
||||
TextLayout layout = createTextLayout(c, text, g2.getFont(),
|
||||
g2.getFontRenderContext());
|
||||
layout.draw(g2, x, y);
|
||||
} else {
|
||||
g.drawString(text, x, y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldAAValue != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
|
||||
}
|
||||
if (oldContrast != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);
|
||||
}
|
||||
}
|
||||
else {
|
||||
g.drawString(text, x, y);
|
||||
}
|
||||
g.drawString(text, x, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draws the string at the specified location underlining the specified
|
||||
* character.
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -76,7 +76,7 @@ public class XMLUtils {
|
|||
} catch (SAXException saxe) {
|
||||
throw new InvalidPropertiesFormatException(saxe);
|
||||
}
|
||||
Element propertiesElement = (Element)doc.getChildNodes().item(1);
|
||||
Element propertiesElement = doc.getDocumentElement();
|
||||
String xmlVersion = propertiesElement.getAttribute("version");
|
||||
if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
|
||||
throw new InvalidPropertiesFormatException(
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
|
||||
To run the Ruler demo:
|
||||
|
||||
java -jar Ruler.jar
|
||||
java -jar TransparentRuler.jar
|
||||
|
||||
These instructions assume that this installation's version of the java
|
||||
command is in your path. If it isn't, then you should either
|
||||
specify the complete path to the java command or update your
|
||||
PATH environment variable as described in the installation
|
||||
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
|
||||
|
|
|
@ -1424,7 +1424,8 @@ typedef struct {
|
|||
*/
|
||||
unsigned int thread_park_blocker : 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;
|
||||
} jdk_version_info;
|
||||
|
|
|
@ -1112,11 +1112,14 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) {
|
|||
uint size3 = suffix * 3;
|
||||
if (suffix == 0) continue; // done with empty string
|
||||
chars.malloc(size3);
|
||||
CHECK;
|
||||
byte* chp = chars.ptr;
|
||||
band saved_band = cp_Utf8_big_chars;
|
||||
cp_Utf8_big_chars.readData(suffix);
|
||||
CHECK;
|
||||
for (int j = 0; j < suffix; j++) {
|
||||
unsigned short ch = cp_Utf8_big_chars.getInt();
|
||||
CHECK;
|
||||
chp = store_Utf8_char(chp, ch);
|
||||
}
|
||||
chars.realloc(chp - chars.ptr);
|
||||
|
@ -1134,10 +1137,12 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) {
|
|||
CHECK;
|
||||
int prevlen = 0; // previous string length (in chars)
|
||||
tmallocs.add(bigbuf.ptr); // free after this block
|
||||
CHECK;
|
||||
cp_Utf8_prefix.rewind();
|
||||
for (i = 0; i < len; i++) {
|
||||
bytes& chars = allsuffixes[i];
|
||||
int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
|
||||
CHECK;
|
||||
int suffix = (int)chars.len;
|
||||
byte* fillp;
|
||||
// by induction, the buffer is already filled with the prefix
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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))
|
||||
msize = sizeof(int); // see 0xbaadf00d below
|
||||
#endif
|
||||
void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize);
|
||||
void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize);
|
||||
if (ptr != null) {
|
||||
memset(ptr, 0, size);
|
||||
} else {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
|
||||
// overflow management
|
||||
#define OVERFLOW ((size_t)-1)
|
||||
#define OVERFLOW ((uint)-1)
|
||||
#define PSIZE_MAX (OVERFLOW/2) /* normal size limit */
|
||||
|
||||
inline size_t scale_size(size_t size, size_t scale) {
|
||||
|
|
|
@ -101,5 +101,5 @@ JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) {
|
|||
// Advertise presence of sun.misc.PostVMInitHook:
|
||||
// future optimization: detect if this is enabled.
|
||||
info->post_vm_init_hook_enabled = 1;
|
||||
|
||||
info->pending_list_uses_discovered_field = 1;
|
||||
}
|
||||
|
|
|
@ -59,13 +59,8 @@ typedef double mlib_d64;
|
|||
|
||||
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__)
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <stdint.h> /* for uintptr_t */
|
||||
#include <malloc.h> /* for ptrdiff_t */
|
||||
#else
|
||||
#include <link.h> /* for uintptr_t */
|
||||
#include <stddef.h> /* for ptrdiff_t */
|
||||
#endif /* __linux__ */
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef MLIB_OS64BIT
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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;
|
||||
TransformInterpFunc *pInterpFunc;
|
||||
jdouble xorig, yorig;
|
||||
jint numedges;
|
||||
jlong numedges;
|
||||
jint *pEdges;
|
||||
jint edgebuf[2 + MAXEDGES * 2];
|
||||
union {
|
||||
|
@ -379,19 +379,44 @@ Java_sun_java2d_loops_TransformHelper_Transform
|
|||
}
|
||||
Region_IntersectBounds(&clipInfo, &dstInfo.bounds);
|
||||
|
||||
numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1);
|
||||
if (numedges > MAXEDGES) {
|
||||
pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges));
|
||||
if (pEdges == NULL) {
|
||||
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
|
||||
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
|
||||
/* edgeArray should already contain zeros for min/maxy */
|
||||
return;
|
||||
}
|
||||
numedges = (((jlong) dstInfo.bounds.y2) - ((jlong) dstInfo.bounds.y1));
|
||||
if (numedges <= 0) {
|
||||
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 (numedges > 0) {
|
||||
JNU_ThrowInternalError(env, "Unable to allocate edge list");
|
||||
}
|
||||
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
|
||||
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
|
||||
/* edgeArray should already contain zeros for min/maxy */
|
||||
return;
|
||||
}
|
||||
|
||||
Transform_GetInfo(env, itxform, &itxInfo);
|
||||
|
||||
if (!Region_IsEmpty(&clipInfo)) {
|
||||
|
@ -500,14 +525,14 @@ Java_sun_java2d_loops_TransformHelper_Transform
|
|||
} else {
|
||||
pEdges[0] = pEdges[1] = 0;
|
||||
}
|
||||
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
|
||||
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
|
||||
|
||||
if (!JNU_IsNull(env, edgeArray)) {
|
||||
(*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges);
|
||||
}
|
||||
if (pEdges != edgebuf) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, edgeArray, pEdges, 0);
|
||||
} else if (pEdges != edgebuf) {
|
||||
free(pEdges);
|
||||
}
|
||||
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
|
||||
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,7 +25,8 @@
|
|||
|
||||
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
|
||||
|
@ -46,12 +47,9 @@ public final class FileDescriptor {
|
|||
|
||||
private int fd;
|
||||
|
||||
/**
|
||||
* A counter for tracking the FIS/FOS/RAF instances that
|
||||
* use this FileDescriptor. The FIS/FOS.finalize() will not release
|
||||
* the FileDescriptor if it is still under user by a stream.
|
||||
*/
|
||||
private AtomicInteger useCount;
|
||||
private Closeable parent;
|
||||
private List<Closeable> otherParents;
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* Constructs an (invalid) FileDescriptor
|
||||
|
@ -59,12 +57,10 @@ public final class FileDescriptor {
|
|||
*/
|
||||
public /**/ FileDescriptor() {
|
||||
fd = -1;
|
||||
useCount = new AtomicInteger();
|
||||
}
|
||||
|
||||
private /* */ FileDescriptor(int 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -466,12 +466,16 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
|||
if (true) {
|
||||
switch(e.getID()) {
|
||||
case PaintEvent.UPDATE:
|
||||
log.finer("XCP coalescePaintEvent : UPDATE : add : x = " +
|
||||
if (log.isLoggable(PlatformLogger.FINER)) {
|
||||
log.finer("XCP coalescePaintEvent : UPDATE : add : x = " +
|
||||
r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height);
|
||||
}
|
||||
return;
|
||||
case PaintEvent.PAINT:
|
||||
log.finer("XCP coalescePaintEvent : PAINT : add : x = " +
|
||||
if (log.isLoggable(PlatformLogger.FINER)) {
|
||||
log.finer("XCP coalescePaintEvent : PAINT : add : x = " +
|
||||
r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1248,7 +1252,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
|||
* ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify
|
||||
*/
|
||||
protected boolean isEventDisabled(XEvent e) {
|
||||
enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable"));
|
||||
if (enableLog.isLoggable(PlatformLogger.FINEST)) {
|
||||
enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable"));
|
||||
}
|
||||
if (!isEnabled()) {
|
||||
switch (e.get_type()) {
|
||||
case XConstants.ButtonPress:
|
||||
|
@ -1258,7 +1264,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
|||
case XConstants.EnterNotify:
|
||||
case XConstants.LeaveNotify:
|
||||
case XConstants.MotionNotify:
|
||||
enableLog.finer("Event {0} is disable", e);
|
||||
if (enableLog.isLoggable(PlatformLogger.FINER)) {
|
||||
enableLog.finer("Event {0} is disable", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -678,7 +678,7 @@ public class WrapperGenerator {
|
|||
public void writeToString(StructType stp, PrintWriter pw) {
|
||||
int type;
|
||||
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() ;) {
|
||||
AtomicType tp = (AtomicType) e.nextElement();
|
||||
|
@ -688,24 +688,24 @@ public class WrapperGenerator {
|
|||
if ((name != null) && (name.length() > 0))
|
||||
{
|
||||
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")) {
|
||||
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")){
|
||||
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) {
|
||||
pw.print("\t\tret += \"{\"");
|
||||
pw.print("\t\tret.append(\"{\")");
|
||||
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 {
|
||||
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) {
|
||||
|
|
|
@ -38,7 +38,9 @@ import java.io.InputStreamReader;
|
|||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Vector;
|
||||
|
||||
|
@ -955,23 +957,49 @@ public class UnixPrintJob implements CancelablePrintJob {
|
|||
private class PrinterSpooler implements java.security.PrivilegedAction {
|
||||
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() {
|
||||
if (spoolFile == null || !spoolFile.exists()) {
|
||||
pex = new PrintException("No spool file");
|
||||
notifyEvent(PrintJobEvent.JOB_FAILED);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Spool to the printer.
|
||||
*/
|
||||
if (spoolFile == null || !spoolFile.exists()) {
|
||||
pex = new PrintException("No spool file");
|
||||
notifyEvent(PrintJobEvent.JOB_FAILED);
|
||||
return null;
|
||||
}
|
||||
String fileName = spoolFile.getAbsolutePath();
|
||||
String execCmd[] = printExecCmd(mDestination, mOptions,
|
||||
mNoJobSheet, jobName, copies, fileName);
|
||||
|
||||
Process process = Runtime.getRuntime().exec(execCmd);
|
||||
process.waitFor();
|
||||
spoolFile.delete();
|
||||
final int result = process.exitValue();
|
||||
if (0 != result) {
|
||||
handleProcessFailure(process, execCmd, result);
|
||||
}
|
||||
notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
|
||||
} catch (IOException ex) {
|
||||
notifyEvent(PrintJobEvent.JOB_FAILED);
|
||||
|
@ -981,6 +1009,7 @@ public class UnixPrintJob implements CancelablePrintJob {
|
|||
notifyEvent(PrintJobEvent.JOB_FAILED);
|
||||
pex = new PrintException(ie);
|
||||
} finally {
|
||||
spoolFile.delete();
|
||||
notifyEvent(PrintJobEvent.NO_MORE_EVENTS);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -43,8 +43,9 @@
|
|||
#include "java_net_Inet4AddressImpl.h"
|
||||
|
||||
/* the initial size of our hostent buffers */
|
||||
#define HENT_BUF_SIZE 1024
|
||||
#define BIG_HENT_BUF_SIZE 10240 /* a jumbo-sized one */
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* Inet4AddressImpl
|
||||
|
@ -57,60 +58,36 @@
|
|||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
|
||||
char hostname[MAXHOSTNAMELEN+1];
|
||||
char hostname[NI_MAXHOST+1];
|
||||
|
||||
hostname[0] = '\0';
|
||||
if (JVM_GetHostName(hostname, sizeof(hostname))) {
|
||||
/* Something went wrong, maybe networking is not setup? */
|
||||
strcpy(hostname, "localhost");
|
||||
} else {
|
||||
#ifdef __linux__
|
||||
/* On Linux gethostname() says "host.domain.sun.com". On
|
||||
* 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;
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
|
||||
// ensure null-terminated
|
||||
hostname[MAXHOSTNAMELEN] = '\0';
|
||||
hostname[NI_MAXHOST] = '\0';
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
#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
|
||||
if (hp) {
|
||||
#ifdef __GLIBC__
|
||||
gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
|
||||
&res2, (char*)buf2, sizeof(buf2), &hp, &h_error);
|
||||
#else
|
||||
hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
|
||||
&res2, (char*)buf2, sizeof(buf2), &h_error);
|
||||
#endif
|
||||
if (hp) {
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
if (error == 0) {/* host is known to name service */
|
||||
getnameinfo(res->ai_addr,
|
||||
res->ai_addrlen,
|
||||
hostname,
|
||||
NI_MAXHOST,
|
||||
NULL,
|
||||
0,
|
||||
NI_NAMEREQD);
|
||||
|
||||
/* if getnameinfo fails hostname is still the value
|
||||
from gethostname */
|
||||
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
}
|
||||
return (*env)->NewStringUTF(env, hostname);
|
||||
|
@ -140,14 +117,9 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
|||
jstring host) {
|
||||
const char *hostname;
|
||||
jobjectArray ret = 0;
|
||||
struct hostent res, *hp = 0;
|
||||
// this buffer must be pointer-aligned so is declared
|
||||
// with pointer type
|
||||
char *buf[HENT_BUF_SIZE/(sizeof (char *))];
|
||||
|
||||
/* temporary buffer, on the off chance we need to expand */
|
||||
char *tmp = NULL;
|
||||
int h_error=0;
|
||||
int retLen = 0;
|
||||
int error = 0;
|
||||
struct addrinfo hints, *res, *resNew = NULL;
|
||||
|
||||
if (!initialized) {
|
||||
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);
|
||||
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__
|
||||
/*
|
||||
* Workaround for Solaris bug 4160367 - if a hostname contains a
|
||||
|
@ -181,69 +158,93 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Try once, with our static buffer. */
|
||||
#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
|
||||
error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
/* With the re-entrant system calls, it's possible that the buffer
|
||||
* we pass to it is not large enough to hold an exceptionally
|
||||
* large DNS entry. This is signaled by errno->ERANGE. We try once
|
||||
* more, with a very big size.
|
||||
*/
|
||||
if (hp == NULL && errno == ERANGE) {
|
||||
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;
|
||||
if (error) {
|
||||
/* report error */
|
||||
ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
} else {
|
||||
int i = 0;
|
||||
struct addrinfo *itr, *last = NULL, *iterator = res;
|
||||
|
||||
while (*addrp != (struct in_addr *) 0) {
|
||||
i++;
|
||||
addrp++;
|
||||
while (iterator != NULL) {
|
||||
// remove the duplicate one
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL);
|
||||
retLen = i;
|
||||
iterator = resNew;
|
||||
|
||||
ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
|
||||
|
||||
if (IS_NULL(ret)) {
|
||||
/* we may have memory to free at the end of this */
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
addrp = (struct in_addr **) hp->h_addr_list;
|
||||
|
||||
i = 0;
|
||||
while (*addrp) {
|
||||
jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
|
||||
if (IS_NULL(iaObj)) {
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetIntField(env, iaObj, ni_iaaddressID,
|
||||
ntohl((*addrp)->s_addr));
|
||||
(*env)->SetObjectField(env, iaObj, ni_iahostID, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, i, iaObj);
|
||||
addrp++;
|
||||
i++;
|
||||
while (iterator != NULL) {
|
||||
jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
|
||||
if (IS_NULL(iaObj)) {
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetIntField(env, iaObj, ni_iaaddressID,
|
||||
ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
|
||||
(*env)->SetObjectField(env, iaObj, ni_iahostID, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, i++, iaObj);
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
} else {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
|
||||
(char *)hostname);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
cleanupAndReturn:
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
if (tmp != NULL) {
|
||||
free(tmp);
|
||||
cleanupAndReturn:
|
||||
{
|
||||
struct addrinfo *iterator, *tmp;
|
||||
iterator = resNew;
|
||||
while (iterator != NULL) {
|
||||
tmp = iterator;
|
||||
iterator = iterator->ai_next;
|
||||
free(tmp);
|
||||
}
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -256,63 +257,38 @@ JNIEXPORT jstring JNICALL
|
|||
Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
|
||||
jbyteArray addrArray) {
|
||||
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;
|
||||
|
||||
/*
|
||||
* We are careful here to use the reentrant version of
|
||||
* gethostbyname because at the Java level this routine is not
|
||||
* protected by any synchronization.
|
||||
*
|
||||
* Still keeping the reentrant platform dependent calls temporarily
|
||||
* We should probably conform to one interface later.
|
||||
*
|
||||
*/
|
||||
char host[NI_MAXHOST+1];
|
||||
int error = 0;
|
||||
int len = 0;
|
||||
jbyte caddr[4];
|
||||
|
||||
struct sockaddr_in him4;
|
||||
struct sockaddr *sa;
|
||||
|
||||
jint addr;
|
||||
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
|
||||
addr = ((caddr[0]<<24) & 0xff000000);
|
||||
addr |= ((caddr[1] <<16) & 0xff0000);
|
||||
addr |= ((caddr[2] <<8) & 0xff00);
|
||||
addr |= (caddr[3] & 0xff);
|
||||
addr = htonl(addr);
|
||||
#ifdef __GLIBC__
|
||||
gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
|
||||
(char*)buf, sizeof(buf), &hp, &h_error);
|
||||
#else
|
||||
hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
|
||||
(char*)buf, sizeof(buf), &h_error);
|
||||
#endif
|
||||
/* With the re-entrant system calls, it's possible that the buffer
|
||||
* we pass to it is not large enough to hold an exceptionally
|
||||
* large DNS entry. This is signaled by errno->ERANGE. We try once
|
||||
* 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");
|
||||
}
|
||||
memset((void *) &him4, 0, sizeof(him4));
|
||||
him4.sin_addr.s_addr = (uint32_t) htonl(addr);
|
||||
him4.sin_family = AF_INET;
|
||||
sa = (struct sockaddr *) &him4;
|
||||
len = sizeof(him4);
|
||||
|
||||
error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
|
||||
if (!error) {
|
||||
ret = (*env)->NewStringUTF(env, host);
|
||||
}
|
||||
if (hp == NULL) {
|
||||
|
||||
if (ret == NULL) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
|
||||
} else {
|
||||
ret = (*env)->NewStringUTF(env, hp->h_name);
|
||||
}
|
||||
if (tmp) {
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,31 +82,29 @@ Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
|
|||
* We use thread-safe system calls.
|
||||
*/
|
||||
#ifdef AF_INET6
|
||||
if (NET_addrtransAvailable()) {
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
|
||||
bzero(&hints, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
||||
error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
|
||||
error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
if (error == 0) {
|
||||
/* host is known to name service */
|
||||
error = (*getnameinfo_ptr)(res->ai_addr,
|
||||
res->ai_addrlen,
|
||||
hostname,
|
||||
NI_MAXHOST,
|
||||
NULL,
|
||||
0,
|
||||
NI_NAMEREQD);
|
||||
if (error == 0) {
|
||||
/* host is known to name service */
|
||||
error = getnameinfo(res->ai_addr,
|
||||
res->ai_addrlen,
|
||||
hostname,
|
||||
NI_MAXHOST,
|
||||
NULL,
|
||||
0,
|
||||
NI_NAMEREQD);
|
||||
|
||||
/* if getnameinfo fails hostname is still the value
|
||||
from gethostname */
|
||||
/* if getnameinfo fails hostname is still the value
|
||||
from gethostname */
|
||||
|
||||
(*freeaddrinfo_ptr)(res);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
#endif /* __linux__ */
|
||||
|
@ -173,193 +171,191 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
|||
CHECK_NULL_RETURN(hostname, NULL);
|
||||
|
||||
#ifdef AF_INET6
|
||||
if (NET_addrtransAvailable()) {
|
||||
static jfieldID ia_preferIPv6AddressID;
|
||||
if (ia_preferIPv6AddressID == NULL) {
|
||||
jclass c = (*env)->FindClass(env,"java/net/InetAddress");
|
||||
if (c) {
|
||||
ia_preferIPv6AddressID =
|
||||
(*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
|
||||
}
|
||||
if (ia_preferIPv6AddressID == NULL) {
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
}
|
||||
static jfieldID ia_preferIPv6AddressID;
|
||||
if (ia_preferIPv6AddressID == NULL) {
|
||||
jclass c = (*env)->FindClass(env,"java/net/InetAddress");
|
||||
if (c) {
|
||||
ia_preferIPv6AddressID =
|
||||
(*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
|
||||
}
|
||||
/* get the address preference */
|
||||
preferIPv6Address
|
||||
= (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
|
||||
if (ia_preferIPv6AddressID == NULL) {
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* get the address preference */
|
||||
preferIPv6Address
|
||||
= (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
|
||||
|
||||
/* Try once, with our static buffer. */
|
||||
bzero(&hints, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
/* Try once, with our static buffer. */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
||||
#ifdef __solaris__
|
||||
/*
|
||||
* Workaround for Solaris bug 4160367 - if a hostname contains a
|
||||
* white space then 0.0.0.0 is returned
|
||||
*/
|
||||
if (isspace((unsigned char)hostname[0])) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
|
||||
hostname);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Workaround for Solaris bug 4160367 - if a hostname contains a
|
||||
* white space then 0.0.0.0 is returned
|
||||
*/
|
||||
if (isspace((unsigned char)hostname[0])) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
|
||||
hostname);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
|
||||
error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
if (error) {
|
||||
/* report error */
|
||||
ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
} else {
|
||||
int i = 0;
|
||||
int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
|
||||
struct addrinfo *itr, *last = NULL, *iterator = res;
|
||||
while (iterator != NULL) {
|
||||
int skip = 0;
|
||||
itr = resNew;
|
||||
while (itr != NULL) {
|
||||
if (iterator->ai_family == itr->ai_family &&
|
||||
iterator->ai_addrlen == itr->ai_addrlen) {
|
||||
if (itr->ai_family == AF_INET) { /* AF_INET */
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
int t;
|
||||
struct sockaddr_in6 *addr1, *addr2;
|
||||
addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
|
||||
addr2 = (struct sockaddr_in6 *)itr->ai_addr;
|
||||
if (error) {
|
||||
/* report error */
|
||||
ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
} else {
|
||||
int i = 0;
|
||||
int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
|
||||
struct addrinfo *itr, *last = NULL, *iterator = res;
|
||||
while (iterator != NULL) {
|
||||
int skip = 0;
|
||||
itr = resNew;
|
||||
while (itr != NULL) {
|
||||
if (iterator->ai_family == itr->ai_family &&
|
||||
iterator->ai_addrlen == itr->ai_addrlen) {
|
||||
if (itr->ai_family == AF_INET) { /* AF_INET */
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
int t;
|
||||
struct sockaddr_in6 *addr1, *addr2;
|
||||
addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
|
||||
addr2 = (struct sockaddr_in6 *)itr->ai_addr;
|
||||
|
||||
for (t = 0; t < 16; t++) {
|
||||
if (addr1->sin6_addr.s6_addr[t] !=
|
||||
addr2->sin6_addr.s6_addr[t]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t < 16) {
|
||||
itr = itr->ai_next;
|
||||
continue;
|
||||
} else {
|
||||
skip = 1;
|
||||
for (t = 0; t < 16; t++) {
|
||||
if (addr1->sin6_addr.s6_addr[t] !=
|
||||
addr2->sin6_addr.s6_addr[t]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (iterator->ai_family != AF_INET &&
|
||||
iterator->ai_family != AF_INET6) {
|
||||
/* we can't handle other family types */
|
||||
skip = 1;
|
||||
break;
|
||||
if (t < 16) {
|
||||
itr = itr->ai_next;
|
||||
continue;
|
||||
} else {
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
itr = itr->ai_next;
|
||||
} else if (iterator->ai_family != AF_INET &&
|
||||
iterator->ai_family != AF_INET6) {
|
||||
/* we can't handle other family types */
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
itr = itr->ai_next;
|
||||
}
|
||||
|
||||
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++;
|
||||
if (iterator->ai_family == AF_INET) {
|
||||
inetCount ++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
inet6Count ++;
|
||||
}
|
||||
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++;
|
||||
if (iterator->ai_family == AF_INET) {
|
||||
inetCount ++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
inet6Count ++;
|
||||
}
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
retLen = i;
|
||||
iterator = resNew;
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
retLen = i;
|
||||
iterator = resNew;
|
||||
|
||||
ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
|
||||
ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
|
||||
|
||||
if (IS_NULL(ret)) {
|
||||
/* we may have memory to free at the end of this */
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
if (IS_NULL(ret)) {
|
||||
/* we may have memory to free at the end of this */
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
if (preferIPv6Address) {
|
||||
/* AF_INET addresses will be offset by inet6Count */
|
||||
inetIndex = inet6Count;
|
||||
inet6Index = 0;
|
||||
} else {
|
||||
/* AF_INET6 addresses will be offset by inetCount */
|
||||
inetIndex = 0;
|
||||
inet6Index = inetCount;
|
||||
}
|
||||
if (preferIPv6Address) {
|
||||
/* AF_INET addresses will be offset by inet6Count */
|
||||
inetIndex = inet6Count;
|
||||
inet6Index = 0;
|
||||
} else {
|
||||
/* AF_INET6 addresses will be offset by inetCount */
|
||||
inetIndex = 0;
|
||||
inet6Index = inetCount;
|
||||
}
|
||||
|
||||
while (iterator != NULL) {
|
||||
if (iterator->ai_family == AF_INET) {
|
||||
while (iterator != NULL) {
|
||||
if (iterator->ai_family == AF_INET) {
|
||||
jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
|
||||
if (IS_NULL(iaObj)) {
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetIntField(env, iaObj, ni_iaaddressID,
|
||||
ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
|
||||
(*env)->SetObjectField(env, iaObj, ni_iahostID, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
|
||||
inetIndex++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
jint scope = 0;
|
||||
jbyteArray ipaddress;
|
||||
|
||||
jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
|
||||
if (IS_NULL(iaObj)) {
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
ipaddress = (*env)->NewByteArray(env, 16);
|
||||
if (IS_NULL(ipaddress)) {
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
|
||||
(jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
|
||||
#ifdef __linux__
|
||||
if (!kernelIsV22()) {
|
||||
scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
|
||||
scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
|
||||
}
|
||||
#else
|
||||
scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
|
||||
#endif
|
||||
if (scope != 0) { /* zero is default value, no need to set */
|
||||
(*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
|
||||
(*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
|
||||
(*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
|
||||
(*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
|
||||
}
|
||||
(*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
|
||||
(*env)->SetObjectField(env, iaObj, ni_iahostID, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
|
||||
inet6Index++;
|
||||
}
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
cleanupAndReturn:
|
||||
cleanupAndReturn:
|
||||
{
|
||||
struct addrinfo *iterator, *tmp;
|
||||
struct addrinfo *iterator, *tmp;
|
||||
iterator = resNew;
|
||||
while (iterator != NULL) {
|
||||
tmp = iterator;
|
||||
|
@ -369,8 +365,7 @@ cleanupAndReturn:
|
|||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
}
|
||||
|
||||
if (NET_addrtransAvailable())
|
||||
(*freeaddrinfo_ptr)(res);
|
||||
freeaddrinfo(res);
|
||||
#endif /* AF_INET6 */
|
||||
|
||||
return ret;
|
||||
|
@ -393,44 +388,42 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
|
|||
int len = 0;
|
||||
jbyte caddr[16];
|
||||
|
||||
if (NET_addrtransAvailable()) {
|
||||
struct sockaddr_in him4;
|
||||
struct sockaddr_in6 him6;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_in him4;
|
||||
struct sockaddr_in6 him6;
|
||||
struct sockaddr *sa;
|
||||
|
||||
/*
|
||||
* For IPv4 addresses construct a sockaddr_in structure.
|
||||
*/
|
||||
if ((*env)->GetArrayLength(env, addrArray) == 4) {
|
||||
jint addr;
|
||||
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
|
||||
addr = ((caddr[0]<<24) & 0xff000000);
|
||||
addr |= ((caddr[1] <<16) & 0xff0000);
|
||||
addr |= ((caddr[2] <<8) & 0xff00);
|
||||
addr |= (caddr[3] & 0xff);
|
||||
memset((void *) &him4, 0, sizeof(him4));
|
||||
him4.sin_addr.s_addr = (uint32_t) htonl(addr);
|
||||
him4.sin_family = AF_INET;
|
||||
sa = (struct sockaddr *) &him4;
|
||||
len = sizeof(him4);
|
||||
} else {
|
||||
/*
|
||||
* For IPv4 addresses construct a sockaddr_in structure.
|
||||
* For IPv6 address construct a sockaddr_in6 structure.
|
||||
*/
|
||||
if ((*env)->GetArrayLength(env, addrArray) == 4) {
|
||||
jint addr;
|
||||
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
|
||||
addr = ((caddr[0]<<24) & 0xff000000);
|
||||
addr |= ((caddr[1] <<16) & 0xff0000);
|
||||
addr |= ((caddr[2] <<8) & 0xff00);
|
||||
addr |= (caddr[3] & 0xff);
|
||||
memset((void *) &him4, 0, sizeof(him4));
|
||||
him4.sin_addr.s_addr = (uint32_t) htonl(addr);
|
||||
him4.sin_family = AF_INET;
|
||||
sa = (struct sockaddr *) &him4;
|
||||
len = sizeof(him4);
|
||||
} else {
|
||||
/*
|
||||
* For IPv6 address construct a sockaddr_in6 structure.
|
||||
*/
|
||||
(*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
|
||||
memset((void *) &him6, 0, sizeof(him6));
|
||||
memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
|
||||
him6.sin6_family = AF_INET6;
|
||||
sa = (struct sockaddr *) &him6 ;
|
||||
len = sizeof(him6) ;
|
||||
}
|
||||
(*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
|
||||
memset((void *) &him6, 0, sizeof(him6));
|
||||
memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
|
||||
him6.sin6_family = AF_INET6;
|
||||
sa = (struct sockaddr *) &him6 ;
|
||||
len = sizeof(him6) ;
|
||||
}
|
||||
|
||||
error = (*getnameinfo_ptr)(sa, len, host, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
|
||||
if (!error) {
|
||||
ret = (*env)->NewStringUTF(env, host);
|
||||
}
|
||||
if (!error) {
|
||||
ret = (*env)->NewStringUTF(env, host);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
|
||||
|
|
|
@ -377,37 +377,12 @@ jint IPv6_supported()
|
|||
* we should also check if the APIs are available.
|
||||
*/
|
||||
ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton");
|
||||
if (ipv6_fn == NULL ) {
|
||||
close(fd);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
if (ipv6_fn == NULL ) {
|
||||
return JNI_FALSE;
|
||||
} else {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
}
|
||||
|
||||
|
@ -920,10 +895,6 @@ NET_IsEqual(jbyte* caddr1, jbyte* caddr2) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
jboolean NET_addrtransAvailable() {
|
||||
return (jboolean)(getaddrinfo_ptr != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the Java level socket option to the platform specific
|
||||
* level and option name.
|
||||
|
|
|
@ -102,10 +102,6 @@ void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
|
|||
const char* hostname,
|
||||
int gai_error);
|
||||
|
||||
/* do we have address translation support */
|
||||
|
||||
extern jboolean NET_addrtransAvailable();
|
||||
|
||||
#define NET_WAIT_READ 0x01
|
||||
#define NET_WAIT_WRITE 0x02
|
||||
#define NET_WAIT_CONNECT 0x04
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <inttypes.h>
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,7 +25,8 @@
|
|||
|
||||
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
|
||||
|
@ -45,13 +46,9 @@ public final class FileDescriptor {
|
|||
|
||||
private long handle;
|
||||
|
||||
/**
|
||||
* A use counter for tracking the FIS/FOS/RAF instances that
|
||||
* use this FileDescriptor. The FIS/FOS.finalize() will not release
|
||||
* the FileDescriptor if it is still under use by any stream.
|
||||
*/
|
||||
private AtomicInteger useCount;
|
||||
|
||||
private Closeable parent;
|
||||
private List<Closeable> otherParents;
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* Constructs an (invalid) FileDescriptor
|
||||
|
@ -60,7 +57,6 @@ public final class FileDescriptor {
|
|||
public /**/ FileDescriptor() {
|
||||
fd = -1;
|
||||
handle = -1;
|
||||
useCount = new AtomicInteger();
|
||||
}
|
||||
|
||||
static {
|
||||
|
@ -168,13 +164,67 @@ public final class FileDescriptor {
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,10 +60,11 @@ final class ProcessImpl extends Process {
|
|||
throws IOException
|
||||
{
|
||||
if (append) {
|
||||
String path = f.getPath();
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkWrite(f.getPath());
|
||||
long handle = openForAtomicAppend(f.getPath());
|
||||
sm.checkWrite(path);
|
||||
long handle = openForAtomicAppend(path);
|
||||
final FileDescriptor fd = new FileDescriptor();
|
||||
fdAccess.setHandle(fd, handle);
|
||||
return AccessController.doPrivileged(
|
||||
|
|
|
@ -314,7 +314,7 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
|||
|
||||
void socketSetOption(int cmd, boolean on, Object value)
|
||||
throws SocketException {
|
||||
socketSetOption(cmd, on, value);
|
||||
impl.socketSetOption(cmd, on, value);
|
||||
}
|
||||
|
||||
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue