This commit is contained in:
J. Duke 2021-03-03 07:58:53 -08:00
commit 27e2c0c520
172 changed files with 2888 additions and 1595 deletions

View File

@ -241,3 +241,4 @@ cbfe5da942c63ef865cab4a7159e01eff7d7fcf5 jdk8-b116
a4afb0a8d55ef75aef5b0d77b434070468fb89f8 jdk8-b117
0a6db1aac998cdc88e52f9adb97d40ca5b0f1da6 jdk8-b118
9e90215673be68a3e77a9e444e4232076373734d jdk8-b119
cd3825b2983045784d6fc6d1729c799b08215752 jdk8-b120

View File

@ -1 +1,2 @@
project=jdk8
bugids=dup

View File

@ -3865,7 +3865,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1384422786
DATE_WHEN_GENERATED=1387198493
###############################################################################
#
@ -11156,6 +11156,12 @@ fi
as_fn_error $? "Update version must have a value" "$LINENO" 5
elif test "x$with_update_version" != x; then
JDK_UPDATE_VERSION="$with_update_version"
# On macosx 10.7, it's not possible to set --with-update-version=0X due
# to a bug in expr (which reduces it to just X). To work around this, we
# always add a 0 to one digit update versions.
if test "${#JDK_UPDATE_VERSION}" = "1"; then
JDK_UPDATE_VERSION="0${JDK_UPDATE_VERSION}"
fi
fi

View File

@ -423,6 +423,12 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_VERSION_NUMBERS],
AC_MSG_ERROR([Update version must have a value])
elif test "x$with_update_version" != x; then
JDK_UPDATE_VERSION="$with_update_version"
# On macosx 10.7, it's not possible to set --with-update-version=0X due
# to a bug in expr (which reduces it to just X). To work around this, we
# always add a 0 to one digit update versions.
if test "${#JDK_UPDATE_VERSION}" = "1"; then
JDK_UPDATE_VERSION="0${JDK_UPDATE_VERSION}"
fi
fi
AC_ARG_WITH(user-release-suffix, [AS_HELP_STRING([--with-user-release-suffix],

View File

@ -401,3 +401,4 @@ c9f439732b18ea16f7e65815327d5ea7092cc258 jdk8-b118
b2426da30009cd3069d03de073f351e6432c7682 hs25-b61
ce42d815dd2130250acf6132b51b624001638f0d jdk8-b119
05fedd51e40da22c9460bf17c7185889e435db3d hs25-b62
fca262db9c4309f99d2f5542ab0780e45c2f1578 jdk8-b120

View File

@ -1 +1,2 @@
project=jdk8
bugids=dup

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2006, 2014, 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
@ -31,11 +31,11 @@
#
# Don't put quotes (fail windows build).
HOTSPOT_VM_COPYRIGHT=Copyright 2013
HOTSPOT_VM_COPYRIGHT=Copyright 2014
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=62
HS_MINOR_VER=5
HS_BUILD_NUMBER=01
JDK_MAJOR_VER=1
JDK_MINOR_VER=8

View File

@ -175,8 +175,8 @@ oop MethodHandles::init_MemberName(Handle mname, Handle target) {
oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
assert(info.resolved_appendix().is_null(), "only normal methods here");
KlassHandle receiver_limit = info.resolved_klass();
methodHandle m = info.resolved_method();
KlassHandle m_klass = m->method_holder();
int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
int vmindex = Method::invalid_vtable_index;
@ -184,14 +184,13 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
case CallInfo::itable_call:
vmindex = info.itable_index();
// More importantly, the itable index only works with the method holder.
receiver_limit = m->method_holder();
assert(receiver_limit->verify_itable_index(vmindex), "");
assert(m_klass->verify_itable_index(vmindex), "");
flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
if (TraceInvokeDynamic) {
ResourceMark rm;
tty->print_cr("memberName: invokeinterface method_holder::method: %s, receiver: %s, itableindex: %d, access_flags:",
Method::name_and_sig_as_C_string(receiver_limit(), m->name(), m->signature()),
receiver_limit()->internal_name(), vmindex);
tty->print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:",
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
vmindex);
m->access_flags().print_on(tty);
if (!m->is_abstract()) {
tty->print("default");
@ -203,12 +202,35 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
case CallInfo::vtable_call:
vmindex = info.vtable_index();
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe");
assert(info.resolved_klass()->is_subtype_of(m_klass()), "virtual call must be type-safe");
if (m_klass->is_interface()) {
// This is a vtable call to an interface method (abstract "miranda method" or default method).
// The vtable index is meaningless without a class (not interface) receiver type, so get one.
// (LinkResolver should help us figure this out.)
KlassHandle m_klass_non_interface = info.resolved_klass();
if (m_klass_non_interface->is_interface()) {
m_klass_non_interface = SystemDictionary::Object_klass();
#ifdef ASSERT
{ ResourceMark rm;
Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex);
assert(m->name() == m2->name() && m->signature() == m2->signature(),
err_msg("at %d, %s != %s", vmindex,
m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string()));
}
#endif //ASSERT
}
if (!m->is_public()) {
assert(m->is_public(), "virtual call must be to public interface method");
return NULL; // elicit an error later in product build
}
assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface()), "virtual call must be type-safe");
m_klass = m_klass_non_interface;
}
if (TraceInvokeDynamic) {
ResourceMark rm;
tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
Method::name_and_sig_as_C_string(receiver_limit(), m->name(), m->signature()),
receiver_limit()->internal_name(), vmindex);
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
m_klass->internal_name(), vmindex);
m->access_flags().print_on(tty);
if (m->is_default_method()) {
tty->print("default");
@ -223,10 +245,8 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
} else if (m->is_initializer()) {
flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed");
} else {
flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe");
}
break;
@ -242,7 +262,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
java_lang_invoke_MemberName::set_flags( mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, m());
java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index
java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror());
java_lang_invoke_MemberName::set_clazz( mname_oop, m_klass->java_mirror());
// Note: name and type can be lazily computed by resolve_MemberName,
// if Java code needs them as resolved String and MethodType objects.
// The clazz must be eagerly stored, because it provides a GC
@ -569,7 +589,7 @@ oop MethodHandles::field_signature_type_or_null(Symbol* s) {
// An unresolved member name is a mere symbolic reference.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS) {
Handle empty;
assert(java_lang_invoke_MemberName::is_instance(mname()), "");
@ -646,20 +666,20 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
assert(!HAS_PENDING_EXCEPTION, "");
if (ref_kind == JVM_REF_invokeStatic) {
LinkResolver::resolve_static_call(result,
defc, name, type, KlassHandle(), false, false, THREAD);
defc, name, type, caller, caller.not_null(), false, THREAD);
} else if (ref_kind == JVM_REF_invokeInterface) {
LinkResolver::resolve_interface_call(result, Handle(), defc,
defc, name, type, KlassHandle(), false, false, THREAD);
defc, name, type, caller, caller.not_null(), false, THREAD);
} else if (mh_invoke_id != vmIntrinsics::_none) {
assert(!is_signature_polymorphic_static(mh_invoke_id), "");
LinkResolver::resolve_handle_call(result,
defc, name, type, KlassHandle(), THREAD);
defc, name, type, caller, THREAD);
} else if (ref_kind == JVM_REF_invokeSpecial) {
LinkResolver::resolve_special_call(result,
defc, name, type, KlassHandle(), false, THREAD);
defc, name, type, caller, caller.not_null(), THREAD);
} else if (ref_kind == JVM_REF_invokeVirtual) {
LinkResolver::resolve_virtual_call(result, Handle(), defc,
defc, name, type, KlassHandle(), false, false, THREAD);
defc, name, type, caller, caller.not_null(), false, THREAD);
} else {
assert(false, err_msg("ref_kind=%d", ref_kind));
}
@ -683,7 +703,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
assert(!HAS_PENDING_EXCEPTION, "");
if (name == vmSymbols::object_initializer_name()) {
LinkResolver::resolve_special_call(result,
defc, name, type, KlassHandle(), false, THREAD);
defc, name, type, caller, caller.not_null(), THREAD);
} else {
break; // will throw after end of switch
}
@ -700,7 +720,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
fieldDescriptor result; // find_field initializes fd if found
{
assert(!HAS_PENDING_EXCEPTION, "");
LinkResolver::resolve_field(result, defc, name, type, KlassHandle(), Bytecodes::_nop, false, false, THREAD);
LinkResolver::resolve_field(result, defc, name, type, caller, Bytecodes::_nop, false, false, THREAD);
if (HAS_PENDING_EXCEPTION) {
return empty;
}
@ -1121,7 +1141,11 @@ JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh,
}
}
Handle resolved = MethodHandles::resolve_MemberName(mname, CHECK_NULL);
KlassHandle caller(THREAD,
caller_jh == NULL ? (Klass*) NULL :
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh)));
Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
if (resolved.is_null()) {
int flags = java_lang_invoke_MemberName::flags(mname());
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;

View File

@ -55,7 +55,7 @@ class MethodHandles: AllStatic {
public:
// working with member names
static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
static Handle resolve_MemberName(Handle mname, KlassHandle caller, TRAPS); // compute vmtarget/vmindex from name/type
static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing
static Handle new_MemberName(TRAPS); // must be followed by init_MemberName
static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target

View File

@ -1264,9 +1264,6 @@ bool os::set_boot_path(char fileSep, char pathSep) {
"%/lib/jce.jar:"
"%/lib/charsets.jar:"
"%/lib/jfr.jar:"
#ifdef __APPLE__
"%/lib/JObjC.jar:"
#endif
"%/classes";
char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);
if (sysclasspath == NULL) return false;

View File

@ -241,3 +241,4 @@ f82b730c798b6bf38946baaba8a7d80fd5efaa70 jdk8-b115
fc4ac66aa657e09de5f8257c3174f240ed0cbaf7 jdk8-b117
28ca338366ff2774ac9002f9f6eaff4101a3ea3b jdk8-b118
e4499a6529e8c3e762ba86f45cdd774c92a8e7bc jdk8-b119
d31cd980e1da31fa496a359caaf1a165aeb5791a jdk8-b120

View File

@ -1 +1,2 @@
project=jdk8
bugids=dup

View File

@ -274,11 +274,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java \
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
# JObjC.jar contains 1.5 byte-code...so skip it here :-(
# MACOSX_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/jobjc/src
# EXCLUDES += tests/java/com/apple/jobjc
EXCLUDES += com/apple/jobjc
endif
# The security classes should not end up in the classes directory as that will prevent them
@ -354,44 +349,6 @@ $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin:
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
#
# JObjC.jar is compiled with BOOT_JAVAC which (may) not support the "-h" flag.
# so we first compile classes with BOOT_JAVAC and then with JDK_JAVAC :-(
#
$(eval $(call SetupJavaCompiler,GENERATE_15BYTECODE, \
JAVAC := $(JAVAC), \
FLAGS := -source 1.5 -target 1.5 -g -bootclasspath $(BOOT_RTJAR) -cp $(JDK_OUTPUTDIR)/../langtools/dist/lib/classes.jar $(DISABLE_WARNINGS), \
SERVER_DIR := $(SJAVAC_SERVER_DIR), \
SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
$(eval $(call SetupJavaCompilation,BUILD_JOBJC, \
SETUP := GENERATE_15BYTECODE, \
DISABLE_SJAVAC := true, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc, \
EXCLUDES := tests/java/com/apple/jobjc, \
BIN := $(JDK_OUTPUTDIR)/jobjc_classes, \
JAR := $(JDK_OUTPUTDIR)/lib/JObjC.jar, \
JARINDEX := true))
$(BUILD_JOBJC): $(BUILD_JDK)
$(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS, \
SETUP := GENERATE_JDKBYTECODE, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc, \
EXCLUDES := tests/java/com/apple/jobjc, \
BIN := $(JDK_OUTPUTDIR)/jobjc_classes_headers, \
HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers_jobjc))
$(BUILD_JOBJC_HEADERS): $(BUILD_JDK)
endif
##########################################################################################
@ -430,7 +387,7 @@ endif
##########################################################################################
all: $(BUILD_JDK) $(BUILD_SECURITY) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \
all: $(BUILD_JDK) $(BUILD_SECURITY) $(COPY_EXTRA) \
$(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin \
$(BUILD_ACCESSBRIDGE_32) $(BUILD_ACCESSBRIDGE_64) \
$(BUILD_ACCESSBRIDGE_LEGACY)

View File

@ -693,13 +693,6 @@ $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar: $(JDK_OUTPUTDIR)/demo/nio/zipfs/zipfs.jar
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
$(eval $(call SetupArchive,BUILD_JOBJC_JAR, , \
SRCS := $(JDK_OUTPUTDIR)/jobjc_classes, \
JAR := $(IMAGES_OUTPUTDIR)/lib/JObjC.jar, \
JARINDEX := true))
endif
# This file is imported from hotspot in Import.gmk. Copying it into images/lib so that
# all jars can be found in one place when creating images in Images.gmk. It needs to be
# done here so that clean targets can be simple and accurate.

View File

@ -85,11 +85,6 @@ GENSRC += $(GENSRC_CLDR)
include gensrc/GensrcSwing.gmk
GENSRC += $(GENSRC_SWING_BEANINFO) $(GENSRC_SWING_NIMBUS)
ifeq ($(OPENJDK_TARGET_OS), macosx)
include gensrc/GensrcJObjC.gmk
GENSRC += $(GENSRC_JOBJC)
endif
$(GENSRC): $(BUILD_TOOLS)
all: $(GENSRC)

View File

@ -303,14 +303,13 @@ $(JDK_IMAGE_DIR)/jre/lib/applet:
$(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(MKDIR) -p $@
# In the old build, JObjC.jar is not part of the meta-index
$(JRE_IMAGE_DIR)/lib/meta-index: $(JRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index `$(LS) *.jar | $(SED) 's/JObjC\.jar//g'`
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index *.jar
$(JDK_IMAGE_DIR)/jre/lib/meta-index: $(JDKJRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index `$(LS) *.jar | $(SED) 's/JObjC\.jar//g'`
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index *.jar
$(JRE_IMAGE_DIR)/lib/ext/meta-index: $(JRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)

View File

@ -105,10 +105,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
endif
ifeq ($(PROFILE), profile_1)
PROFILE_JARS := $(PROFILE_1_JARS)
else ifeq ($(PROFILE), profile_2)

View File

@ -25,6 +25,7 @@
LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/share/native/java/net \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/ \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/dns \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/spi

View File

@ -136,64 +136,6 @@ endif
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
$(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC32, \
LIBRARY := JObjC, \
OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := -fpascal-strings \
-fobjc-gc \
-gdwarf-2 \
$(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-m32, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
-m32, \
LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-lffi, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
$(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC64, \
LIBRARY := JObjC, \
OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := -fpascal-strings \
-fobjc-gc \
-gdwarf-2 \
$(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
, \
LDFLAGS := -fpascal-strings \
-fobjc-gc \
-gdwarf-2 \
$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-lffi, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
$(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX): $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64)
$(LIPO) -create -output $@ $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64)
BUILD_LIBRARIES += $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX)
endif
##########################################################################################
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)

View File

@ -86,6 +86,8 @@ SUNWprivate_1.1 {
Java_java_net_PlainSocketImpl_socketConnect;
Java_java_net_PlainDatagramSocketImpl_getTimeToLive;
Java_java_net_PlainDatagramSocketImpl_setTimeToLive;
Java_sun_net_PortConfig_getUpper0;
Java_sun_net_PortConfig_getLower0;
Java_sun_net_dns_ResolverConfigurationImpl_localDomain0;
Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0;
Java_sun_net_sdp_SdpSupport_convert0;

View File

@ -55,7 +55,7 @@ public class CClipboard extends SunClipboard {
}
protected void setContentsNative(Transferable contents) {
FlavorTable flavorMap = getDefaultFlavorTable();
// Don't use delayed Clipboard rendering for the Transferable's data.
// If we did that, we would call Transferable.getTransferData on
// the Toolkit thread, which is a security hole.

View File

@ -290,8 +290,8 @@ SplashEventLoop(Splash * splash) {
SplashUnlock(splash);
rc = poll(pfd, 1, timeout);
SplashLock(splash);
if (splash->isVisible>0 && SplashTime() >= splash->time +
splash->frames[splash->currentFrame].delay) {
if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
SplashNextFrame(splash);
SplashRedrawWindow(splash);
}

View File

@ -29,6 +29,7 @@ import com.sun.beans.finder.ClassFinder;
import java.beans.ExceptionListener;
import java.io.IOException;
import java.io.StringReader;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
@ -245,6 +246,14 @@ public final class DocumentHandler extends DefaultHandler {
this.objects.add(object);
}
/**
* Disables any external entities.
*/
@Override
public InputSource resolveEntity(String publicId, String systemId) {
return new InputSource(new StringReader(""));
}
/**
* Prepares this handler to read objects from XML document.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -72,13 +72,17 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
throw new IllegalStateException(
"TlsRsaPremasterSecretGenerator must be initialized");
}
if (random == null) {
random = new SecureRandom();
byte[] b = spec.getEncodedSecret();
if (b == null) {
if (random == null) {
random = new SecureRandom();
}
b = new byte[48];
random.nextBytes(b);
b[0] = (byte)spec.getMajorVersion();
b[1] = (byte)spec.getMinorVersion();
}
byte[] b = new byte[48];
random.nextBytes(b);
b[0] = (byte)spec.getMajorVersion();
b[1] = (byte)spec.getMinorVersion();
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
}

View File

@ -27,17 +27,9 @@ package com.sun.jmx.snmp.agent;
// java imports
//
import com.sun.jmx.snmp.SnmpDefinitions;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Enumeration;
// jmx imports
//
import com.sun.jmx.snmp.SnmpValue;
import com.sun.jmx.snmp.SnmpVarBind;
import com.sun.jmx.snmp.SnmpStatusException;
import com.sun.jmx.snmp.agent.SnmpMibOid;
import com.sun.jmx.snmp.agent.SnmpMibNode;
/**
* Represents a node in an SNMP MIB which corresponds to a table entry
@ -99,7 +91,9 @@ public abstract class SnmpMibEntry extends SnmpMibNode
*/
public void validateVarId(long arc, Object userData)
throws SnmpStatusException {
if (isVariable(arc) == false) throw noSuchNameException;
if (isVariable(arc) == false) {
throw new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
}
}
/**

View File

@ -108,8 +108,9 @@ public abstract class SnmpMibGroup extends SnmpMibOid
*/
public void validateVarId(long arc, Object userData)
throws SnmpStatusException {
if (isVariable(arc) == false)
throw noSuchObjectException;
if (isVariable(arc) == false) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
}
@ -360,17 +361,20 @@ public abstract class SnmpMibGroup extends SnmpMibOid
validateVarId(arc, data);
// The trailing .0 is missing in the OID
if (depth+2 > length)
throw noSuchInstanceException;
if (depth+2 > length) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// There are too many arcs left in the OID (there should remain
// a single trailing .0)
if (depth+2 < length)
throw noSuchInstanceException;
if (depth+2 < length) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// The last trailing arc is not .0
if (oid[depth+1] != 0L)
throw noSuchInstanceException;
if (oid[depth+1] != 0L) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// It's one of our variable, register this node.
handlers.add(this,depth,varbind);
@ -389,12 +393,13 @@ public abstract class SnmpMibGroup extends SnmpMibOid
int length = oid.length;
SnmpMibNode node = null;
if (handlers == null)
if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
@ -430,7 +435,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
depth+1,handlers,
checker);
}catch(SnmpStatusException ex) {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} finally {
checker.remove(depth);
}
@ -455,7 +460,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
try {
checker.checkCurrentOid();
} catch(SnmpStatusException e) {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} finally {
checker.remove(depth,2);
}
@ -500,7 +505,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
// The oid is not valid, we will throw an exception in order
// to try with the next valid identifier...
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} catch (SnmpStatusException e) {
// We didn't find anything at the given arc, so we're going

View File

@ -155,7 +155,7 @@ public abstract class SnmpMibNode implements Serializable {
long[] oid, int depth,
SnmpRequestTree handlers)
throws SnmpStatusException {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
/**
@ -183,7 +183,7 @@ public abstract class SnmpMibNode implements Serializable {
long[] oid, int pos, int depth,
SnmpRequestTree handlers, AcmChecker checker)
throws SnmpStatusException {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
/**
@ -346,8 +346,9 @@ public abstract class SnmpMibNode implements Serializable {
final int[] a = table;
final int val= (int) value;
if (a == null)
throw noSuchObjectException;
if (a == null) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
int low= 0;
int max= a.length;
@ -356,11 +357,13 @@ public abstract class SnmpMibNode implements Serializable {
// Basic check
//
if (max < 1)
throw noSuchObjectException;
if (max < 1) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (a[max-1] <= val)
throw noSuchObjectException;
if (a[max-1] <= val) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
while (low <= max) {
elmt= a[curr];
@ -400,15 +403,4 @@ public abstract class SnmpMibNode implements Serializable {
* Contains the list of variable identifiers.
*/
protected int[] varList;
/**
* Contains a predefined exception that is often fired when an
* object is not found in the MIB.
*/
static final protected SnmpStatusException noSuchInstanceException =
new SnmpStatusException(SnmpStatusException.noSuchInstance);
static final protected SnmpStatusException noSuchObjectException =
new SnmpStatusException(SnmpStatusException.noSuchObject);
static final protected SnmpStatusException noSuchNameException =
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
}

View File

@ -160,12 +160,10 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
if (depth > length) {
// Nothing is left... the oid is not valid
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (depth == length) {
// The oid is not complete...
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} else {
// Some children variable or subobject is being querried
// getChild() will raise an exception if no child is found.
@ -205,12 +203,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
final int length = oid.length;
SnmpMibNode node = null;
long[] result = null;
if (handlers == null)
if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
@ -235,7 +234,7 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
// SnmpOid result = null;
if (child == null) {
// shouldn't happen
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
// validateVarId(index);
// handlers.add(this,varbind,depth);
// result = new SnmpOid(0);
@ -444,11 +443,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
// first we need to retrieve the identifier in the list of children
//
final int pos= getInsertAt(id);
if (pos >= nbChildren)
throw noSuchObjectException;
if (pos >= nbChildren) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (varList[pos] != (int) id)
throw noSuchObjectException;
if (varList[pos] != (int) id) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// Access the node
//
@ -456,10 +457,11 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
try {
child = children.elementAtNonSync(pos);
} catch(ArrayIndexOutOfBoundsException e) {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (child == null) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
if (child == null)
throw noSuchInstanceException;
return child;
}

View File

@ -280,7 +280,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
SnmpVarBind var;
for (Enumeration<SnmpVarBind> e= r.getElements(); e.hasMoreElements();) {
var = e.nextElement();
r.registerGetException(var,noSuchInstanceException);
r.registerGetException(var,new SnmpStatusException(SnmpStatusException.noSuchInstance));
}
}
@ -1607,8 +1607,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
protected SnmpOid getNextOid(SnmpOid oid, Object userData)
throws SnmpStatusException {
if (size == 0)
throw noSuchInstanceException;
if (size == 0) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
final SnmpOid resOid = oid;
@ -1619,7 +1620,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
if (last.equals(resOid)) {
// Last element of the table ...
//
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// First find the oid. This will allow to speed up retrieval process
@ -1641,12 +1642,12 @@ public abstract class SnmpMibTable extends SnmpMibNode
// XX last = (SnmpOid) oids.elementAt(newPos);
last = tableoids[newPos];
} catch(ArrayIndexOutOfBoundsException e) {
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
} else {
// We are dealing with the last element of the table ..
//
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
@ -1668,8 +1669,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
*/
protected SnmpOid getNextOid(Object userData)
throws SnmpStatusException {
if (size == 0)
throw noSuchInstanceException;
if (size == 0) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// XX return (SnmpOid) oids.firstElement();
return tableoids[0];
}
@ -1875,10 +1877,10 @@ public abstract class SnmpMibTable extends SnmpMibNode
// not support creation.
// We know that the entry does not exists if (isentry == false).
if (!hasEntry) {
if (!handlers.isCreationAllowed())
if (!handlers.isCreationAllowed()) {
// we're not doing a set
throw noSuchInstanceException;
else if (!isCreationEnabled())
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} else if (!isCreationEnabled())
// we're doing a set but creation is disabled.
throw new
SnmpStatusException(SnmpStatusException.snmpRspNoAccess);
@ -1922,12 +1924,13 @@ public abstract class SnmpMibTable extends SnmpMibNode
int length = oid.length;
if (handlers == null)
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw noSuchObjectException;
if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
@ -1961,7 +1964,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
// so we won't find the next element in this table... (any
// element in this table will have a smaller OID)
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (oid[pos] < nodeId) {
// we must return the first leaf under the first columnar
// object, so we are back to our first case where pos was
@ -2051,8 +2054,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// in tables can't be properly supported (all rows
// must have the same holes)
//
if (skipEntryVariable(entryoid,var,data,pduVersion))
throw noSuchObjectException;
if (skipEntryVariable(entryoid,var,data,pduVersion)) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} catch(SnmpStatusException se) {
entryoid = getNextOid(data);
var = getNextVarEntryId(entryoid,var,data,pduVersion);
@ -2085,8 +2089,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// So we throw the exception.
// => will skip to next node in the MIB tree.
//
if (entryoid == null || var == -1 ) throw noSuchObjectException;
if (entryoid == null || var == -1 ) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// So here we know both the row (entryoid) and the column (var)
//
@ -2097,8 +2102,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// for this specific entry, it is not readable for any
// other entry => skip to next column.
//
if (!isReadableEntryId(entryoid,var,data))
throw noSuchObjectException;
if (!isReadableEntryId(entryoid,var,data)) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// Prepare the result and the ACM checker.
//
@ -2161,8 +2167,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// No need to continue, we throw an exception.
// => will skip to next node in the MIB tree.
//
if (entryoid == null || var == -1 )
throw noSuchObjectException;
if (entryoid == null || var == -1 ) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
}
}
@ -2182,14 +2189,15 @@ public abstract class SnmpMibTable extends SnmpMibNode
// Control the length of the oid
//
if (pos +2 >= length)
throw noSuchInstanceException;
if (pos +2 >= length) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// Check that the entry identifier is specified
//
if (oid[pos] != nodeId)
throw noSuchObjectException;
if (oid[pos] != nodeId) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
}
// ----------------------------------------------------------------------

View File

@ -1146,7 +1146,4 @@ class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions {
static final private String InterruptSysCallMsg =
"Interrupted system call";
static final private SnmpStatusException noSuchNameException =
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName) ;
}

View File

@ -25,27 +25,33 @@
package com.sun.media.sound;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;
import javax.sound.midi.spi.MidiDeviceProvider;
import javax.sound.midi.spi.MidiFileReader;
import javax.sound.midi.spi.MidiFileWriter;
import javax.sound.midi.spi.SoundbankReader;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Port;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.spi.AudioFileReader;
import javax.sound.sampled.spi.AudioFileWriter;
import javax.sound.sampled.spi.FormatConversionProvider;
import javax.sound.sampled.spi.MixerProvider;
/**
* JDK13Services uses the Service class in JDK 1.3
* to discover a list of service providers installed
* in the system.
*
* JDK13Services uses the Service class in JDK 1.3 to discover a list of service
* providers installed in the system.
* <p>
* This class is public because it is called from javax.sound.midi.MidiSystem
* and javax.sound.sampled.AudioSystem. The alternative would be to make
* JSSecurityManager public, which is considered worse.
@ -54,80 +60,55 @@ import javax.sound.sampled.TargetDataLine;
*/
public final class JDK13Services {
/** The default for the length of the period to hold the cache.
This value is given in milliseconds. It is equivalent to
1 minute.
*/
private static final long DEFAULT_CACHING_PERIOD = 60000;
/** Filename of the properties file for default provider properties.
This file is searched in the subdirectory "lib" of the JRE directory
(this behaviour is hardcoded).
*/
/**
* Filename of the properties file for default provider properties. This
* file is searched in the subdirectory "lib" of the JRE directory (this
* behaviour is hardcoded).
*/
private static final String PROPERTIES_FILENAME = "sound.properties";
/** Cache for the providers.
Class objects of the provider type (MixerProvider, MidiDeviceProvider
...) are used as keys. The values are instances of ProviderCache.
*/
private static final Map providersCacheMap = new HashMap();
/** The length of the period to hold the cache.
This value is given in milliseconds.
*/
private static long cachingPeriod = DEFAULT_CACHING_PERIOD;
/** Properties loaded from the properties file for default provider
properties.
*/
/**
* Properties loaded from the properties file for default provider
* properties.
*/
private static Properties properties;
/** Private, no-args constructor to ensure against instantiation.
/**
* Private, no-args constructor to ensure against instantiation.
*/
private JDK13Services() {
}
/** Set the period provider lists are cached.
This method is only intended for testing.
/**
* Obtains a List containing installed instances of the providers for the
* requested service. The returned List is immutable.
*
* @param serviceClass The type of providers requested. This should be one
* of AudioFileReader.class, AudioFileWriter.class,
* FormatConversionProvider.class, MixerProvider.class,
* MidiDeviceProvider.class, MidiFileReader.class,
* MidiFileWriter.class or SoundbankReader.class.
*
* @return A List of providers of the requested type. This List is
* immutable.
*/
public static void setCachingPeriod(int seconds) {
cachingPeriod = seconds * 1000L;
}
/** Obtains a List containing installed instances of the
providers for the requested service.
The List of providers is cached for the period of time given by
{@link #cachingPeriod cachingPeriod}. During this period, the same
List instance is returned for the same type of provider. After this
period, a new instance is constructed and returned. The returned
List is immutable.
@param serviceClass The type of providers requested. This should be one
of AudioFileReader.class, AudioFileWriter.class,
FormatConversionProvider.class, MixerProvider.class,
MidiDeviceProvider.class, MidiFileReader.class, MidiFileWriter.class or
SoundbankReader.class.
@return A List of providers of the requested type. This List is
immutable.
*/
public static synchronized List getProviders(Class serviceClass) {
ProviderCache cache = (ProviderCache) providersCacheMap.get(serviceClass);
if (cache == null) {
cache = new ProviderCache();
providersCacheMap.put(serviceClass, cache);
public static List<?> getProviders(final Class<?> serviceClass) {
final List<?> providers;
if (!MixerProvider.class.equals(serviceClass)
&& !FormatConversionProvider.class.equals(serviceClass)
&& !AudioFileReader.class.equals(serviceClass)
&& !AudioFileWriter.class.equals(serviceClass)
&& !MidiDeviceProvider.class.equals(serviceClass)
&& !SoundbankReader.class.equals(serviceClass)
&& !MidiFileWriter.class.equals(serviceClass)
&& !MidiFileReader.class.equals(serviceClass)) {
providers = new ArrayList<>(0);
} else {
providers = JSSecurityManager.getProviders(serviceClass);
}
if (cache.providers == null ||
System.currentTimeMillis() > cache.lastUpdate + cachingPeriod) {
cache.providers = Collections.unmodifiableList(JSSecurityManager.getProviders(serviceClass));
cache.lastUpdate = System.currentTimeMillis();
}
return cache.providers;
return Collections.unmodifiableList(providers);
}
/** Obtain the provider class name part of a default provider property.
@param typeClass The type of the default provider property. This
should be one of Receiver.class, Transmitter.class, Sequencer.class,
@ -219,14 +200,4 @@ public final class JDK13Services {
}
return properties;
}
// INNER CLASSES
private static class ProviderCache {
// System time of the last update in milliseconds.
public long lastUpdate;
// The providers.
public List providers;
}
}

View File

@ -185,8 +185,8 @@ final class JSSecurityManager {
return thread;
}
static <T> List<T> getProviders(final Class<T> providerClass) {
List<T> p = new ArrayList<>();
static synchronized <T> List<T> getProviders(final Class<T> providerClass) {
List<T> p = new ArrayList<>(7);
// ServiceLoader creates "lazy" iterator instance, but it ensures that
// next/hasNext run with permissions that are restricted by whatever
// creates the ServiceLoader instance, so it requires to be called from

View File

@ -56,9 +56,12 @@ public final class FactoryEnumeration {
* references so as not to prevent GC of the class loader. Each
* weak reference is tagged with the factory's class name so the
* class can be reloaded if the reference is cleared.
*
* @param factories A non-null list
* @param loader The class loader of the list's contents
*
* This internal method is used with Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*/
FactoryEnumeration(List<NamedWeakReference<Object>> factories,
ClassLoader loader) {
@ -79,7 +82,8 @@ public final class FactoryEnumeration {
try {
if (answer == null) { // reload class if weak ref cleared
answer = Class.forName(className, true, loader);
Class<?> cls = Class.forName(className, true, loader);
answer = cls;
}
// Instantiate Class to get factory
answer = ((Class) answer).newInstance();

View File

@ -53,21 +53,24 @@ import javax.naming.*;
final class VersionHelper12 extends VersionHelper {
private boolean getSystemPropsFailed = false;
VersionHelper12() {} // Disallow external from creating one of these.
// Disallow external from creating one of these.
VersionHelper12() {
}
public Class<?> loadClass(String className) throws ClassNotFoundException {
ClassLoader cl = getContextClassLoader();
return Class.forName(className, true, cl);
return loadClass(className, getContextClassLoader());
}
/**
* Package private.
*/
* Package private.
*
* This internal method is used with Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*/
Class<?> loadClass(String className, ClassLoader cl)
throws ClassNotFoundException {
return Class.forName(className, true, cl);
Class<?> cls = Class.forName(className, true, cl);
return cls;
}
/**
@ -75,13 +78,13 @@ final class VersionHelper12 extends VersionHelper {
* @param codebase A non-null, space-separated list of URL strings.
*/
public Class<?> loadClass(String className, String codebase)
throws ClassNotFoundException, MalformedURLException {
ClassLoader cl;
throws ClassNotFoundException, MalformedURLException {
ClassLoader parent = getContextClassLoader();
cl = URLClassLoader.newInstance(getUrlArray(codebase), parent);
ClassLoader cl =
URLClassLoader.newInstance(getUrlArray(codebase), parent);
return Class.forName(className, true, cl);
return loadClass(className, cl);
}
String getJndiProperty(final int i) {
@ -99,16 +102,12 @@ final class VersionHelper12 extends VersionHelper {
}
String[] getJndiProperties() {
if (getSystemPropsFailed) {
return null; // after one failure, don't bother trying again
}
Properties sysProps = AccessController.doPrivileged(
new PrivilegedAction<Properties>() {
public Properties run() {
try {
return System.getProperties();
} catch (SecurityException e) {
getSystemPropsFailed = true;
return null;
}
}
@ -173,17 +172,32 @@ final class VersionHelper12 extends VersionHelper {
return new InputStreamEnumeration(urls);
}
/**
* Package private.
*
* This internal method returns Thread Context Class Loader (TCCL),
* if null, returns the system Class Loader.
*
* Please don't expose this method as public.
*/
ClassLoader getContextClassLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
if (loader == null) {
// Don't use bootstrap class loader directly!
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}
}
);
}
/**
* Given an enumeration of URLs, an instance of this class represents
* an enumeration of their InputStreams. Each operation on the URL

View File

@ -276,6 +276,11 @@ public abstract class SctpChannel
*
* @throws IOException
* If some other I/O error occurs
*
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/
public abstract SctpChannel bind(SocketAddress local)
throws IOException;

View File

@ -382,7 +382,8 @@ public abstract class Canonicalizer11 extends CanonicalizerBase {
} else if (!isVisible(xmlns)) {
//There is a definition but the xmlns is not selected by the xpath.
//then xmlns=""
n = ns.addMappingAndRender(XMLNS, "", nullNode);
n = ns.addMappingAndRender(
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
}
//output the xmlns def if needed.
if (n != null) {

View File

@ -327,7 +327,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase {
} else if (!isVisible(xmlns)) {
//There is a definition but the xmlns is not selected by the xpath.
//then xmlns=""
n = ns.addMappingAndRender(XMLNS, "", nullNode);
n = ns.addMappingAndRender(
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
}
//output the xmlns def if needed.
if (n != null) {

View File

@ -292,7 +292,7 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
if (xmlns != null && !isVisible(xmlns)) {
// There is a definition but the xmlns is not selected by the
// xpath. then xmlns=""
ns.addMapping(XMLNS, "", nullNode);
ns.addMapping(XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
}
String prefix = null;

View File

@ -34,8 +34,6 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
@ -49,6 +47,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
@ -64,8 +63,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
public static final String XMLNS = "xmlns";
protected static final AttrCompare COMPARE = new AttrCompare();
protected static final Attr nullNode;
// Make sure you clone the following mutable arrays before passing to
// potentially untrusted objects such as OutputStreams.
private static final byte[] END_PI = {'?','>'};
private static final byte[] BEGIN_PI = {'<','?'};
private static final byte[] END_COMM = {'-','-','>'};
@ -78,27 +78,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private static final byte[] LT = {'&','l','t',';'};
private static final byte[] END_TAG = {'<','/'};
private static final byte[] AMP = {'&','a','m','p',';'};
private static final byte[] equalsStr = {'=','\"'};
private static final byte[] EQUALS_STR = {'=','\"'};
protected static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
protected static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
static {
// The null xmlns definition.
try {
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
nullNode = documentBuilder.newDocument().createAttributeNS(Constants.NamespaceSpecNS, XMLNS);
nullNode.setValue("");
} catch (Exception e) {
throw new RuntimeException("Unable to create nullNode: " + e);
}
}
private List<NodeFilter> nodeFilter;
private boolean includeComments;
private Set<Node> xpathNodeSet;
/**
* The node to be skipped/excluded from the DOM tree
* in subtree canonicalizations.
@ -106,6 +96,11 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private Node excludeNode;
private OutputStream writer = new ByteArrayOutputStream();
/**
* The null xmlns definition.
*/
private Attr nullNode;
/**
* Constructor CanonicalizerBase
*
@ -310,7 +305,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
writer.write('>');
sibling = currentNode.getFirstChild();
if (sibling == null) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeStringToUtf8(name, writer);
writer.write('>');
//We finished with this level, pop to the previous definitions.
@ -328,7 +323,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
break;
}
while (sibling == null && parentNode != null) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>');
//We finished with this level, pop to the previous definitions.
@ -488,7 +483,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (sibling == null) {
if (currentNodeIsVisible) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeByte(name, writer, cache);
writer.write('>');
//We finished with this level, pop to the previous definitions.
@ -510,7 +505,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
}
while (sibling == null && parentNode != null) {
if (isVisible(parentNode)) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>');
//We finished with this level, pop to the previous definitions.
@ -641,8 +636,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
parents.clear();
Attr nsprefix;
if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null)
&& "".equals(nsprefix.getValue())) {
ns.addMappingAndRender(XMLNS, "", nullNode);
&& "".equals(nsprefix.getValue())) {
ns.addMappingAndRender(
XMLNS, "", getNullNode(nsprefix.getOwnerDocument()));
}
}
@ -696,7 +692,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
) throws IOException {
writer.write(' ');
UtfHelpper.writeByte(name, writer, cache);
writer.write(equalsStr);
writer.write(EQUALS_STR.clone());
byte[] toWrite;
final int length = value.length();
int i = 0;
@ -706,27 +702,27 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) {
case '&' :
toWrite = AMP;
toWrite = AMP.clone();
break;
case '<' :
toWrite = LT;
toWrite = LT.clone();
break;
case '"' :
toWrite = QUOT;
toWrite = QUOT.clone();
break;
case 0x09 : // '\t'
toWrite = X9;
toWrite = X9.clone();
break;
case 0x0A : // '\n'
toWrite = XA;
toWrite = XA.clone();
break;
case 0x0D : // '\r'
toWrite = XD;
toWrite = XD.clone();
break;
default :
@ -756,7 +752,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n');
}
writer.write(BEGIN_PI);
writer.write(BEGIN_PI.clone());
final String target = currentPI.getTarget();
int length = target.length();
@ -764,7 +760,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) {
char c = target.charAt(i);
if (c == 0x0D) {
writer.write(XD);
writer.write(XD.clone());
} else {
if (c < 0x80) {
writer.write(c);
@ -784,14 +780,14 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) {
char c = data.charAt(i);
if (c == 0x0D) {
writer.write(XD);
writer.write(XD.clone());
} else {
UtfHelpper.writeCharToUtf8(c, writer);
}
}
}
writer.write(END_PI);
writer.write(END_PI.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n');
}
@ -810,7 +806,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n');
}
writer.write(BEGIN_COMM);
writer.write(BEGIN_COMM.clone());
final String data = currentComment.getData();
final int length = data.length();
@ -818,7 +814,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) {
char c = data.charAt(i);
if (c == 0x0D) {
writer.write(XD);
writer.write(XD.clone());
} else {
if (c < 0x80) {
writer.write(c);
@ -828,7 +824,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
}
}
writer.write(END_COMM);
writer.write(END_COMM.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n');
}
@ -852,19 +848,19 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) {
case '&' :
toWrite = AMP;
toWrite = AMP.clone();
break;
case '<' :
toWrite = LT;
toWrite = LT.clone();
break;
case '>' :
toWrite = GT;
toWrite = GT.clone();
break;
case 0xD :
toWrite = XD;
toWrite = XD.clone();
break;
default :
@ -879,4 +875,18 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
}
}
// The null xmlns definition.
protected Attr getNullNode(Document ownerDocument) {
if (nullNode == null) {
try {
nullNode = ownerDocument.createAttributeNS(
Constants.NamespaceSpecNS, XMLNS);
nullNode.setValue("");
} catch (Exception e) {
throw new RuntimeException("Unable to create nullNode: " + e);
}
}
return nullNode;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,7 @@ import javax.sql.rowset.spi.*;
import javax.sql.rowset.serial.*;
import com.sun.rowset.internal.*;
import com.sun.rowset.providers.*;
import sun.reflect.misc.ReflectUtil;
/**
* The standard implementation of the <code>CachedRowSet</code> interface.
@ -2959,13 +2960,9 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern
// create new instance of the class
SQLData obj = null;
try {
obj = (SQLData)c.newInstance();
} catch (java.lang.InstantiationException ex) {
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(),
ex.getMessage()));
} catch (java.lang.IllegalAccessException ex) {
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(),
ex.getMessage()));
obj = (SQLData) ReflectUtil.newInstance(c);
} catch(Exception ex) {
throw new SQLException("Unable to Instantiate: ", ex);
}
// get the attributes from the struct
Object attribs[] = s.getAttributes(map);
@ -5710,13 +5707,9 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern
// create new instance of the class
SQLData obj = null;
try {
obj = (SQLData)c.newInstance();
} catch (java.lang.InstantiationException ex) {
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(),
ex.getMessage()));
} catch (java.lang.IllegalAccessException ex) {
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(),
ex.getMessage()));
obj = (SQLData) ReflectUtil.newInstance(c);
} catch(Exception ex) {
throw new SQLException("Unable to Instantiate: ", ex);
}
// get the attributes from the struct
Object attribs[] = s.getAttributes(map);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.sql.*;
import javax.sql.*;
import java.util.*;
import java.io.*;
import sun.reflect.misc.ReflectUtil;
import com.sun.rowset.*;
import java.text.MessageFormat;
@ -572,13 +573,9 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable {
// create new instance of the class
SQLData obj = null;
try {
obj = (SQLData)c.newInstance();
} catch (java.lang.InstantiationException ex) {
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(),
ex.getMessage()));
} catch (java.lang.IllegalAccessException ex) {
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(),
ex.getMessage()));
obj = (SQLData)ReflectUtil.newInstance(c);
} catch (Exception ex) {
throw new SQLException("Unable to Instantiate: ", ex);
}
// get the attributes from the struct
Object attribs[] = s.getAttributes(map);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -660,7 +660,7 @@ public class XmlReaderContentHandler extends DefaultHandler {
//Added the handling for Class tags to take care of maps
//Makes an entry into the map upon end of class tag
try{
typeMap.put(Key_map,Class.forName(Value_map));
typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map));
}catch(ClassNotFoundException ex) {
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));

View File

@ -44,8 +44,8 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import sun.awt.AppContext;
import sun.awt.datatransfer.DataTransferer;
/**
@ -66,10 +66,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
*/
private static String JavaMIME = "JAVA_DATAFLAVOR:";
/**
* System singleton which maps a thread's ClassLoader to a SystemFlavorMap.
*/
private static final WeakHashMap<ClassLoader, FlavorMap> flavorMaps = new WeakHashMap<>();
private static final Object FLAVOR_MAP_KEY = new Object();
/**
* Copied from java.util.Properties.
@ -183,22 +180,12 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
* Returns the default FlavorMap for this thread's ClassLoader.
*/
public static FlavorMap getDefaultFlavorMap() {
ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
if (contextClassLoader == null) {
contextClassLoader = ClassLoader.getSystemClassLoader();
AppContext context = AppContext.getAppContext();
FlavorMap fm = (FlavorMap) context.get(FLAVOR_MAP_KEY);
if (fm == null) {
fm = new SystemFlavorMap();
context.put(FLAVOR_MAP_KEY, fm);
}
FlavorMap fm;
synchronized(flavorMaps) {
fm = flavorMaps.get(contextClassLoader);
if (fm == null) {
fm = new SystemFlavorMap();
flavorMaps.put(contextClassLoader, fm);
}
}
return fm;
}
@ -239,26 +226,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
});
BufferedReader flavormapURL =
String url =
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<BufferedReader>() {
public BufferedReader run() {
String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
if (url == null) {
return null;
}
try {
return new BufferedReader
(new InputStreamReader
(new URL(url).openStream(), "ISO-8859-1"));
} catch (MalformedURLException e) {
System.err.println("MalformedURLException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
} catch (IOException e) {
System.err.println("IOException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
}
return null;
new java.security.PrivilegedAction<String>() {
public String run() {
return Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
}
});
@ -270,6 +242,19 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
}
BufferedReader flavormapURL = null;
if (url != null) {
try {
flavormapURL = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "ISO-8859-1"));
} catch (MalformedURLException e) {
System.err.println("MalformedURLException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
} catch (IOException e) {
System.err.println("IOException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
} catch (SecurityException e) {
// ignored
}
}
if (flavormapURL != null) {
try {
parseAndStoreReader(flavormapURL);

View File

@ -1114,11 +1114,8 @@ class SecurityManager {
* calling thread is not allowed to wait for a connection request on
* the specified local port number.
* <p>
* If port is not 0, this method calls
* <code>checkPermission</code> with the
* This method calls <code>checkPermission</code> with the
* <code>SocketPermission("localhost:"+port,"listen")</code>.
* If port is zero, this method calls <code>checkPermission</code>
* with <code>SocketPermission("localhost:1024-","listen").</code>
* <p>
* If you override this method, then you should make a call to
* <code>super.checkListen</code>
@ -1131,12 +1128,8 @@ class SecurityManager {
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkListen(int port) {
if (port == 0) {
checkPermission(SecurityConstants.LOCAL_LISTEN_PERMISSION);
} else {
checkPermission(new SocketPermission("localhost:"+port,
SecurityConstants.SOCKET_LISTEN_ACTION));
}
checkPermission(new SocketPermission("localhost:"+port,
SecurityConstants.SOCKET_LISTEN_ACTION));
}
/**

View File

@ -2070,6 +2070,7 @@ assert((int)twice.invokeExact(21) == 42);
*/
public static
MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
reorder = reorder.clone();
checkReorder(reorder, newType, target.type());
return target.permuteArguments(newType, reorder);
}
@ -2264,6 +2265,7 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
throw newIllegalArgumentException("no argument type to remove");
ArrayList<Class<?>> ptypes = new ArrayList<>(oldType.parameterList());
ptypes.addAll(pos, valueTypes);
if (ptypes.size() != inargs) throw newIllegalArgumentException("valueTypes");
MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
return target.dropArguments(newType, pos, dropped);
}

View File

@ -272,7 +272,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its
* {@code checkConnect} method doesn't allow the operation.
* {@code checkConnect} method doesn't allow the connection
* to the destination, or if its {@code checkListen} method
* doesn't allow the bind to the local port.
* @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
@ -311,7 +313,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its
* {@code checkConnect} method doesn't allow the operation.
* {@code checkConnect} method doesn't allow the connection
* to the destination, or if its {@code checkListen} method
* doesn't allow the bind to the local port.
* @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
@ -609,6 +613,9 @@ class Socket implements java.io.Closeable {
* is already bound.
* @throws IllegalArgumentException if bindpoint is a
* SocketAddress subclass not supported by this socket
* @throws SecurityException if a security manager exists and its
* {@code checkListen} method doesn't allow the bind
* to the local port.
*
* @since 1.4
* @see #isBound
@ -630,6 +637,10 @@ class Socket implements java.io.Closeable {
InetAddress addr = epoint.getAddress();
int port = epoint.getPort();
checkAddress (addr, "bind");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkListen(port);
}
getImpl().bind (addr, port);
bound = true;
}

View File

@ -34,6 +34,9 @@ import java.util.StringTokenizer;
import java.net.InetAddress;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.Security;
import java.io.Serializable;
import java.io.ObjectStreamField;
import java.io.ObjectOutputStream;
@ -41,6 +44,7 @@ import java.io.ObjectInputStream;
import java.io.IOException;
import sun.net.util.IPAddressUtil;
import sun.net.RegisteredDomain;
import sun.net.PortConfig;
import sun.security.util.SecurityConstants;
import sun.security.util.Debug;
@ -89,6 +93,9 @@ import sun.security.util.Debug;
* form "N-", where <i>N</i> is a port number, signifies all ports
* numbered <i>N</i> and above, while a specification of the
* form "-N" indicates all ports numbered <i>N</i> and below.
* The special port value {@code 0} refers to the entire <i>ephemeral</i>
* port range. This is a fixed range of ports a system may use to
* allocate dynamic ports from. The actual range may be system dependent.
* <p>
* The possible ways to connect to the host are
* <pre>
@ -97,7 +104,8 @@ import sun.security.util.Debug;
* listen
* resolve
* </pre>
* The "listen" action is only meaningful when used with "localhost".
* The "listen" action is only meaningful when used with "localhost" and
* means the ability to bind to a specified port.
* The "resolve" action is implied when any of the other actions are present.
* The action "resolve" refers to host/ip name service lookups.
* <P>
@ -176,6 +184,7 @@ public final class SocketPermission extends Permission
private static final int PORT_MIN = 0;
private static final int PORT_MAX = 65535;
private static final int PRIV_PORT_MAX = 1023;
private static final int DEF_EPH_LOW = 49152;
// the actions mask
private transient int mask;
@ -226,6 +235,14 @@ public final class SocketPermission extends Permission
private static Debug debug = null;
private static boolean debugInit = false;
// ephemeral port range for this system
private static final int ephemeralLow = initEphemeralPorts(
"low", DEF_EPH_LOW
);
private static final int ephemeralHigh = initEphemeralPorts(
"high", PORT_MAX
);
static {
Boolean tmp = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
@ -359,6 +376,14 @@ public final class SocketPermission extends Permission
}
}
/**
* Returns true if the permission has specified zero
* as its value (or lower bound) signifying the ephemeral range
*/
private boolean includesEphemerals() {
return portrange[0] == 0;
}
/**
* Initialize the SocketPermission object. We don't do any DNS lookups
* as this point, instead we hold off until the implies method is
@ -850,10 +875,21 @@ public final class SocketPermission extends Permission
int i,j;
if ((that.mask & RESOLVE) != that.mask) {
// check port range
// check simple port range
if ((that.portrange[0] < this.portrange[0]) ||
(that.portrange[1] > this.portrange[1])) {
// if either includes the ephemeral range, do full check
if (this.includesEphemerals() || that.includesEphemerals()) {
if (!inRange(this.portrange[0], this.portrange[1],
that.portrange[0], that.portrange[1]))
{
return false;
}
} else {
return false;
}
}
}
@ -1168,6 +1204,75 @@ public final class SocketPermission extends Permission
init(getName(),getMask(actions));
}
/**
* Check the system/security property for the ephemeral port range
* for this system. The suffix is either "high" or "low"
*/
private static int initEphemeralPorts(String suffix, int defval) {
return AccessController.doPrivileged(
new PrivilegedAction<Integer>(){
public Integer run() {
int val = Integer.getInteger(
"jdk.net.ephemeralPortRange."+suffix, -1
);
if (val != -1) {
return val;
} else {
return suffix.equals("low") ?
PortConfig.getLower() : PortConfig.getUpper();
}
}
}
);
}
/**
* Check if the target range is within the policy range
* together with the ephemeral range for this platform
* (if policy includes ephemeral range)
*/
private static boolean inRange(
int policyLow, int policyHigh, int targetLow, int targetHigh
)
{
if (targetLow == 0) {
// check policy includes ephemeral range
if (!inRange(policyLow, policyHigh, ephemeralLow, ephemeralHigh)) {
return false;
}
if (targetHigh == 0) {
// nothing left to do
return true;
}
// continue check with first real port number
targetLow = 1;
}
if (policyLow == 0 && policyHigh == 0) {
// ephemeral range only
return targetLow >= ephemeralLow && targetHigh <= ephemeralHigh;
}
if (policyLow != 0) {
// simple check of policy only
return targetLow >= policyLow && targetHigh <= policyHigh;
}
// policyLow == 0 which means possibly two ranges to check
// first check if policy and ephem range overlap/contiguous
if (policyHigh >= ephemeralLow - 1) {
return targetHigh <= ephemeralHigh;
}
// policy and ephem range do not overlap
// target range must lie entirely inside policy range or eph range
return (targetLow <= policyHigh && targetHigh <= policyHigh) ||
(targetLow >= ephemeralLow && targetHigh <= ephemeralHigh);
}
/*
public String toString()
{

View File

@ -200,6 +200,10 @@ public abstract class AsynchronousSocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/
@Override
public abstract AsynchronousSocketChannel bind(SocketAddress local)

View File

@ -227,6 +227,10 @@ public abstract class SocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*
* @since 1.7
*/

View File

@ -53,6 +53,13 @@ import sun.misc.SharedSecrets;
* or method in this class will cause a {@link NullPointerException} to be
* thrown.
*
* If the verify flag is on when opening a signed jar file, the content of the
* file is verified against its signature embedded inside the file. Please note
* that the verification process does not include validating the signer's
* certificate. A caller should inspect the return value of
* {@link JarEntry#getCodeSigners()} to further determine if the signature
* can be trusted.
*
* @author David Connelly
* @see Manifest
* @see java.util.zip.ZipFile

View File

@ -179,7 +179,9 @@ class JarVerifier {
name = name.substring(1);
// only set the jev object for entries that have a signature
if (sigFileSigners.get(name) != null) {
// (either verified or not)
if (sigFileSigners.get(name) != null ||
verifiedSigners.get(name) != null) {
mev.setEntry(name, je);
return;
}
@ -685,6 +687,8 @@ class JarVerifier {
} else {
matchUnsigned = true;
}
} else {
matchUnsigned = true;
}
}
@ -787,23 +791,7 @@ class JarVerifier {
// true if file is part of the signature mechanism itself
static boolean isSigningRelated(String name) {
name = name.toUpperCase(Locale.ENGLISH);
if (!name.startsWith("META-INF/")) {
return false;
}
name = name.substring(9);
if (name.indexOf('/') != -1) {
return false;
}
if (name.endsWith(".DSA")
|| name.endsWith(".RSA")
|| name.endsWith(".SF")
|| name.endsWith(".EC")
|| name.startsWith("SIG-")
|| name.equals("MANIFEST.MF")) {
return true;
}
return false;
return SignatureFileVerifier.isSigningRelated(name);
}
private Enumeration<String> unsignedEntryNames(JarFile jar) {

View File

@ -248,6 +248,11 @@ public class LogManager {
* retrieved by calling LogManager.getLogManager.
*/
protected LogManager() {
this(checkSubclassPermissions());
}
private LogManager(Void checked) {
// Add a shutdown hook to close the global handlers.
try {
Runtime.getRuntime().addShutdownHook(new Cleaner());
@ -257,6 +262,19 @@ public class LogManager {
}
}
private static Void checkSubclassPermissions() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// These permission will be checked in the LogManager constructor,
// in order to register the Cleaner() thread as a shutdown hook.
// Check them here to avoid the penalty of constructing the object
// etc...
sm.checkPermission(new RuntimePermission("shutdownHooks"));
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
return null;
}
/**
* Lazy initialization: if this instance of manager is the global
* manager then this method will read the initial configuration and

View File

@ -91,7 +91,10 @@ public final class SimpleDoc implements Doc {
Class repClass = null;
try {
repClass = Class.forName(flavor.getRepresentationClassName());
String className = flavor.getRepresentationClassName();
sun.reflect.misc.ReflectUtil.checkPackageAccess(className);
repClass = Class.forName(className, false,
Thread.currentThread().getContextClassLoader());
} catch (Throwable e) {
throw new IllegalArgumentException("unknown representation class");
}

View File

@ -26,6 +26,10 @@
package javax.security.auth;
import java.security.Security;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import sun.security.util.Debug;
/**
@ -155,22 +159,15 @@ import sun.security.util.Debug;
public abstract class Policy {
private static Policy policy;
private static ClassLoader contextClassLoader;
private final static String AUTH_POLICY =
"sun.security.provider.AuthPolicyFile";
private final java.security.AccessControlContext acc =
java.security.AccessController.getContext();
// true if a custom (not AUTH_POLICY) system-wide policy object is set
private static boolean isCustomPolicy;
static {
contextClassLoader = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
};
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
@ -213,8 +210,8 @@ public abstract class Policy {
if (policy == null) {
String policy_class = null;
policy_class = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<String>() {
policy_class = AccessController.doPrivileged
(new PrivilegedAction<String>() {
public String run() {
return java.security.Security.getProperty
("auth.policy.provider");
@ -226,18 +223,28 @@ public abstract class Policy {
try {
final String finalClass = policy_class;
policy = java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Policy>() {
public Policy run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
return (Policy) Class.forName
(finalClass,
true,
contextClassLoader).newInstance();
}
});
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
Policy untrustedImpl = AccessController.doPrivileged(
new PrivilegedExceptionAction<Policy>() {
public Policy run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class<? extends Policy> implClass = Class.forName(
finalClass, false,
Thread.currentThread().getContextClassLoader()
).asSubclass(Policy.class);
return implClass.newInstance();
}
});
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() {
setPolicy(untrustedImpl);
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
return null;
}
}, Objects.requireNonNull(untrustedImpl.acc)
);
} catch (Exception e) {
throw new SecurityException
(sun.security.util.ResourcesMgr.getString

View File

@ -964,6 +964,10 @@ public final class Subject implements java.io.Serializable {
s.defaultReadObject();
// Rewrap the principals into a SecureSet
principals = Collections.synchronizedSet(new SecureSet<Principal>
(this, PRINCIPAL_SET, principals));
// The Credential {@code Set} is not serialized, but we do not
// want the default deserialization routine to set it to null.
this.pubCredentials = Collections.synchronizedSet

View File

@ -27,9 +27,6 @@ package javax.security.auth.login;
import javax.security.auth.AuthPermission;
import java.io.*;
import java.util.*;
import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
@ -38,7 +35,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;
import java.security.SecurityPermission;
import java.util.Objects;
import sun.security.jca.GetInstance;
@ -191,16 +188,9 @@ import sun.security.jca.GetInstance;
public abstract class Configuration {
private static Configuration configuration;
private static ClassLoader contextClassLoader;
static {
contextClassLoader = AccessController.doPrivileged
(new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
};
private final java.security.AccessControlContext acc =
java.security.AccessController.getContext();
private static void checkPermission(String type) {
SecurityManager sm = System.getSecurityManager();
@ -253,17 +243,26 @@ public abstract class Configuration {
try {
final String finalClass = config_class;
configuration = AccessController.doPrivileged
(new PrivilegedExceptionAction<Configuration>() {
public Configuration run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
return (Configuration)Class.forName
(finalClass,
true,
contextClassLoader).newInstance();
}
});
Configuration untrustedImpl = AccessController.doPrivileged(
new PrivilegedExceptionAction<Configuration>() {
public Configuration run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class<? extends Configuration> implClass = Class.forName(
finalClass, false,
Thread.currentThread().getContextClassLoader()
).asSubclass(Configuration.class);
return implClass.newInstance();
}
});
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() {
setConfiguration(untrustedImpl);
return null;
}
}, Objects.requireNonNull(untrustedImpl.acc)
);
} catch (PrivilegedActionException e) {
Exception ee = e.getException();
if (ee instanceof InstantiationException) {

View File

@ -209,8 +209,7 @@ public class LoginContext {
private Map<String,?> state = new HashMap<String,Object>();
private Configuration config;
private boolean configProvided = false;
private AccessControlContext creatorAcc = null;
private AccessControlContext creatorAcc = null; // customized config only
private ModuleInfo[] moduleStack;
private ClassLoader contextClassLoader = null;
private static final Class<?>[] PARAMS = { };
@ -229,7 +228,7 @@ public class LoginContext {
private void init(String name) throws LoginException {
SecurityManager sm = System.getSecurityManager();
if (sm != null && !configProvided) {
if (sm != null && creatorAcc == null) {
sm.checkPermission(new AuthPermission
("createLoginContext." + name));
}
@ -252,7 +251,7 @@ public class LoginContext {
AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
if (entries == null) {
if (sm != null && !configProvided) {
if (sm != null && creatorAcc == null) {
sm.checkPermission(new AuthPermission
("createLoginContext." + OTHER));
}
@ -279,7 +278,15 @@ public class LoginContext {
contextClassLoader = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
if (loader == null) {
// Don't use bootstrap class loader directly to ensure
// proper package access control!
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}
});
}
@ -298,10 +305,10 @@ public class LoginContext {
(DEFAULT_HANDLER);
if (defaultHandler == null || defaultHandler.length() == 0)
return null;
Class<?> c = Class.forName(defaultHandler,
true,
finalLoader);
return (CallbackHandler)c.newInstance();
Class<? extends CallbackHandler> c = Class.forName(
defaultHandler, true,
finalLoader).asSubclass(CallbackHandler.class);
return c.newInstance();
}
});
} catch (java.security.PrivilegedActionException pae) {
@ -309,7 +316,7 @@ public class LoginContext {
}
// secure it with the caller's ACC
if (this.callbackHandler != null && !configProvided) {
if (this.callbackHandler != null && creatorAcc == null) {
this.callbackHandler = new SecureCallbackHandler
(java.security.AccessController.getContext(),
this.callbackHandler);
@ -498,8 +505,7 @@ public class LoginContext {
CallbackHandler callbackHandler,
Configuration config) throws LoginException {
this.config = config;
configProvided = (config != null) ? true : false;
if (configProvided) {
if (config != null) {
creatorAcc = java.security.AccessController.getContext();
}
@ -510,7 +516,7 @@ public class LoginContext {
}
if (callbackHandler == null) {
loadDefaultCallbackHandler();
} else if (!configProvided) {
} else if (creatorAcc == null) {
this.callbackHandler = new SecureCallbackHandler
(java.security.AccessController.getContext(),
callbackHandler);
@ -577,23 +583,13 @@ public class LoginContext {
}
try {
if (configProvided) {
// module invoked in doPrivileged with creatorAcc
invokeCreatorPriv(LOGIN_METHOD);
invokeCreatorPriv(COMMIT_METHOD);
} else {
// module invoked in doPrivileged
invokePriv(LOGIN_METHOD);
invokePriv(COMMIT_METHOD);
}
// module invoked in doPrivileged
invokePriv(LOGIN_METHOD);
invokePriv(COMMIT_METHOD);
loginSucceeded = true;
} catch (LoginException le) {
try {
if (configProvided) {
invokeCreatorPriv(ABORT_METHOD);
} else {
invokePriv(ABORT_METHOD);
}
invokePriv(ABORT_METHOD);
} catch (LoginException le2) {
throw le;
}
@ -628,13 +624,8 @@ public class LoginContext {
("null.subject.logout.called.before.login"));
}
if (configProvided) {
// module invoked in doPrivileged with creatorAcc
invokeCreatorPriv(LOGOUT_METHOD);
} else {
// module invoked in doPrivileged
invokePriv(LOGOUT_METHOD);
}
// module invoked in doPrivileged
invokePriv(LOGOUT_METHOD);
}
/**
@ -677,35 +668,13 @@ public class LoginContext {
/**
* Invokes the login, commit, and logout methods
* from a LoginModule inside a doPrivileged block.
* from a LoginModule inside a doPrivileged block restricted
* by creatorAcc (may be null).
*
* This version is called if the caller did not instantiate
* the LoginContext with a Configuration object.
*/
private void invokePriv(final String methodName) throws LoginException {
try {
java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Void>() {
public Void run() throws LoginException {
invoke(methodName);
return null;
}
});
} catch (java.security.PrivilegedActionException pae) {
throw (LoginException)pae.getException();
}
}
/**
* Invokes the login, commit, and logout methods
* from a LoginModule inside a doPrivileged block restricted
* by creatorAcc
*
* This version is called if the caller instantiated
* the LoginContext with a Configuration object.
*/
private void invokeCreatorPriv(final String methodName)
throws LoginException {
try {
java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Void>() {
@ -735,24 +704,24 @@ public class LoginContext {
} else {
// instantiate the LoginModule
Class<?> c = Class.forName
(moduleStack[i].entry.getLoginModuleName(),
//
// Allow any object to be a LoginModule as long as it
// conforms to the interface.
Class<?> c = Class.forName(
moduleStack[i].entry.getLoginModuleName(),
true,
contextClassLoader);
Constructor<?> constructor = c.getConstructor(PARAMS);
Object[] args = { };
// allow any object to be a LoginModule
// as long as it conforms to the interface
moduleStack[i].module = constructor.newInstance(args);
methods = moduleStack[i].module.getClass().getMethods();
// call the LoginModule's initialize method
methods = moduleStack[i].module.getClass().getMethods();
for (mIndex = 0; mIndex < methods.length; mIndex++) {
if (methods[mIndex].getName().equals(INIT_METHOD))
if (methods[mIndex].getName().equals(INIT_METHOD)) {
break;
}
}
Object[] initArgs = {subject,
@ -760,19 +729,28 @@ public class LoginContext {
state,
moduleStack[i].entry.getOptions() };
// invoke the LoginModule initialize method
//
// Throws ArrayIndexOutOfBoundsException if no such
// method defined. May improve to use LoginException in
// the future.
methods[mIndex].invoke(moduleStack[i].module, initArgs);
}
// find the requested method in the LoginModule
for (mIndex = 0; mIndex < methods.length; mIndex++) {
if (methods[mIndex].getName().equals(methodName))
if (methods[mIndex].getName().equals(methodName)) {
break;
}
}
// set up the arguments to be passed to the LoginModule method
Object[] args = { };
// invoke the LoginModule method
//
// Throws ArrayIndexOutOfBoundsException if no such
// method defined. May improve to use LoginException in
// the future.
boolean status = ((Boolean)methods[mIndex].invoke
(moduleStack[i].module, args)).booleanValue();

View File

@ -28,8 +28,11 @@ package javax.sql.rowset;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.sql.SQLException;
import java.util.PropertyPermission;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import javax.sql.rowset.spi.SyncFactoryException;
import sun.reflect.misc.ReflectUtil;
/**
* A factory API that enables applications to obtain a
@ -129,15 +132,11 @@ public class RowSetProvider {
factoryClassName = getSystemProperty(ROWSET_FACTORY_NAME);
if (factoryClassName != null) {
trace("Found system property, value=" + factoryClassName);
factory = (RowSetFactory) getFactoryClass(factoryClassName, null, true).newInstance();
factory = (RowSetFactory) ReflectUtil.newInstance(getFactoryClass(factoryClassName, null, true));
}
} catch (ClassNotFoundException e) {
throw new SQLException(
"RowSetFactory: " + factoryClassName + " not found", e);
} catch (Exception e) {
throw new SQLException(
"RowSetFactory: " + factoryClassName + " could not be instantiated: " + e,
e);
} catch (Exception e) {
throw new SQLException( "RowSetFactory: " + factoryClassName +
" could not be instantiated: ", e);
}
// Check to see if we found the RowSetFactory via a System property
@ -182,6 +181,16 @@ public class RowSetProvider {
throws SQLException {
trace("***In newInstance()");
if(factoryClassName == null) {
throw new SQLException("Error: factoryClassName cannot be null");
}
try {
ReflectUtil.checkPackageAccess(factoryClassName);
} catch (java.security.AccessControlException e) {
throw new SQLException("Access Exception",e);
}
try {
Class<?> providerClass = getFactoryClass(factoryClassName, cl, false);
RowSetFactory instance = (RowSetFactory) providerClass.newInstance();
@ -291,8 +300,9 @@ public class RowSetProvider {
public String run() {
return System.getProperty(propName);
}
});
}, null, new PropertyPermission(propName, "read"));
} catch (SecurityException se) {
trace("error getting " + propName + ": "+ se);
if (debug) {
se.printStackTrace();
}

View File

@ -27,6 +27,7 @@ package javax.sql.rowset.serial;
import java.sql.*;
import java.util.Arrays;
import java.util.Map;
import sun.reflect.misc.ReflectUtil;
/**
* An input stream used for custom mapping user-defined types (UDTs).
@ -476,13 +477,9 @@ public class SQLInputImpl implements SQLInput {
// create new instance of the class
SQLData obj = null;
try {
obj = (SQLData)c.newInstance();
} catch (java.lang.InstantiationException ex) {
throw new SQLException("Unable to instantiate: " +
ex.getMessage());
} catch (java.lang.IllegalAccessException ex) {
throw new SQLException("Unable to instantiate: " +
ex.getMessage());
obj = (SQLData)ReflectUtil.newInstance(c);
} catch (Exception ex) {
throw new SQLException("Unable to Instantiate: ", ex);
}
// get the attributes from the struct
Object attribs[] = s.getAttributes(map);

View File

@ -35,8 +35,13 @@ import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.naming.*;
import sun.reflect.misc.ReflectUtil;
/**
* The Service Provider Interface (SPI) mechanism that generates <code>SyncProvider</code>
@ -327,7 +332,7 @@ public class SyncFactory {
// Local implementation class names and keys from Properties
// file, translate names into Class objects using Class.forName
// and store mappings
Properties properties = new Properties();
final Properties properties = new Properties();
if (implementations == null) {
implementations = new Hashtable<>();
@ -348,7 +353,18 @@ public class SyncFactory {
/*
* Dependent on application
*/
String strRowsetProperties = System.getProperty("rowset.properties");
String strRowsetProperties;
try {
strRowsetProperties = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("rowset.properties");
}
}, null, new PropertyPermission("rowset.properties", "read"));
} catch (Exception ex) {
System.out.println("errorget rowset.properties: " + ex);
strRowsetProperties = null;
};
if (strRowsetProperties != null) {
// Load user's implementation of SyncProvider
// here. -Drowset.properties=/abc/def/pqr.txt
@ -368,14 +384,27 @@ public class SyncFactory {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try (InputStream stream =
(cl == null) ? ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES)
: cl.getResourceAsStream(ROWSET_PROPERTIES)) {
if (stream == null) {
throw new SyncFactoryException(
"Resource " + ROWSET_PROPERTIES + " not found");
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
try (InputStream stream = (cl == null) ?
ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES)
: cl.getResourceAsStream(ROWSET_PROPERTIES)) {
if (stream == null) {
throw new SyncFactoryException("Resource " + ROWSET_PROPERTIES + " not found");
}
properties.load(stream);
}
return null;
});
} catch (PrivilegedActionException ex) {
Throwable e = ex.getException();
if (e instanceof SyncFactoryException) {
throw (SyncFactoryException) e;
} else {
SyncFactoryException sfe = new SyncFactoryException();
sfe.initCause(ex.getException());
throw sfe;
}
properties.load(stream);
}
parseProperties(properties);
@ -393,7 +422,16 @@ public class SyncFactory {
* load additional properties from -D command line
*/
properties.clear();
String providerImpls = System.getProperty(ROWSET_SYNC_PROVIDER);
String providerImpls;
try {
providerImpls = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(ROWSET_SYNC_PROVIDER);
}
}, null, new PropertyPermission(ROWSET_SYNC_PROVIDER, "read"));
} catch (Exception ex) {
providerImpls = null;
}
if (providerImpls != null) {
int i = 0;
@ -526,6 +564,14 @@ public class SyncFactory {
return new com.sun.rowset.providers.RIOptimisticProvider();
}
try {
ReflectUtil.checkPackageAccess(providerID);
} catch (java.security.AccessControlException e) {
SyncFactoryException sfe = new SyncFactoryException();
sfe.initCause(e);
throw sfe;
}
// Attempt to invoke classname from registered SyncProvider list
Class<?> c = null;
try {
@ -534,7 +580,7 @@ public class SyncFactory {
/**
* The SyncProvider implementation of the user will be in
* the classpath. We need to find the ClassLoader which loads
* this SyncFactory and try to laod the SyncProvider class from
* this SyncFactory and try to load the SyncProvider class from
* there.
**/
c = Class.forName(providerID, true, cl);

View File

@ -24,6 +24,7 @@
*/
package javax.swing;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2;
import sun.swing.UIAction;
@ -33,9 +34,6 @@ import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.DropTarget;
import java.util.Vector;
import java.util.Hashtable;
import java.lang.reflect.*;
import javax.accessibility.*;
@ -1872,6 +1870,7 @@ public class SwingUtilities implements SwingConstants
static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
ReflectUtil.checkPackageAccess(className);
return Class.forName(className, true, Thread.currentThread().
getContextClassLoader());
}

View File

@ -27,6 +27,7 @@ package javax.swing.event;
import java.io.*;
import java.util.*;
import java.lang.reflect.Array;
import sun.reflect.misc.ReflectUtil;
/**
* A class that holds a list of EventListeners. A single instance
@ -271,7 +272,9 @@ public class EventListenerList implements Serializable {
while (null != (listenerTypeOrNull = s.readObject())) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
EventListener l = (EventListener)s.readObject();
add((Class<EventListener>)Class.forName((String)listenerTypeOrNull, true, cl), l);
String name = (String) listenerTypeOrNull;
ReflectUtil.checkPackageAccess(name);
add((Class<EventListener>)Class.forName(name, true, cl), l);
}
}

View File

@ -87,7 +87,7 @@ public class ClipboardTransferable implements Transferable {
HashMap cached_data = new HashMap(formats.length, 1.0f);
Map flavorsForFormats = DataTransferer.getInstance().
getFlavorsForFormats(formats, SunClipboard.flavorMap);
getFlavorsForFormats(formats, SunClipboard.getDefaultFlavorTable());
for (Iterator iter = flavorsForFormats.keySet().iterator();
iter.hasNext(); )
{

View File

@ -64,9 +64,6 @@ import sun.awt.EventListenerAggregate;
public abstract class SunClipboard extends Clipboard
implements PropertyChangeListener {
public static final FlavorTable flavorMap =
(FlavorTable)SystemFlavorMap.getDefaultFlavorMap();
private AppContext contentsContext = null;
private final Object CLIPBOARD_FLAVOR_LISTENER_KEY;
@ -172,7 +169,7 @@ public abstract class SunClipboard extends Clipboard
long[] formats = getClipboardFormatsOpenClose();
return DataTransferer.getInstance().
getFlavorsForFormatsAsArray(formats, flavorMap);
getFlavorsForFormatsAsArray(formats, getDefaultFlavorTable());
}
/**
@ -218,7 +215,7 @@ public abstract class SunClipboard extends Clipboard
long[] formats = getClipboardFormats();
Long lFormat = (Long)DataTransferer.getInstance().
getFlavorsForFormats(formats, flavorMap).get(flavor);
getFlavorsForFormats(formats, getDefaultFlavorTable()).get(flavor);
if (lFormat == null) {
throw new UnsupportedFlavorException(flavor);
@ -349,7 +346,7 @@ public abstract class SunClipboard extends Clipboard
private static Set formatArrayAsDataFlavorSet(long[] formats) {
return (formats == null) ? null :
DataTransferer.getInstance().
getFlavorsForFormatsAsSet(formats, flavorMap);
getFlavorsForFormatsAsSet(formats, getDefaultFlavorTable());
}
@ -469,4 +466,7 @@ public abstract class SunClipboard extends Clipboard
}
}
public static FlavorTable getDefaultFlavorTable() {
return (FlavorTable) SystemFlavorMap.getDefaultFlavorMap();
}
}

View File

@ -541,9 +541,11 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
* to last and last, respectively, in the case of a POST
* request.
*/
if (!failedOnce)
requests.prepend(method + " " + getRequestURI()+" " +
httpVersion, null);
if (!failedOnce) {
checkURLFile();
requests.prepend(method + " " + getRequestURI() + " " +
httpVersion, null);
}
if (!getUseCaches()) {
requests.setIfNotSet ("Cache-Control", "no-cache");
requests.setIfNotSet ("Pragma", "no-cache");
@ -554,7 +556,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
if (port != -1 && port != url.getDefaultPort()) {
host += ":" + String.valueOf(port);
}
requests.setIfNotSet("Host", host);
String reqHost = requests.findValue("Host");
if (reqHost == null ||
(!reqHost.equalsIgnoreCase(host) && !checkSetHost()))
{
requests.set("Host", host);
}
requests.setIfNotSet("Accept", acceptString);
/*
@ -671,6 +678,44 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
}
}
private boolean checkSetHost() {
SecurityManager s = System.getSecurityManager();
if (s != null) {
String name = s.getClass().getName();
if (name.equals("sun.plugin2.applet.AWTAppletSecurityManager") ||
name.equals("sun.plugin2.applet.FXAppletSecurityManager") ||
name.equals("com.sun.javaws.security.JavaWebStartSecurity") ||
name.equals("sun.plugin.security.ActivatorSecurityManager"))
{
int CHECK_SET_HOST = -2;
try {
s.checkConnect(url.toExternalForm(), CHECK_SET_HOST);
} catch (SecurityException ex) {
return false;
}
}
}
return true;
}
private void checkURLFile() {
SecurityManager s = System.getSecurityManager();
if (s != null) {
String name = s.getClass().getName();
if (name.equals("sun.plugin2.applet.AWTAppletSecurityManager") ||
name.equals("sun.plugin2.applet.FXAppletSecurityManager") ||
name.equals("com.sun.javaws.security.JavaWebStartSecurity") ||
name.equals("sun.plugin.security.ActivatorSecurityManager"))
{
int CHECK_SUBPATH = -3;
try {
s.checkConnect(url.toExternalForm(), CHECK_SUBPATH);
} catch (SecurityException ex) {
throw new SecurityException("denied access outside a permitted URL subpath", ex);
}
}
}
}
/**
* Create a new HttpClient object, bypassing the cache of

View File

@ -428,6 +428,10 @@ abstract class AsynchronousSocketChannelImpl
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);

View File

@ -572,6 +572,10 @@ class SocketChannelImpl
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);

View File

@ -28,7 +28,10 @@ package sun.reflect.generics.reflectiveObjects;
import java.lang.annotation.*;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.LinkedHashMap;
@ -40,6 +43,7 @@ import sun.reflect.annotation.AnnotationType;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.misc.ReflectUtil;
/**
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
@ -95,6 +99,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
TypeVariableImpl<T> make(T decl, String name,
FieldTypeSignature[] bs,
GenericsFactory f) {
if (!((decl instanceof Class) ||
(decl instanceof Method) ||
(decl instanceof Constructor))) {
throw new AssertionError("Unexpected kind of GenericDeclaration" +
decl.getClass().toString());
}
return new TypeVariableImpl<T>(decl, name, bs, f);
}
@ -149,6 +160,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
* @since 1.5
*/
public D getGenericDeclaration(){
if (genericDeclaration instanceof Class)
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
else if ((genericDeclaration instanceof Method) ||
(genericDeclaration instanceof Constructor))
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration);
else
throw new AssertionError("Unexpected kind of GenericDeclaration");
return genericDeclaration;
}
@ -164,7 +182,8 @@ public class TypeVariableImpl<D extends GenericDeclaration>
@Override
public boolean equals(Object o) {
if (o instanceof TypeVariable) {
if (o instanceof TypeVariable &&
o.getClass() == TypeVariableImpl.class) {
TypeVariable<?> that = (TypeVariable<?>) o;
GenericDeclaration thatDecl = that.getGenericDeclaration();

View File

@ -26,11 +26,13 @@
package sun.reflect.misc;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
public final class ReflectUtil {
@ -117,6 +119,40 @@ public final class ReflectUtil {
return false;
}
/**
* Does a conservative approximation of member access check. Use this if
* you don't have an actual 'userland' caller Class/ClassLoader available.
* This might be more restrictive than a precise member access check where
* you have a caller, but should never allow a member access that is
* forbidden.
*
* @param m the {@code Member} about to be accessed
*/
public static void conservativeCheckMemberAccess(Member m) throws SecurityException{
final SecurityManager sm = System.getSecurityManager();
if (sm == null)
return;
// Check for package access on the declaring class.
//
// In addition, unless the member and the declaring class are both
// public check for access declared member permissions.
//
// This is done regardless of ClassLoader relations between the {@code
// Member m} and any potential caller.
final Class<?> declaringClass = m.getDeclaringClass();
checkPackageAccess(declaringClass);
if (Modifier.isPublic(m.getModifiers()) &&
Modifier.isPublic(declaringClass.getModifiers()))
return;
// Check for declared member access.
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
/**
* Checks package access on the given class.
*

View File

@ -94,8 +94,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
RMIServerSocketFactory ssf)
throws RemoteException
{
LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref));
if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) {
// grant permission for default port only.
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws RemoteException {
LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref));
return null;
}
}, null, new SocketPermission("localhost:"+port, "listen,accept"));
} catch (PrivilegedActionException pae) {
throw (RemoteException)pae.getException();
}
} else {
LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref));
}
}
/**
@ -104,8 +119,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl(int port)
throws RemoteException
{
LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref));
if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) {
// grant permission for default port only.
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws RemoteException {
LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref));
return null;
}
}, null, new SocketPermission("localhost:"+port, "listen,accept"));
} catch (PrivilegedActionException pae) {
throw (RemoteException)pae.getException();
}
} else {
LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref));
}
}
/*
@ -352,7 +382,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl run() throws RemoteException {
return new RegistryImpl(regPort);
}
}, getAccessControlContext());
}, getAccessControlContext(regPort));
} catch (PrivilegedActionException ex) {
throw (RemoteException) ex.getException();
}
@ -382,7 +412,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* The approach used here is taken from the similar method
* getAccessControlContext() in the sun.applet.AppletPanel class.
*/
private static AccessControlContext getAccessControlContext() {
private static AccessControlContext getAccessControlContext(int port) {
// begin with permissions granted to all code in current policy
PermissionCollection perms = AccessController.doPrivileged(
new java.security.PrivilegedAction<PermissionCollection>() {
@ -404,6 +434,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* related classes themselves are more tightly limited by RMI.
*/
perms.add(new SocketPermission("*", "connect,accept"));
perms.add(new SocketPermission("localhost:"+port, "listen,accept"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*"));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -45,11 +45,12 @@ public class TlsRsaPremasterSecretParameterSpec
private final int majorVersion;
private final int minorVersion;
private final byte[] encodedSecret;
/**
* Constructs a new TlsRsaPremasterSecretParameterSpec.
*
* <p>The version numbers will be placed inside the premaster secret to
* <P>
* The version numbers will be placed inside the premaster secret to
* detect version rollbacks attacks as described in the TLS specification.
* Note that they do not indicate the protocol version negotiated for
* the handshake.
@ -65,7 +66,42 @@ public class TlsRsaPremasterSecretParameterSpec
this.majorVersion =
TlsMasterSecretParameterSpec.checkVersion(majorVersion);
this.minorVersion =
TlsMasterSecretParameterSpec.checkVersion(minorVersion); }
TlsMasterSecretParameterSpec.checkVersion(minorVersion);
this.encodedSecret = null;
}
/**
* Constructs a new TlsRsaPremasterSecretParameterSpec.
* <P>
* The version numbers will be placed inside the premaster secret to
* detect version rollbacks attacks as described in the TLS specification.
* Note that they do not indicate the protocol version negotiated for
* the handshake.
* <P>
* Usually, the encoded secret key is a random number that acts as
* dummy pre_master_secret to avoid vulnerabilities described by
* section 7.4.7.1, RFC 5246.
*
* @param majorVersion the major number of the protocol version
* @param minorVersion the minor number of the protocol version
* @param encodedSecret the encoded secret key
*
* @throws IllegalArgumentException if minorVersion or majorVersion are
* negative or larger than 255, or encodedSecret is not exactly 48 bytes.
*/
public TlsRsaPremasterSecretParameterSpec(int majorVersion,
int minorVersion, byte[] encodedSecret) {
this.majorVersion =
TlsMasterSecretParameterSpec.checkVersion(majorVersion);
this.minorVersion =
TlsMasterSecretParameterSpec.checkVersion(minorVersion);
if (encodedSecret == null || encodedSecret.length != 48) {
throw new IllegalArgumentException(
"Encoded secret is not exactly 48 bytes");
}
this.encodedSecret = encodedSecret.clone();
}
/**
* Returns the major version.
@ -84,4 +120,13 @@ public class TlsRsaPremasterSecretParameterSpec
public int getMinorVersion() {
return minorVersion;
}
/**
* Returns the encoded secret.
*
* @return the encoded secret, may be null if no encoded secret.
*/
public byte[] getEncodedSecret() {
return encodedSecret == null ? null : encodedSecret.clone();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -451,30 +451,7 @@ final class P11RSACipher extends CipherSpi {
// see JCE spec
protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
int type) throws InvalidKeyException, NoSuchAlgorithmException {
if (algorithm.equals("TlsRsaPremasterSecret")) {
// the instance variable "session" has been initialized for
// decrypt mode, so use a local variable instead.
Session s = null;
try {
s = token.getObjSession();
long keyType = CKK_GENERIC_SECRET;
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
};
attributes = token.getAttributes
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_UnwrapKey(s.id(),
new CK_MECHANISM(mechanism), p11Key.keyID, wrappedKey,
attributes);
return P11Key.secretKey(s, keyID, algorithm, 48 << 3,
attributes);
} catch (PKCS11Exception e) {
throw new InvalidKeyException("unwrap() failed", e);
} finally {
token.releaseSession(s);
}
}
// XXX implement unwrap using C_Unwrap() for all keys
implInit(Cipher.DECRYPT_MODE, p11Key);
if (wrappedKey.length > maxInputSize) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -88,23 +88,33 @@ final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
throw new IllegalStateException
("TlsRsaPremasterSecretGenerator must be initialized");
}
CK_VERSION version =
new CK_VERSION(spec.getMajorVersion(), spec.getMinorVersion());
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_GenerateKey
(session.id(), new CK_MECHANISM(mechanism, version), attributes);
SecretKey key = P11Key.secretKey
(session, keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
return key;
} catch (PKCS11Exception e) {
throw new ProviderException("Could not generate premaster secret", e);
} finally {
token.releaseSession(session);
byte[] b = spec.getEncodedSecret();
if (b == null) {
CK_VERSION version = new CK_VERSION(
spec.getMajorVersion(), spec.getMinorVersion());
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes(
O_GENERATE, CKO_SECRET_KEY,
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_GenerateKey(session.id(),
new CK_MECHANISM(mechanism, version), attributes);
SecretKey key = P11Key.secretKey(session,
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
return key;
} catch (PKCS11Exception e) {
throw new ProviderException(
"Could not generate premaster secret", e);
} finally {
token.releaseSession(session);
}
}
// Won't worry, the TlsRsaPremasterSecret will be soon converted to
// TlsMasterSecret.
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -43,10 +43,8 @@ import sun.misc.Unsafe;
* These are the only platforms we currently support, but other optimized
* variants could be added as needed.
*
* NOTE that because this code performs unchecked direct memory access, it
* MUST be restricted to trusted code. It is imperative that the caller protects
* against out of bounds memory access by performing the necessary bounds
* checks before calling methods in this class.
* NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks
* failed.
*
* This class may also be helpful in improving the performance of the
* crypto code in the SunJCE provider. However, for now it is only accessible by
@ -103,6 +101,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, little endian byte order.
*/
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
@ -131,6 +133,10 @@ final class ByteArrayAccess {
// Special optimization of b2iLittle(in, inOfs, out, 0, 64)
static void b2iLittle64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = unsafe.getInt(in, (long)(inOfs ));
@ -176,6 +182,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, little endian byte order.
*/
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
@ -204,6 +214,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.
static void i2bLittle4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
} else if (bigEndian && ((outOfs & 3) == 0)) {
@ -220,6 +233,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, big endian byte order.
*/
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
@ -248,6 +265,10 @@ final class ByteArrayAccess {
// Special optimization of b2iBig(in, inOfs, out, 0, 64)
static void b2iBig64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
@ -293,6 +314,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, big endian byte order.
*/
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
@ -321,6 +346,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
static void i2bBig4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
} else if (bigEndian && ((outOfs & 3) == 0)) {
@ -337,6 +365,10 @@ final class ByteArrayAccess {
* byte[] to long[] conversion, big endian byte order.
*/
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/8)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
@ -378,6 +410,10 @@ final class ByteArrayAccess {
// Special optimization of b2lBig(in, inOfs, out, 0, 128)
static void b2lBig128(byte[] in, int inOfs, long[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 128) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs )));
@ -406,6 +442,10 @@ final class ByteArrayAccess {
* long[] to byte[] conversion, big endian byte order.
*/
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
len += outOfs;
while (outOfs < len) {
long i = in[inOfs++];
@ -419,5 +459,4 @@ final class ByteArrayAccess {
out[outOfs++] = (byte)(i );
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -318,33 +318,53 @@ public final class RSAPadding {
/**
* PKCS#1 v1.5 unpadding (blocktype 1 and 2).
*
* Note that we want to make it a constant-time operation
*/
private byte[] unpadV15(byte[] padded) throws BadPaddingException {
int k = 0;
BadPaddingException bpe = null;
if (padded[k++] != 0) {
throw new BadPaddingException("Data must start with zero");
bpe = new BadPaddingException("Data must start with zero");
}
if (padded[k++] != type) {
throw new BadPaddingException("Blocktype mismatch: " + padded[1]);
if (padded[k++] != type && bpe == null) {
bpe = new BadPaddingException("Blocktype mismatch: " + padded[1]);
}
while (true) {
int p = 0;
while (k < padded.length) {
int b = padded[k++] & 0xff;
if (b == 0) {
break;
if (b == 0 && p == 0) {
p = k;
}
if (k == padded.length) {
throw new BadPaddingException("Padding string not terminated");
if (k == padded.length && p == 0 && bpe == null) {
bpe = new BadPaddingException("Padding string not terminated");
}
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff)) {
throw new BadPaddingException("Padding byte not 0xff: " + b);
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
p == 0 && bpe == null) {
bpe = new BadPaddingException("Padding byte not 0xff: " + b);
}
}
int n = padded.length - k;
if (n > maxDataSize) {
throw new BadPaddingException("Padding string too short");
int n = padded.length - p;
if (n > maxDataSize && bpe == null) {
bpe = new BadPaddingException("Padding string too short");
}
// copy useless padding array for a constant-time method
//
// Is it necessary?
byte[] padding = new byte[p];
System.arraycopy(padded, 0, padding, 0, p);
byte[] data = new byte[n];
System.arraycopy(padded, padded.length - n, data, 0, n);
System.arraycopy(padded, p, data, 0, n);
if (bpe == null) {
bpe = new BadPaddingException("Unused exception");
} else {
throw bpe;
}
return data;
}

View File

@ -1104,94 +1104,23 @@ abstract class Handshaker {
clnt_random.random_bytes, svr_random.random_bytes,
prfHashAlg, prfHashLength, prfBlockSize);
SecretKey masterSecret;
try {
KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
kg.init(spec);
masterSecret = kg.generateKey();
} catch (GeneralSecurityException e) {
return kg.generateKey();
} catch (InvalidAlgorithmParameterException |
NoSuchAlgorithmException iae) {
// unlikely to happen, otherwise, must be a provider exception
//
// For RSA premaster secrets, do not signal a protocol error
// due to the Bleichenbacher attack. See comments further down.
if (!preMasterSecret.getAlgorithm().equals(
"TlsRsaPremasterSecret")) {
throw new ProviderException(e);
}
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA master secret generation error:");
e.printStackTrace(System.out);
iae.printStackTrace(System.out);
}
throw new ProviderException(iae);
if (requestedVersion != null) {
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(requestedVersion);
} else {
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(protocolVersion);
}
// recursive call with new premaster secret
return calculateMasterSecret(preMasterSecret, null);
}
// if no version check requested (client side handshake), or version
// information is not available (not an RSA premaster secret),
// return master secret immediately.
if ((requestedVersion == null) ||
!(masterSecret instanceof TlsMasterSecret)) {
return masterSecret;
}
// we have checked the ClientKeyExchange message when reading TLS
// record, the following check is necessary to ensure that
// JCE provider does not ignore the checking, or the previous
// checking process bypassed the premaster secret version checking.
TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
int major = tlsKey.getMajorVersion();
int minor = tlsKey.getMinorVersion();
if ((major < 0) || (minor < 0)) {
return masterSecret;
}
// check if the premaster secret version is ok
// the specification says that it must be the maximum version supported
// by the client from its ClientHello message. However, many
// implementations send the negotiated version, so accept both
// for SSL v3.0 and TLS v1.0.
// NOTE that we may be comparing two unsupported version numbers, which
// is why we cannot use object reference equality in this special case.
ProtocolVersion premasterVersion =
ProtocolVersion.valueOf(major, minor);
boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
/*
* we never checked the client_version in server side
* for TLS v1.0 and SSL v3.0. For compatibility, we
* maintain this behavior.
*/
if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
versionMismatch = (premasterVersion.v != protocolVersion.v);
}
if (versionMismatch == false) {
// check passed, return key
return masterSecret;
}
// Due to the Bleichenbacher attack, do not signal a protocol error.
// Generate a random premaster secret and continue with the handshake,
// which will fail when verifying the finished messages.
// For more information, see comments in PreMasterSecret.
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA PreMasterSecret version error: expected"
+ protocolVersion + " or " + requestedVersion + ", decrypted: "
+ premasterVersion);
}
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(requestedVersion);
// recursive call with new premaster secret
return calculateMasterSecret(preMasterSecret, null);
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -133,26 +133,37 @@ final class RSAClientKeyExchange extends HandshakeMessage {
} else {
encrypted = new byte [messageSize];
if (input.read(encrypted) != messageSize) {
throw new SSLProtocolException
("SSL: read PreMasterSecret: short read");
throw new SSLProtocolException(
"SSL: read PreMasterSecret: short read");
}
}
Exception failover = null;
byte[] encoded = null;
try {
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
cipher.init(Cipher.UNWRAP_MODE, privateKey);
preMaster = (SecretKey)cipher.unwrap(encrypted,
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
// polish the premaster secret
preMaster = polishPreMasterSecretKey(currentVersion, maxVersion,
generator, preMaster, null);
// Cannot generate key here, please don't use Cipher.UNWRAP_MODE!
cipher.init(Cipher.DECRYPT_MODE, privateKey);
encoded = cipher.doFinal(encrypted);
} catch (BadPaddingException bpe) {
failover = bpe;
encoded = null;
} catch (IllegalBlockSizeException ibse) {
// the message it too big to process with RSA
throw new SSLProtocolException(
"Unable to process PreMasterSecret, may be too big");
} catch (Exception e) {
// polish the premaster secret
preMaster =
polishPreMasterSecretKey(currentVersion, maxVersion,
generator, null, e);
// unlikely to happen, otherwise, must be a provider exception
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA premaster secret decryption error:");
e.printStackTrace(System.out);
}
throw new RuntimeException("Could not generate dummy secret", e);
}
// polish the premaster secret
preMaster = polishPreMasterSecretKey(
currentVersion, maxVersion, generator, encoded, failover);
}
/**
@ -163,85 +174,74 @@ final class RSAClientKeyExchange extends HandshakeMessage {
*
* RFC 5246 describes the approach as :
*
* 1. Generate a string R of 46 random bytes
* 1. Generate a string R of 48 random bytes
*
* 2. Decrypt the message to recover the plaintext M
*
* 3. If the PKCS#1 padding is not correct, or the length of message
* M is not exactly 48 bytes:
* pre_master_secret = ClientHello.client_version || R
* pre_master_secret = R
* else If ClientHello.client_version <= TLS 1.0, and version
* number check is explicitly disabled:
* pre_master_secret = M
* premaster secret = M
* else If M[0..1] != ClientHello.client_version:
* premaster secret = R
* else:
* pre_master_secret = ClientHello.client_version || M[2..47]
* premaster secret = M
*
* Note that #2 has completed before the call of this method.
*/
private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion,
ProtocolVersion clientHelloVersion, SecureRandom generator,
SecretKey secretKey, Exception failoverException) {
byte[] encoded, Exception failoverException) {
this.protocolVersion = clientHelloVersion;
if (generator == null) {
generator = new SecureRandom();
}
byte[] random = new byte[48];
generator.nextBytes(random);
if (failoverException == null && secretKey != null) {
if (failoverException == null && encoded != null) {
// check the length
byte[] encoded = secretKey.getEncoded();
if (encoded == null) { // unable to get the encoded key
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"unable to get the plaintext of the premaster secret");
}
int keySize = KeyUtil.getKeySize(secretKey);
if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"incorrect length of premaster secret: " +
(keySize/8));
}
return generateDummySecret(clientHelloVersion);
}
// The key size is exactly 48 bytes or not accessible.
//
// Conservatively, pass the checking to master secret
// calculation.
return secretKey;
} else if (encoded.length == 48) {
// check the version
if (clientHelloVersion.major == encoded[0] &&
clientHelloVersion.minor == encoded[1]) {
return secretKey;
} else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
currentVersion.major == encoded[0] &&
currentVersion.minor == encoded[1]) {
/*
* For compatibility, we maintain the behavior that the
* version in pre_master_secret can be the negotiated
* version for TLS v1.0 and SSL v3.0.
*/
this.protocolVersion = currentVersion;
return secretKey;
}
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Mismatching Protocol Versions, " +
"ClientHello.client_version is " + clientHelloVersion +
", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1]));
}
return generateDummySecret(clientHelloVersion);
} else {
if (encoded.length != 48) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"incorrect length of premaster secret: " +
encoded.length);
}
return generateDummySecret(clientHelloVersion);
return generatePreMasterSecret(
clientHelloVersion, random, generator);
}
if (clientHelloVersion.major != encoded[0] ||
clientHelloVersion.minor != encoded[1]) {
if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
currentVersion.major == encoded[0] &&
currentVersion.minor == encoded[1]) {
/*
* For compatibility, we maintain the behavior that the
* version in pre_master_secret can be the negotiated
* version for TLS v1.0 and SSL v3.0.
*/
this.protocolVersion = currentVersion;
} else {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Mismatching Protocol Versions, " +
"ClientHello.client_version is " +
clientHelloVersion +
", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1]));
}
encoded = random;
}
}
return generatePreMasterSecret(
clientHelloVersion, encoded, generator);
}
if (debug != null && Debug.isOn("handshake") &&
@ -250,11 +250,14 @@ final class RSAClientKeyExchange extends HandshakeMessage {
failoverException.printStackTrace(System.out);
}
return generateDummySecret(clientHelloVersion);
return generatePreMasterSecret(clientHelloVersion, random, generator);
}
// generate a premaster secret with the specified version number
static SecretKey generateDummySecret(ProtocolVersion version) {
private static SecretKey generatePreMasterSecret(
ProtocolVersion version, byte[] encodedSecret,
SecureRandom generator) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Generating a random fake premaster secret");
}
@ -263,11 +266,17 @@ final class RSAClientKeyExchange extends HandshakeMessage {
String s = ((version.v >= ProtocolVersion.TLS12.v) ?
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
KeyGenerator kg = JsseJce.getKeyGenerator(s);
kg.init(new TlsRsaPremasterSecretParameterSpec
(version.major, version.minor));
kg.init(new TlsRsaPremasterSecretParameterSpec(
version.major, version.minor, encodedSecret), generator);
return kg.generateKey();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate dummy secret", e);
} catch (InvalidAlgorithmParameterException |
NoSuchAlgorithmException iae) {
// unlikely to happen, otherwise, must be a provider exception
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA premaster secret generation error:");
iae.printStackTrace(System.out);
}
throw new RuntimeException("Could not generate dummy secret", iae);
}
}

View File

@ -90,9 +90,6 @@ public class Main {
private static final String META_INF = "META-INF/";
// prefix for new signature-related files in META-INF directory
private static final String SIG_PREFIX = META_INF + "SIG-";
private static final Class<?>[] PARAM_STRING = { String.class };
private static final String NONE = "NONE";
@ -158,8 +155,13 @@ public class Main {
private String altSignerClasspath = null;
private ZipFile zipFile = null;
private boolean hasExpiredCert = false;
// Informational warnings
private boolean hasExpiringCert = false;
private boolean noTimestamp = false;
private Date expireDate = new Date(0L); // used in noTimestamp warning
// Severe warnings
private boolean hasExpiredCert = false;
private boolean notYetValidCert = false;
private boolean chainNotValidated = false;
private boolean notSignedByAlias = false;
@ -258,9 +260,6 @@ public class Main {
if (strict) {
int exitCode = 0;
if (hasExpiringCert) {
exitCode |= 2;
}
if (chainNotValidated || hasExpiredCert || notYetValidCert) {
exitCode |= 4;
}
@ -754,14 +753,25 @@ public class Main {
System.out.println(rb.getString(
"jar.is.unsigned.signatures.missing.or.not.parsable."));
} else {
System.out.println(rb.getString("jar.verified."));
if (hasUnsignedEntry || hasExpiredCert || hasExpiringCert ||
badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated ||
aliasNotInStore || notSignedByAlias) {
boolean warningAppeared = false;
boolean errorAppeared = false;
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated || hasExpiredCert ||
hasUnsignedEntry ||
aliasNotInStore || notSignedByAlias) {
if (strict) {
System.out.println(rb.getString("jar.verified.with.signer.errors."));
System.out.println();
System.out.println(rb.getString("Error."));
errorAppeared = true;
} else {
System.out.println(rb.getString("jar.verified."));
System.out.println();
System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
System.out.println();
System.out.println(rb.getString("Warning."));
if (badKeyUsage) {
System.out.println(
rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
@ -785,10 +795,6 @@ public class Main {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.has.expired."));
}
if (hasExpiringCert) {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
}
if (notYetValidCert) {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid."));
@ -807,10 +813,29 @@ public class Main {
if (aliasNotInStore) {
System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore."));
}
} else {
System.out.println(rb.getString("jar.verified."));
}
if (hasExpiringCert || noTimestamp) {
if (!warningAppeared) {
System.out.println();
System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
if (hasExpiringCert) {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
}
if (noTimestamp) {
System.out.println(
String.format(rb.getString("no.timestamp.verifying"), expireDate));
}
}
if (warningAppeared || errorAppeared) {
if (! (verbose != null && showcerts)) {
System.out.println();
System.out.println(rb.getString(
"Re.run.with.the.verbose.and.certs.options.for.more.details."));
"Re.run.with.the.verbose.and.certs.options.for.more.details."));
}
}
}
@ -870,6 +895,9 @@ public class Main {
try {
boolean printValidity = true;
if (timestamp == null) {
if (expireDate.getTime() == 0 || expireDate.after(notAfter)) {
expireDate = notAfter;
}
x509Cert.checkValidity();
// test if cert will expire within six months
if (notAfter.getTime() < System.currentTimeMillis() + SIX_MONTHS) {
@ -1233,6 +1261,10 @@ public class Main {
tsaCert = getTsaCert(tsaAlias);
}
if (tsaUrl == null && tsaCert == null) {
noTimestamp = true;
}
SignatureFile.Block block = null;
try {
@ -1380,12 +1412,20 @@ public class Main {
}
}
if (hasExpiredCert || hasExpiringCert || notYetValidCert
|| badKeyUsage || badExtendedKeyUsage
|| badNetscapeCertType || chainNotValidated) {
System.out.println();
boolean warningAppeared = false;
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated || hasExpiredCert) {
if (strict) {
System.out.println(rb.getString("jar.signed.with.signer.errors."));
System.out.println();
System.out.println(rb.getString("Error."));
} else {
System.out.println(rb.getString("jar.signed."));
System.out.println();
System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
System.out.println(rb.getString("Warning."));
if (badKeyUsage) {
System.out.println(
rb.getString("The.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
@ -1404,9 +1444,6 @@ public class Main {
if (hasExpiredCert) {
System.out.println(
rb.getString("The.signer.certificate.has.expired."));
} else if (hasExpiringCert) {
System.out.println(
rb.getString("The.signer.certificate.will.expire.within.six.months."));
} else if (notYetValidCert) {
System.out.println(
rb.getString("The.signer.certificate.is.not.yet.valid."));
@ -1416,6 +1453,24 @@ public class Main {
System.out.println(
rb.getString("The.signer.s.certificate.chain.is.not.validated."));
}
} else {
System.out.println(rb.getString("jar.signed."));
}
if (hasExpiringCert || noTimestamp) {
if (!warningAppeared) {
System.out.println();
System.out.println(rb.getString("Warning."));
}
if (hasExpiringCert) {
System.out.println(
rb.getString("The.signer.certificate.will.expire.within.six.months."));
}
if (noTimestamp) {
System.out.println(
String.format(rb.getString("no.timestamp.signing"), expireDate));
}
}
// no IOException thrown in the above try clause, so disable
@ -1464,22 +1519,7 @@ public class Main {
* . META-INF/*.EC
*/
private boolean signatureRelated(String name) {
String ucName = name.toUpperCase(Locale.ENGLISH);
if (ucName.equals(JarFile.MANIFEST_NAME) ||
ucName.equals(META_INF) ||
(ucName.startsWith(SIG_PREFIX) &&
ucName.indexOf("/") == ucName.lastIndexOf("/"))) {
return true;
}
if (ucName.startsWith(META_INF) &&
SignatureFileVerifier.isBlockOrSF(ucName)) {
// .SF/.DSA/.RSA/.EC files in META-INF subdirs
// are not considered signature-related
return (ucName.indexOf("/") == ucName.lastIndexOf("/"));
}
return false;
return SignatureFileVerifier.isSigningRelated(name);
}
Map<CodeSigner,String> cacheForSignerInfo = new IdentityHashMap<>();
@ -1502,6 +1542,7 @@ public class Main {
timestamp = ts.getTimestamp();
} else {
timestamp = null;
noTimestamp = true;
}
// display the certificate(s). The first one is end-entity cert and
// its KeyUsage should be checked.

View File

@ -112,9 +112,9 @@ public class Resources extends java.util.ListResourceBundle {
{"Please.specify.alias.name", "Please specify alias name"},
{"Only.one.alias.can.be.specified", "Only one alias can be specified"},
{"This.jar.contains.signed.entries.which.is.not.signed.by.the.specified.alias.es.",
"This jar contains signed entries which is not signed by the specified alias(es)."},
"This jar contains signed entries which are not signed by the specified alias(es)."},
{"This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore.",
"This jar contains signed entries that's not signed by alias in this keystore."},
"This jar contains signed entries that are not signed by alias in this keystore."},
{"s", "s"},
{"m", "m"},
{"k", "k"},
@ -135,7 +135,10 @@ public class Resources extends java.util.ListResourceBundle {
{".Unsigned.entries.", "(Unsigned entries)"},
{"jar.is.unsigned.signatures.missing.or.not.parsable.",
"jar is unsigned. (signatures missing or not parsable)"},
{"jar.signed.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."},
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
{"jarsigner.", "jarsigner: "},
{"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
"signature filename must consist of the following characters: A-Z, 0-9, _ or -"},
@ -193,6 +196,7 @@ public class Resources extends java.util.ListResourceBundle {
"using an alternative signing mechanism"},
{"entry.was.signed.on", "entry was signed on {0}"},
{"Warning.", "Warning: "},
{"Error.", "Error: "},
{"This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked.",
"This jar contains unsigned entries which have not been integrity-checked. "},
{"This.jar.contains.entries.whose.signer.certificate.has.expired.",
@ -229,6 +233,10 @@ public class Resources extends java.util.ListResourceBundle {
"The signer's certificate chain is not validated."},
{"This.jar.contains.entries.whose.certificate.chain.is.not.validated.",
"This jar contains entries whose certificate chain is not validated."},
{"no.timestamp.signing",
"No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
{"no.timestamp.verifying",
"This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
{"Unknown.password.type.", "Unknown password type: "},
{"Cannot.find.environment.variable.",
"Cannot find environment variable: "},

View File

@ -222,5 +222,5 @@ public final class SecurityConstants {
// java.lang.SecurityManager
public static final SocketPermission LOCAL_LISTEN_PERMISSION =
new SocketPermission("localhost:1024-", SOCKET_LISTEN_ACTION);
new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION);
}

View File

@ -152,6 +152,52 @@ public class SignatureFileVerifier {
return false;
}
/**
* Yet another utility method used by JarVerifier and JarSigner
* to determine what files are signature related, which includes
* the MANIFEST, SF files, known signature block files, and other
* unknown signature related files (those starting with SIG- with
* an optional [A-Z0-9]{1,3} extension right inside META-INF).
*
* @param s file name
* @return true if the input file name is signature related
*/
public static boolean isSigningRelated(String name) {
name = name.toUpperCase(Locale.ENGLISH);
if (!name.startsWith("META-INF/")) {
return false;
}
name = name.substring(9);
if (name.indexOf('/') != -1) {
return false;
}
if (isBlockOrSF(name) || name.equals("MANIFEST.MF")) {
return true;
} else if (name.startsWith("SIG-")) {
// check filename extension
// see http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures
// for what filename extensions are legal
int extIndex = name.lastIndexOf('.');
if (extIndex != -1) {
String ext = name.substring(extIndex + 1);
// validate length first
if (ext.length() > 3 || ext.length() < 1) {
return false;
}
// then check chars, must be in [a-zA-Z0-9] per the jar spec
for (int index = 0; index < ext.length(); index++) {
char cc = ext.charAt(index);
// chars are promoted to uppercase so skip lowercase checks
if ((cc < 'A' || cc > 'Z') && (cc < '0' || cc > '9')) {
return false;
}
}
}
return true; // no extension is OK
}
return false;
}
/** get digest from cache */
private MessageDigest getDigest(String algorithm)

View File

@ -2,48 +2,48 @@
// Standard extensions get all permissions by default
grant codeBase "file:${{java.ext.dirs}}/*" {
permission java.security.AllPermission;
permission java.security.AllPermission;
};
// default permissions granted to all domains
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See the API specification of java.lang.Thread.stop() for more
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See the API specification of java.lang.Thread.stop() for more
// information.
permission java.lang.RuntimePermission "stopThread";
permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on un-privileged ports
permission java.net.SocketPermission "localhost:1024-", "listen";
// allows anyone to listen on dynamic ports
permission java.net.SocketPermission "localhost:0", "listen";
// "standard" properies that can be read by anyone
// "standard" properies that can be read by anyone
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
};

View File

@ -182,6 +182,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -205,7 +206,7 @@ package.access=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
@ -228,6 +229,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -251,7 +253,7 @@ package.definition=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048

View File

@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048

View File

@ -184,6 +184,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -207,7 +208,7 @@ package.access=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -252,7 +254,7 @@ package.definition=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048

View File

@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -206,7 +207,7 @@ package.access=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
@ -252,7 +254,7 @@ package.definition=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048

View File

@ -435,9 +435,7 @@ DGifGetImageDesc(GifFileType * GifFile) {
Private->PixelCount = (long)GifFile->Image.Width *
(long)GifFile->Image.Height;
DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
return GIF_OK;
return DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
}
/******************************************************************************

View File

@ -228,6 +228,49 @@ getMlibEdgeHint(jint edgeHint) {
}
}
/*
* We have to make sure that awt_setPixels can be safely applied to the given pair of
* raster and mlib image.
*
* In particular, make sure that
* - dimension is the same
* - number of channels in mlib image corresponds to the number of bands in the raster
* - sample size in image and raster are the same.
*
* Returns:
* -1 to indicate failure,
* 1 to indicate success
*/
static int setPixelsFormMlibImage(JNIEnv *env, RasterS_t *rasterP, mlib_image* img) {
if (rasterP->width != img->width || rasterP->height != img->height) {
/* dimension does not match */
return -1;
}
if (rasterP->numBands != img->channels) {
/* number of bands does not match */
return -1;
}
switch (rasterP->dataType) {
case BYTE_DATA_TYPE:
if (img->type != MLIB_BYTE) {
return -1;
}
break;
case SHORT_DATA_TYPE:
if (img->type != MLIB_SHORT && img->type != MLIB_USHORT) {
return -1;
}
break;
default:
/* awt_setPixels does not support such rasters */
return -1;
}
return awt_setPixels(env, rasterP, mlib_ImageGetData(img));
}
/***************************************************************************
* External Functions *
***************************************************************************/
@ -700,7 +743,9 @@ Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this,
/* Means that we couldn't write directly into the destination buffer */
if (ddata == NULL) {
retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
}
}
/* Release the pinned memory */
@ -1106,7 +1151,7 @@ fprintf(stderr,"Flags : %d\n",dst->flags);
if (ddata == NULL) {
/* Need to store it back into the array */
if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
}
}
@ -1432,6 +1477,14 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib,
retStatus = 0;
}
/* Release the LUT */
for (i=0; i < lut_nbands; i++) {
(*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
(jbyte *) jtable[i].table, JNI_ABORT);
}
free ((void *) jtable);
free ((void *) tbl);
/*
* Means that we couldn't write directly into
* the destination buffer
@ -1445,13 +1498,6 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib,
}
}
/* Release the LUT */
for (i=0; i < lut_nbands; i++) {
(*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
(jbyte *) jtable[i].table, JNI_ABORT);
}
free ((void *) jtable);
free ((void *) tbl);
/* Release the pinned memory */
freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
@ -1669,18 +1715,20 @@ Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
retStatus = 0;
}
/* Release the LUT */
for (i=0; i < lut_nbands; i++) {
(*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
(jbyte *) jtable[i].table, JNI_ABORT);
}
/*
* Means that we couldn't write directly into
* the destination buffer
*/
if (ddata == NULL) {
retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
}
/* Release the LUT */
for (i=0; i < lut_nbands; i++) {
(*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
(jbyte *) jtable[i].table, JNI_ABORT);
if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
}
}
/* Release the pinned memory */
@ -2640,7 +2688,7 @@ storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
}
}
else if (mlibImP->type == MLIB_SHORT) {
return awt_setPixels(env, rasterP, mlibImP->data);
return setPixelsFormMlibImage(env, rasterP, mlibImP);
}
}
else {

View File

@ -111,8 +111,9 @@ SplashDone(Splash * splash)
int
SplashIsStillLooping(Splash * splash)
{
if (splash->currentFrame < 0)
if (splash->currentFrame < 0) {
return 0;
}
return splash->loopCount != 1 ||
splash->currentFrame + 1 < splash->frameCount;
}
@ -121,17 +122,22 @@ void
SplashUpdateScreenData(Splash * splash)
{
ImageRect srcRect, dstRect;
if (splash->currentFrame < 0) {
return;
}
initRect(&srcRect, 0, 0, splash->width, splash->height, 1,
splash->width * sizeof(rgbquad_t),
splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat);
if (splash->screenData)
if (splash->screenData) {
free(splash->screenData);
}
splash->screenStride = splash->width * splash->screenFormat.depthBytes;
if (splash->byteAlignment > 1)
if (splash->byteAlignment > 1) {
splash->screenStride =
(splash->screenStride + splash->byteAlignment - 1) &
~(splash->byteAlignment - 1);
}
splash->screenData = malloc(splash->height * splash->screenStride);
initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
splash->screenStride, splash->screenData, &splash->screenFormat);
@ -146,16 +152,19 @@ SplashUpdateScreenData(Splash * splash)
void
SplashNextFrame(Splash * splash)
{
if (splash->currentFrame < 0)
if (splash->currentFrame < 0) {
return;
}
do {
if (!SplashIsStillLooping(splash))
if (!SplashIsStillLooping(splash)) {
return;
}
splash->time += splash->frames[splash->currentFrame].delay;
if (++splash->currentFrame >= splash->frameCount) {
splash->currentFrame = 0;
if (splash->loopCount > 0)
if (splash->loopCount > 0) {
splash->loopCount--;
}
}
} while (splash->time + splash->frames[splash->currentFrame].delay -
SplashTime() <= 0);
@ -183,8 +192,9 @@ BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out)
pSrc += pSrcRect->depthBytes;
++i;
}
if (i >= pSrcRect->numSamples)
if (i >= pSrcRect->numSamples) {
break;
}
i0 = i;
while (i < pSrcRect->numSamples &&
getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) {

View File

@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate), success)) {
glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
}

View File

@ -37,55 +37,54 @@
U_NAMESPACE_BEGIN
void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const
void AnchorTable::getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{
switch(SWAPW(anchorFormat)) {
switch(SWAPW(anchorFormat)) {
case 1:
{
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
f1->getAnchor(fontInstance, anchor);
LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
break;
}
case 2:
{
const Format2AnchorTable *f2 = (const Format2AnchorTable *) this;
f2->getAnchor(glyphID, fontInstance, anchor);
LEReferenceTo<Format2AnchorTable> f2(base, success);
f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
break;
}
case 3:
{
const Format3AnchorTable *f3 = (const Format3AnchorTable *) this;
f3->getAnchor(fontInstance, anchor);
LEReferenceTo<Format3AnchorTable> f3(base, success);
f3->getAnchor(f3, fontInstance, anchor, success);
break;
}
default:
{
// unknown format: just use x, y coordinate, like format 1...
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
f1->getAnchor(fontInstance, anchor);
LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
break;
}
}
}
void Format1AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
void Format1AnchorTable::getAnchor(const LEReferenceTo<Format1AnchorTable>& base, const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const
{
le_int16 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate);
LEPoint pixels;
fontInstance->transformFunits(x, y, pixels);
fontInstance->pixelsToUnits(pixels, anchor);
}
void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const
void Format2AnchorTable::getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor
, LEErrorCode &success) const
{
LEPoint point;
@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font
fontInstance->pixelsToUnits(point, anchor);
}
void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
void Format3AnchorTable::getAnchor(const LEReferenceTo<Format3AnchorTable> &base, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{
le_int16 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate);
@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &
fontInstance->transformFunits(x, y, pixels);
if (dtxOffset != 0) {
const DeviceTable *dtx = (const DeviceTable *) ((char *) this + dtxOffset);
le_int16 adjx = dtx->getAdjustment((le_int16) fontInstance->getXPixelsPerEm());
LEReferenceTo<DeviceTable> dt(base, success, dtxOffset);
le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
pixels.fX += adjx;
}
if (dtyOffset != 0) {
const DeviceTable *dty = (const DeviceTable *) ((char *) this + dtyOffset);
le_int16 adjy = dty->getAdjustment((le_int16) fontInstance->getYPixelsPerEm());
LEReferenceTo<DeviceTable> dt(base, success, dtyOffset);
le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
pixels.fY += adjy;
}

View File

@ -49,20 +49,23 @@ struct AnchorTable
le_int16 xCoordinate;
le_int16 yCoordinate;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const;
void getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
};
struct Format1AnchorTable : AnchorTable
{
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
void getAnchor(const LEReferenceTo<Format1AnchorTable>& base,
const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const;
};
struct Format2AnchorTable : AnchorTable
{
le_uint16 anchorPoint;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const;
void getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
};
struct Format3AnchorTable : AnchorTable
@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable
Offset xDeviceTableOffset;
Offset yDeviceTableOffset;
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
void getAnchor(const LEReferenceTo<Format3AnchorTable>& base,
const LEFontInstance *fontInstance, LEPoint &anchor,
LEErrorCode &success) const;
};
U_NAMESPACE_END

View File

@ -51,7 +51,7 @@
U_NAMESPACE_BEGIN
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const
{
return fFontInstance->canDisplay((LEUnicode) glyph);
}
@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success);
} else {
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,
CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
@ -157,9 +159,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
/* OpenTypeLayoutEngine will allocate a substitution filter */
fGSUBTable.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);
fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
/* OpenTypeLayoutEngine will allocate a substitution filter */
}
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()

View File

@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{
LEErrorCode success = LE_NO_ERROR;
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
const LEReferenceTo<ClassDefinitionTable> joiningTypes(LETableReference::kStaticData,
(const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
ArabicShaping::shapingTypeTableLen);
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);

View File

@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{
LEErrorCode success = LE_NO_ERROR;
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);

View File

@ -43,6 +43,8 @@ class LEFontInstance;
* This filter is used by character-based GSUB processors. It
* accepts only those characters which the given font can display.
*
* Note: Implementation is in ArabicLayoutEngine.cpp
*
* @internal
*/
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
@ -97,7 +99,7 @@ public:
*
* @internal
*/
le_bool accept(LEGlyphID glyph) const;
le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
};
U_NAMESPACE_END

View File

@ -49,6 +49,7 @@ struct ClassDefinitionTable
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
#if LE_ENABLE_RAW
le_int32 getGlyphClass(LEGlyphID glyphID) const {
LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR;
@ -60,6 +61,7 @@ struct ClassDefinitionTable
LEErrorCode ignored = LE_NO_ERROR;
return hasGlyphClass(base,glyphClass,ignored);
}
#endif
};
struct ClassDefFormat1Table : ClassDefinitionTable

View File

@ -154,6 +154,7 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount);
if (LE_FAILURE(success)) { return newGlyph; }
newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success));
}
}

View File

@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
*/
void ContextualSubstitutionBase::applySubstitutionLookups(
const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray,
const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
@ -60,10 +60,11 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
}
GlyphIterator tempIterator(*glyphIterator);
const SubstitutionLookupRecord *substLookupRecordArrayPtr = substLookupRecordArray.getAlias(); // OK to dereference, range checked against substCount below.
for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex);
le_uint16 sequenceIndex = SWAPW(substLookupRecordArrayPtr[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArrayPtr[subst].lookupListIndex);
tempIterator.setCurrStreamPosition(position);
tempIterator.next(sequenceIndex);
@ -72,7 +73,7 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
}
}
le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, le_uint16 glyphCount,
le_bool ContextualSubstitutionBase::matchGlyphIDs(const LEReferenceToArrayOf<TTGlyphID>& glyphArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, le_bool backtrack)
{
le_int32 direction = 1;
@ -101,11 +102,16 @@ le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, l
return TRUE;
}
le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable,
le_bool backtrack)
le_bool ContextualSubstitutionBase::matchGlyphClasses(
const LEReferenceToArrayOf<le_uint16> &classArray,
le_uint16 glyphCount,
GlyphIterator *glyphIterator,
const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable,
LEErrorCode &success,
le_bool backtrack)
{
if (LE_FAILURE(success)) { return FALSE; }
le_int32 direction = 1;
le_int32 match = 0;
@ -120,7 +126,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 glyphClass = classDefinitionTable->getGlyphClass(glyph);
le_int32 glyphClass = classDefinitionTable->getGlyphClass(classDefinitionTable, glyph, success);
le_int32 matchClass = SWAPW(classArray[match]);
if (glyphClass != matchClass) {
@ -128,7 +134,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
// in the class array which aren't in the class definition
// table. If we're looking for such a class, pretend that
// we found it.
if (classDefinitionTable->hasGlyphClass(matchClass)) {
if (classDefinitionTable->hasGlyphClass(classDefinitionTable, matchClass, success)) {
return FALSE;
}
}
@ -140,8 +146,8 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
return TRUE;
}
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack)
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference &offsetBase, LEErrorCode &success, le_bool backtrack)
{
le_int32 direction = 1;
le_int32 glyph = 0;
@ -153,13 +159,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
while (glyphCount > 0) {
Offset coverageTableOffset = SWAPW(coverageTableOffsetArray[glyph]);
const CoverageTable *coverageTable = (const CoverageTable *) (offsetBase + coverageTableOffset);
LEReferenceTo<CoverageTable> coverageTable(offsetBase, success, coverageTableOffset);
if (! glyphIterator->next()) {
if (LE_FAILURE(success) || ! glyphIterator->next()) {
return FALSE;
}
if (coverageTable->getGlyphCoverage((LEGlyphID) glyphIterator->getCurrGlyphID()) < 0) {
if (coverageTable->getGlyphCoverage(coverageTable,
(LEGlyphID) glyphIterator->getCurrGlyphID(),
success) < 0) {
return FALSE;
}
@ -170,7 +178,7 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
return TRUE;
}
le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ContextualSubstitutionSubtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
@ -186,20 +194,29 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
case 1:
{
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ContextualSubstitutionFormat1Subtable> subtable(base, success, (const ContextualSubstitutionFormat1Subtable *) this);
if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 2:
{
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ContextualSubstitutionFormat2Subtable> subtable(base, success, (const ContextualSubstitutionFormat2Subtable *) this);
if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 3:
{
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ContextualSubstitutionFormat3Subtable> subtable(base, success, (const ContextualSubstitutionFormat3Subtable *) this);
if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
default:
@ -207,7 +224,7 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
}
}
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
@ -227,22 +244,23 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
if (coverageIndex < srSetCount) {
Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]);
const SubRuleSetTable *subRuleSetTable =
(const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset);
LEReferenceTo<SubRuleSetTable>
subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset));
le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) {
Offset subRuleTableOffset =
SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]);
const SubRuleTable *subRuleTable =
(const SubRuleTable *) ((char *) subRuleSetTable + subRuleTableOffset);
LEReferenceTo<SubRuleTable>
subRuleTable(subRuleSetTable, success, subRuleTableOffset);
le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1;
le_uint16 substCount = SWAPW(subRuleTable->substCount);
if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount];
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2);
if (LE_FAILURE(success)) { return 0; }
if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
@ -259,10 +277,11 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
return 0;
}
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
@ -275,29 +294,34 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
}
if (coverageIndex >= 0) {
const ClassDefinitionTable *classDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset));
LEReferenceTo<ClassDefinitionTable> classDefinitionTable(base, success,
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)));
le_uint16 scSetCount = SWAPW(subClassSetCount);
le_int32 setClass = classDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
le_int32 setClass = classDefinitionTable->getGlyphClass(classDefinitionTable,
glyphIterator->getCurrGlyphID(),
success);
if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) {
Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]);
const SubClassSetTable *subClassSetTable =
(const SubClassSetTable *) ((char *) this + subClassSetTableOffset);
LEReferenceTo<SubClassSetTable>
subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset));
le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) {
Offset subClassRuleTableOffset =
SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]);
const SubClassRuleTable *subClassRuleTable =
(const SubClassRuleTable *) ((char *) subClassSetTable + subClassRuleTableOffset);
LEReferenceTo<SubClassRuleTable>
subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset);
le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1;
le_uint16 substCount = SWAPW(subClassRuleTable->substCount);
if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount];
LEReferenceToArrayOf<le_uint16> classArray(base, success, subClassRuleTable->classArray, matchCount+1);
if (LE_FAILURE(success)) { return 0; }
if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
@ -314,7 +338,8 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
return 0;
}
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LETableReference &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success)const
@ -333,9 +358,13 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
// that matched when we're done.
glyphIterator->prev();
if (ContextualSubstitutionBase::matchGlyphCoverages(coverageTableOffsetArray, gCount, glyphIterator, (const char *) this)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount];
LEReferenceToArrayOf<Offset> covTableOffsetArray(base, success, coverageTableOffsetArray, gCount);
if( LE_FAILURE(success) ) { return 0; }
if (ContextualSubstitutionBase::matchGlyphCoverages(covTableOffsetArray, gCount, glyphIterator, base, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount], subCount);
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
@ -347,7 +376,8 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
return 0;
}
le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionSubtable::process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
@ -363,20 +393,23 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
case 1:
{
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ChainingContextualSubstitutionFormat1Subtable> subtable(base, success, (ChainingContextualSubstitutionFormat1Subtable *) this);
if(LE_FAILURE(success)) return 0;
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 2:
{
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ChainingContextualSubstitutionFormat2Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat2Subtable *) this);
if( LE_FAILURE(success) ) { return 0; }
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 3:
{
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ChainingContextualSubstitutionFormat3Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat3Subtable *) this);
if( LE_FAILURE(success) ) { return 0; }
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
default:
@ -390,7 +423,7 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
// emptyFeatureList matches an le_uint32 or an le_uint16...
static const FeatureMask emptyFeatureList = 0x00000000UL;
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
@ -410,8 +443,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
if (coverageIndex < srSetCount) {
Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]);
const ChainSubRuleSetTable *chainSubRuleSetTable =
(const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset);
LEReferenceTo<ChainSubRuleSetTable>
chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset));
le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
@ -419,13 +452,19 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) {
Offset chainSubRuleTableOffset =
SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]);
const ChainSubRuleTable *chainSubRuleTable =
(const ChainSubRuleTable *) ((char *) chainSubRuleSetTable + chainSubRuleTableOffset);
LEReferenceTo<ChainSubRuleTable>
chainSubRuleTable = LEReferenceTo<ChainSubRuleTable>(chainSubRuleSetTable, success, chainSubRuleTableOffset);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount);
LEReferenceToArrayOf<TTGlyphID> backtrackGlyphArray(base, success, chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 inputGlyphCount = (le_uint16) SWAPW(chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount]) - 1;
const TTGlyphID *inputGlyphArray = &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1];
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1], inputGlyphCount+2);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputGlyphArray[inputGlyphCount]);
const TTGlyphID *lookaheadGlyphArray = &inputGlyphArray[inputGlyphCount + 1];
LEReferenceToArrayOf<TTGlyphID> lookaheadGlyphArray(base, success, inputGlyphArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]);
tempIterator.setCurrStreamPosition(position);
@ -435,7 +474,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
}
tempIterator.prev();
if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
if (! matchGlyphIDs(backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
continue;
}
@ -446,8 +486,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
}
if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1];
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadGlyphArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
@ -464,7 +504,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
return 0;
}
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
@ -480,19 +520,21 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
}
if (coverageIndex >= 0) {
const ClassDefinitionTable *backtrackClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset));
const ClassDefinitionTable *inputClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset));
const ClassDefinitionTable *lookaheadClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset));
LEReferenceTo<ClassDefinitionTable>
backtrackClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset)));
LEReferenceTo<ClassDefinitionTable>
inputClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset)));
LEReferenceTo<ClassDefinitionTable>
lookaheadClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset)));
le_uint16 scSetCount = SWAPW(chainSubClassSetCount);
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable,
glyphIterator->getCurrGlyphID(),
success);
if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) {
Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]);
const ChainSubClassSetTable *chainSubClassSetTable =
(const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset);
LEReferenceTo<ChainSubClassSetTable>
chainSubClassSetTable(base, success, (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset));
le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
@ -500,13 +542,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) {
Offset chainSubClassRuleTableOffset =
SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]);
const ChainSubClassRuleTable *chainSubClassRuleTable =
(const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset);
LEReferenceTo<ChainSubClassRuleTable>
chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset);
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1];
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]);
const le_uint16 *lookaheadClassArray = &inputClassArray[inputGlyphCount + 1];
LEReferenceToArrayOf<le_uint16> inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success));
LEReferenceToArrayOf<le_uint16> lookaheadClassArray(base, success, inputClassArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2); // +2 for the substCount
if( LE_FAILURE(success) ) { return 0; }
le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]);
@ -517,21 +561,23 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
}
tempIterator.prev();
if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount,
&tempIterator, backtrackClassDefinitionTable, TRUE)) {
LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
if( LE_FAILURE(success) ) { return 0; }
if (! matchGlyphClasses(backtrackClassArray, backtrackGlyphCount,
&tempIterator, backtrackClassDefinitionTable, success, TRUE)) {
continue;
}
tempIterator.setCurrStreamPosition(position);
tempIterator.next(inputGlyphCount);
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable)) {
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable, success)) {
continue;
}
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1];
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount);
if (LE_FAILURE(success)) { return 0; }
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount + 1;
@ -547,7 +593,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
return 0;
}
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode & success) const
@ -558,9 +604,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1];
LEReferenceToArrayOf<Offset> inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset
if (LE_FAILURE(success)) { return 0; }
const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]);
const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1];
if( LE_FAILURE(success)) { return 0; }
LEReferenceToArrayOf<Offset> lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]);
le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
@ -571,14 +622,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
tempIterator.prev();
if (! ContextualSubstitutionBase::matchGlyphCoverages(backtrackCoverageTableOffsetArray,
backtrkGlyphCount, &tempIterator, (const char *) this, TRUE)) {
backtrkGlyphCount, &tempIterator, base, success, TRUE)) {
return 0;
}
tempIterator.setCurrStreamPosition(position);
tempIterator.next(inputGlyphCount - 1);
if (! ContextualSubstitutionBase::matchGlyphCoverages(lookaheadCoverageTableOffsetArray,
lookaheadGlyphCount, &tempIterator, (const char *) this)) {
lookaheadGlyphCount, &tempIterator, base, success)) {
return 0;
}
@ -589,9 +640,10 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
glyphIterator->prev();
if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray,
inputGlyphCount, glyphIterator, (const char *) this)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1];
inputGlyphCount, glyphIterator, base, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success,
(const SubstitutionLookupRecord *) lookaheadCoverageTableOffsetArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);

View File

@ -56,20 +56,32 @@ struct SubstitutionLookupRecord
struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
{
static le_bool matchGlyphIDs(
const TTGlyphID *glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const LEReferenceToArrayOf<TTGlyphID> &glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
le_bool backtrack = FALSE);
static le_bool matchGlyphClasses(
const le_uint16 *classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable, le_bool backtrack = FALSE);
const LEReferenceToArrayOf<le_uint16> &classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable, LEErrorCode &success, le_bool backtrack = FALSE);
static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack = FALSE);
const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE);
/**
* little shim to wrap the Offset array in range checking
* @private
*/
static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE) {
LEReferenceToArrayOf<Offset> ref(offsetBase, success, coverageTableOffsetArray, glyphCount);
if( LE_FAILURE(success) ) { return FALSE; }
return matchGlyphCoverages(ref, glyphCount, glyphIterator, offsetBase, success, backtrack);
}
static void applySubstitutionLookups(
const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray,
const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
{
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint16 subRuleSetCount;
Offset subRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint16 subClassSetCount;
Offset subClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable
Offset coverageTableOffsetArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint16 chainSubRuleSetCount;
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint16 chainSubClassSetCount;
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
//le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)

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