提交 d2a73c79 编写于 作者: L lana

Merge

...@@ -274,11 +274,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx) ...@@ -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/SctpMultiChannelImpl.java \
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.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 endif
# The security classes should not end up in the classes directory as that will prevent them # 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: ...@@ -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
########################################################################################## ##########################################################################################
......
...@@ -693,13 +693,6 @@ $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar: $(JDK_OUTPUTDIR)/demo/nio/zipfs/zipfs.jar ...@@ -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 # 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 # 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. # done here so that clean targets can be simple and accurate.
......
...@@ -85,11 +85,6 @@ GENSRC += $(GENSRC_CLDR) ...@@ -85,11 +85,6 @@ GENSRC += $(GENSRC_CLDR)
include gensrc/GensrcSwing.gmk include gensrc/GensrcSwing.gmk
GENSRC += $(GENSRC_SWING_BEANINFO) $(GENSRC_SWING_NIMBUS) GENSRC += $(GENSRC_SWING_BEANINFO) $(GENSRC_SWING_NIMBUS)
ifeq ($(OPENJDK_TARGET_OS), macosx)
include gensrc/GensrcJObjC.gmk
GENSRC += $(GENSRC_JOBJC)
endif
$(GENSRC): $(BUILD_TOOLS) $(GENSRC): $(BUILD_TOOLS)
all: $(GENSRC) all: $(GENSRC)
......
...@@ -303,14 +303,13 @@ $(JDK_IMAGE_DIR)/jre/lib/applet: ...@@ -303,14 +303,13 @@ $(JDK_IMAGE_DIR)/jre/lib/applet:
$(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(MKDIR) -p $@ $(MKDIR) -p $@
# In the old build, JObjC.jar is not part of the meta-index
$(JRE_IMAGE_DIR)/lib/meta-index: $(JRE_LIB_TARGETS) $(JRE_IMAGE_DIR)/lib/meta-index: $(JRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(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) $(JDK_IMAGE_DIR)/jre/lib/meta-index: $(JDKJRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(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) $(JRE_IMAGE_DIR)/lib/ext/meta-index: $(JRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
...@@ -326,6 +325,7 @@ $(JDK_IMAGE_DIR)/jre/lib/ext/meta-index: $(JDKJRE_LIB_TARGETS) ...@@ -326,6 +325,7 @@ $(JDK_IMAGE_DIR)/jre/lib/ext/meta-index: $(JDKJRE_LIB_TARGETS)
ifneq ($(OPENJDK_TARGET_OS), windows) ifneq ($(OPENJDK_TARGET_OS), windows)
JRE_MAN_PAGES := \ JRE_MAN_PAGES := \
java.1 \ java.1 \
jjs.1 \
keytool.1 \ keytool.1 \
orbd.1 \ orbd.1 \
pack200.1 \ pack200.1 \
...@@ -356,6 +356,7 @@ ifneq ($(OPENJDK_TARGET_OS), windows) ...@@ -356,6 +356,7 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
jconsole.1 \ jconsole.1 \
jcmd.1 \ jcmd.1 \
jdb.1 \ jdb.1 \
jdeps.1 \
jhat.1 \ jhat.1 \
jinfo.1 \ jinfo.1 \
jmap.1 \ jmap.1 \
...@@ -374,7 +375,10 @@ ifneq ($(OPENJDK_TARGET_OS), windows) ...@@ -374,7 +375,10 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
xjc.1 xjc.1
ifndef OPENJDK ifndef OPENJDK
JDK_MAN_PAGES += jvisualvm.1 JDK_MAN_PAGES += \
jvisualvm.1 \
jmc.1 \
#
endif endif
# This variable is potentially overridden in the closed makefile. # This variable is potentially overridden in the closed makefile.
...@@ -387,15 +391,13 @@ ifneq ($(OPENJDK_TARGET_OS), windows) ...@@ -387,15 +391,13 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
ifeq ($(OPENJDK_TARGET_OS), solaris) ifeq ($(OPENJDK_TARGET_OS), solaris)
MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/solaris/doc MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/solaris/doc
MAN1_SUBDIR := sun/man/man1 MAN1_SUBDIR := sun/man/man1
JDK_MAN_PAGES := $(filter-out jmc.1, $(JDK_MAN_PAGES))
endif endif
ifeq ($(OPENJDK_TARGET_OS), macosx) ifeq ($(OPENJDK_TARGET_OS), macosx)
MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/bsd/doc MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/bsd/doc
MAN1_SUBDIR := man MAN1_SUBDIR := man
JDK_MAN_PAGES := $(filter-out jcmd.1, $(JDK_MAN_PAGES))
JDK_MAN_PAGES := $(filter-out jvisualvm.1, $(JDK_MAN_PAGES))
endif endif
$(JRE_IMAGE_DIR)/man/man1/%: $(MAN_SRC_DIR)/$(MAN1_SUBDIR)/% $(JRE_IMAGE_DIR)/man/man1/%: $(MAN_SRC_DIR)/$(MAN1_SUBDIR)/%
$(ECHO) $(LOG_INFO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(ECHO) $(LOG_INFO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(install-file) $(install-file)
......
...@@ -105,10 +105,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows) ...@@ -105,10 +105,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar
endif endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
endif
ifeq ($(PROFILE), profile_1) ifeq ($(PROFILE), profile_1)
PROFILE_JARS := $(PROFILE_1_JARS) PROFILE_JARS := $(PROFILE_1_JARS)
else ifeq ($(PROFILE), profile_2) else ifeq ($(PROFILE), profile_2)
......
...@@ -77,7 +77,7 @@ $(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) \ ...@@ -77,7 +77,7 @@ $(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) \
$(ECHO) Generating beaninfo $(ECHO) Generating beaninfo
$(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing $(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing
$(JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) \ $(JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) \
-sourcepath "$(JDK_TOPDIR)/src/share/classes$(PATH_SEP)$(JDK_OUTPUTDIR)/gensrc" \ -sourcepath "$(JDK_TOPDIR)/src/share/classes$(PATH_SEP)$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes$(PATH_SEP)$(JDK_OUTPUTDIR)/gensrc" \
-doclet build.tools.swingbeaninfo.GenDocletBeanInfo \ -doclet build.tools.swingbeaninfo.GenDocletBeanInfo \
-x $(SWINGBEAN_DEBUG_FLAG) -d $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing \ -x $(SWINGBEAN_DEBUG_FLAG) -d $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing \
-t $(DOCLET_DATA_DIR)/SwingBeanInfo.template -docletpath $(JDK_OUTPUTDIR)/btclasses \ -t $(DOCLET_DATA_DIR)/SwingBeanInfo.template -docletpath $(JDK_OUTPUTDIR)/btclasses \
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/share/native/java/net \ 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/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/dns \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/spi $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/spi
......
...@@ -136,64 +136,6 @@ endif ...@@ -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 ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows) ifeq ($(OPENJDK_TARGET_OS), windows)
......
...@@ -86,6 +86,8 @@ SUNWprivate_1.1 { ...@@ -86,6 +86,8 @@ SUNWprivate_1.1 {
Java_java_net_PlainSocketImpl_socketConnect; Java_java_net_PlainSocketImpl_socketConnect;
Java_java_net_PlainDatagramSocketImpl_getTimeToLive; Java_java_net_PlainDatagramSocketImpl_getTimeToLive;
Java_java_net_PlainDatagramSocketImpl_setTimeToLive; 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_localDomain0;
Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0; Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0;
Java_sun_net_sdp_SdpSupport_convert0; Java_sun_net_sdp_SdpSupport_convert0;
......
." Copyright (c) 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
." under the terms of the GNU General Public License version 2 only, as
." published by the Free Software Foundation.
."
." This code is distributed in the hope that it will be useful, but WITHOUT
." ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
." FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
." version 2 for more details (a copy is included in the LICENSE file that
." accompanied this code).
."
." You should have received a copy of the GNU General Public License version
." 2 along with this work; if not, write to the Free Software Foundation,
." Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
."
." Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
." or visit www.oracle.com if you need additional information or have any
." questions.
."
.TH jcmd 1 "07 May 2011"
.LP
." Copyright (c) 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
." under the terms of the GNU General Public License version 2 only, as
." published by the Free Software Foundation.
."
." This code is distributed in the hope that it will be useful, but WITHOUT
." ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
." FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
." version 2 for more details (a copy is included in the LICENSE file that
." accompanied this code).
."
." You should have received a copy of the GNU General Public License version
." 2 along with this work; if not, write to the Free Software Foundation,
." Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
."
." Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
." or visit www.oracle.com if you need additional information or have any
." questions.
."
.TH jdeps 1 "07 May 2011"
.LP
." Copyright (c) 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
." under the terms of the GNU General Public License version 2 only, as
." published by the Free Software Foundation.
."
." This code is distributed in the hope that it will be useful, but WITHOUT
." ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
." FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
." version 2 for more details (a copy is included in the LICENSE file that
." accompanied this code).
."
." You should have received a copy of the GNU General Public License version
." 2 along with this work; if not, write to the Free Software Foundation,
." Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
."
." Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
." or visit www.oracle.com if you need additional information or have any
." questions.
."
.TH jjs 1 "07 May 2011"
.LP
'\" t
.\"
.\" Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved.
.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
.\"
.\" This code is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License version 2 only, as
.\" published by the Free Software Foundation.
.\"
.\" This code is distributed in the hope that it will be useful, but WITHOUT
.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
.\" version 2 for more details (a copy is included in the LICENSE file that
.\" accompanied this code).
.\"
.\" You should have received a copy of the GNU General Public License version
.\" 2 along with this work; if not, write to the Free Software Foundation,
.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
.\" or visit www.oracle.com if you need additional information or have any
.\" questions.
.\"
.\"
.\"
'\" t
.\"
.\" Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved.
.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
.\"
.\" This code is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License version 2 only, as
.\" published by the Free Software Foundation.
.\"
.\" This code is distributed in the hope that it will be useful, but WITHOUT
.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
.\" version 2 for more details (a copy is included in the LICENSE file that
.\" accompanied this code).
.\"
.\" You should have received a copy of the GNU General Public License version
.\" 2 along with this work; if not, write to the Free Software Foundation,
.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
.\" or visit www.oracle.com if you need additional information or have any
.\" questions.
.\"
.\"
'\" t
.\"
.\" Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved.
.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
.\"
.\" This code is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License version 2 only, as
.\" published by the Free Software Foundation.
.\"
.\" This code is distributed in the hope that it will be useful, but WITHOUT
.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
.\" version 2 for more details (a copy is included in the LICENSE file that
.\" accompanied this code).
.\"
.\" You should have received a copy of the GNU General Public License version
.\" 2 along with this work; if not, write to the Free Software Foundation,
.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
.\" or visit www.oracle.com if you need additional information or have any
.\" questions.
.\"
.\"
...@@ -290,8 +290,8 @@ SplashEventLoop(Splash * splash) { ...@@ -290,8 +290,8 @@ SplashEventLoop(Splash * splash) {
SplashUnlock(splash); SplashUnlock(splash);
rc = poll(pfd, 1, timeout); rc = poll(pfd, 1, timeout);
SplashLock(splash); SplashLock(splash);
if (splash->isVisible>0 && SplashTime() >= splash->time + if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
splash->frames[splash->currentFrame].delay) { SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
SplashNextFrame(splash); SplashNextFrame(splash);
SplashRedrawWindow(splash); SplashRedrawWindow(splash);
} }
......
...@@ -29,6 +29,7 @@ import com.sun.beans.finder.ClassFinder; ...@@ -29,6 +29,7 @@ import com.sun.beans.finder.ClassFinder;
import java.beans.ExceptionListener; import java.beans.ExceptionListener;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
...@@ -245,6 +246,14 @@ public final class DocumentHandler extends DefaultHandler { ...@@ -245,6 +246,14 @@ public final class DocumentHandler extends DefaultHandler {
this.objects.add(object); 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. * Prepares this handler to read objects from XML document.
*/ */
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -72,13 +72,17 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi { ...@@ -72,13 +72,17 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
throw new IllegalStateException( throw new IllegalStateException(
"TlsRsaPremasterSecretGenerator must be initialized"); "TlsRsaPremasterSecretGenerator must be initialized");
} }
byte[] b = spec.getEncodedSecret();
if (b == null) {
if (random == null) { if (random == null) {
random = new SecureRandom(); random = new SecureRandom();
} }
byte[] b = new byte[48]; b = new byte[48];
random.nextBytes(b); random.nextBytes(b);
b[0] = (byte)spec.getMajorVersion(); b[0] = (byte)spec.getMajorVersion();
b[1] = (byte)spec.getMinorVersion(); b[1] = (byte)spec.getMinorVersion();
}
return new SecretKeySpec(b, "TlsRsaPremasterSecret"); return new SecretKeySpec(b, "TlsRsaPremasterSecret");
} }
......
...@@ -27,17 +27,9 @@ package com.sun.jmx.snmp.agent; ...@@ -27,17 +27,9 @@ package com.sun.jmx.snmp.agent;
// java imports // java imports
// //
import com.sun.jmx.snmp.SnmpDefinitions;
import java.io.Serializable; 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.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 * Represents a node in an SNMP MIB which corresponds to a table entry
...@@ -99,7 +91,9 @@ public abstract class SnmpMibEntry extends SnmpMibNode ...@@ -99,7 +91,9 @@ public abstract class SnmpMibEntry extends SnmpMibNode
*/ */
public void validateVarId(long arc, Object userData) public void validateVarId(long arc, Object userData)
throws SnmpStatusException { throws SnmpStatusException {
if (isVariable(arc) == false) throw noSuchNameException; if (isVariable(arc) == false) {
throw new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
}
} }
/** /**
......
...@@ -108,8 +108,9 @@ public abstract class SnmpMibGroup extends SnmpMibOid ...@@ -108,8 +108,9 @@ public abstract class SnmpMibGroup extends SnmpMibOid
*/ */
public void validateVarId(long arc, Object userData) public void validateVarId(long arc, Object userData)
throws SnmpStatusException { throws SnmpStatusException {
if (isVariable(arc) == false) if (isVariable(arc) == false) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} }
...@@ -360,17 +361,20 @@ public abstract class SnmpMibGroup extends SnmpMibOid ...@@ -360,17 +361,20 @@ public abstract class SnmpMibGroup extends SnmpMibOid
validateVarId(arc, data); validateVarId(arc, data);
// The trailing .0 is missing in the OID // The trailing .0 is missing in the OID
if (depth+2 > length) if (depth+2 > length) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// There are too many arcs left in the OID (there should remain // There are too many arcs left in the OID (there should remain
// a single trailing .0) // a single trailing .0)
if (depth+2 < length) if (depth+2 < length) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// The last trailing arc is not .0 // The last trailing arc is not .0
if (oid[depth+1] != 0L) if (oid[depth+1] != 0L) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// It's one of our variable, register this node. // It's one of our variable, register this node.
handlers.add(this,depth,varbind); handlers.add(this,depth,varbind);
...@@ -389,12 +393,13 @@ public abstract class SnmpMibGroup extends SnmpMibOid ...@@ -389,12 +393,13 @@ public abstract class SnmpMibGroup extends SnmpMibOid
int length = oid.length; int length = oid.length;
SnmpMibNode node = null; SnmpMibNode node = null;
if (handlers == null) if (handlers == null) {
// This should be considered as a genErr, but we do not want to // This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw // abort the whole request, so we're going to throw
// a noSuchObject... // a noSuchObject...
// //
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData(); final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion(); final int pduVersion = handlers.getRequestPduVersion();
...@@ -430,7 +435,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid ...@@ -430,7 +435,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
depth+1,handlers, depth+1,handlers,
checker); checker);
}catch(SnmpStatusException ex) { }catch(SnmpStatusException ex) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} finally { } finally {
checker.remove(depth); checker.remove(depth);
} }
...@@ -455,7 +460,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid ...@@ -455,7 +460,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
try { try {
checker.checkCurrentOid(); checker.checkCurrentOid();
} catch(SnmpStatusException e) { } catch(SnmpStatusException e) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} finally { } finally {
checker.remove(depth,2); checker.remove(depth,2);
} }
...@@ -500,7 +505,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid ...@@ -500,7 +505,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
// The oid is not valid, we will throw an exception in order // The oid is not valid, we will throw an exception in order
// to try with the next valid identifier... // to try with the next valid identifier...
// //
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} catch (SnmpStatusException e) { } catch (SnmpStatusException e) {
// We didn't find anything at the given arc, so we're going // We didn't find anything at the given arc, so we're going
......
...@@ -155,7 +155,7 @@ public abstract class SnmpMibNode implements Serializable { ...@@ -155,7 +155,7 @@ public abstract class SnmpMibNode implements Serializable {
long[] oid, int depth, long[] oid, int depth,
SnmpRequestTree handlers) SnmpRequestTree handlers)
throws SnmpStatusException { throws SnmpStatusException {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} }
/** /**
...@@ -183,7 +183,7 @@ public abstract class SnmpMibNode implements Serializable { ...@@ -183,7 +183,7 @@ public abstract class SnmpMibNode implements Serializable {
long[] oid, int pos, int depth, long[] oid, int pos, int depth,
SnmpRequestTree handlers, AcmChecker checker) SnmpRequestTree handlers, AcmChecker checker)
throws SnmpStatusException { throws SnmpStatusException {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} }
/** /**
...@@ -346,8 +346,9 @@ public abstract class SnmpMibNode implements Serializable { ...@@ -346,8 +346,9 @@ public abstract class SnmpMibNode implements Serializable {
final int[] a = table; final int[] a = table;
final int val= (int) value; final int val= (int) value;
if (a == null) if (a == null) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
int low= 0; int low= 0;
int max= a.length; int max= a.length;
...@@ -356,11 +357,13 @@ public abstract class SnmpMibNode implements Serializable { ...@@ -356,11 +357,13 @@ public abstract class SnmpMibNode implements Serializable {
// Basic check // Basic check
// //
if (max < 1) if (max < 1) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (a[max-1] <= val) if (a[max-1] <= val) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
while (low <= max) { while (low <= max) {
elmt= a[curr]; elmt= a[curr];
...@@ -400,15 +403,4 @@ public abstract class SnmpMibNode implements Serializable { ...@@ -400,15 +403,4 @@ public abstract class SnmpMibNode implements Serializable {
* Contains the list of variable identifiers. * Contains the list of variable identifiers.
*/ */
protected int[] varList; 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);
} }
...@@ -160,12 +160,10 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable { ...@@ -160,12 +160,10 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
if (depth > length) { if (depth > length) {
// Nothing is left... the oid is not valid // Nothing is left... the oid is not valid
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (depth == length) { } else if (depth == length) {
// The oid is not complete... // The oid is not complete...
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} else { } else {
// Some children variable or subobject is being querried // Some children variable or subobject is being querried
// getChild() will raise an exception if no child is found. // getChild() will raise an exception if no child is found.
...@@ -205,12 +203,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable { ...@@ -205,12 +203,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
final int length = oid.length; final int length = oid.length;
SnmpMibNode node = null; SnmpMibNode node = null;
long[] result = null; long[] result = null;
if (handlers == null) if (handlers == null) {
// This should be considered as a genErr, but we do not want to // This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw // abort the whole request, so we're going to throw
// a noSuchObject... // a noSuchObject...
// //
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData(); final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion(); final int pduVersion = handlers.getRequestPduVersion();
...@@ -235,7 +234,7 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable { ...@@ -235,7 +234,7 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
// SnmpOid result = null; // SnmpOid result = null;
if (child == null) { if (child == null) {
// shouldn't happen // shouldn't happen
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
// validateVarId(index); // validateVarId(index);
// handlers.add(this,varbind,depth); // handlers.add(this,varbind,depth);
// result = new SnmpOid(0); // result = new SnmpOid(0);
...@@ -444,11 +443,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable { ...@@ -444,11 +443,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
// first we need to retrieve the identifier in the list of children // first we need to retrieve the identifier in the list of children
// //
final int pos= getInsertAt(id); final int pos= getInsertAt(id);
if (pos >= nbChildren) if (pos >= nbChildren) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (varList[pos] != (int) id) if (varList[pos] != (int) id) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// Access the node // Access the node
// //
...@@ -456,10 +457,11 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable { ...@@ -456,10 +457,11 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
try { try {
child = children.elementAtNonSync(pos); child = children.elementAtNonSync(pos);
} catch(ArrayIndexOutOfBoundsException e) { } 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; return child;
} }
......
...@@ -280,7 +280,7 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -280,7 +280,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
SnmpVarBind var; SnmpVarBind var;
for (Enumeration<SnmpVarBind> e= r.getElements(); e.hasMoreElements();) { for (Enumeration<SnmpVarBind> e= r.getElements(); e.hasMoreElements();) {
var = e.nextElement(); var = e.nextElement();
r.registerGetException(var,noSuchInstanceException); r.registerGetException(var,new SnmpStatusException(SnmpStatusException.noSuchInstance));
} }
} }
...@@ -1607,8 +1607,9 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -1607,8 +1607,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
protected SnmpOid getNextOid(SnmpOid oid, Object userData) protected SnmpOid getNextOid(SnmpOid oid, Object userData)
throws SnmpStatusException { throws SnmpStatusException {
if (size == 0) if (size == 0) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
final SnmpOid resOid = oid; final SnmpOid resOid = oid;
...@@ -1619,7 +1620,7 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -1619,7 +1620,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
if (last.equals(resOid)) { if (last.equals(resOid)) {
// Last element of the table ... // Last element of the table ...
// //
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} }
// First find the oid. This will allow to speed up retrieval process // First find the oid. This will allow to speed up retrieval process
...@@ -1641,12 +1642,12 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -1641,12 +1642,12 @@ public abstract class SnmpMibTable extends SnmpMibNode
// XX last = (SnmpOid) oids.elementAt(newPos); // XX last = (SnmpOid) oids.elementAt(newPos);
last = tableoids[newPos]; last = tableoids[newPos];
} catch(ArrayIndexOutOfBoundsException e) { } catch(ArrayIndexOutOfBoundsException e) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} }
} else { } else {
// We are dealing with the last element of the table .. // 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 ...@@ -1668,8 +1669,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
*/ */
protected SnmpOid getNextOid(Object userData) protected SnmpOid getNextOid(Object userData)
throws SnmpStatusException { throws SnmpStatusException {
if (size == 0) if (size == 0) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// XX return (SnmpOid) oids.firstElement(); // XX return (SnmpOid) oids.firstElement();
return tableoids[0]; return tableoids[0];
} }
...@@ -1875,10 +1877,10 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -1875,10 +1877,10 @@ public abstract class SnmpMibTable extends SnmpMibNode
// not support creation. // not support creation.
// We know that the entry does not exists if (isentry == false). // We know that the entry does not exists if (isentry == false).
if (!hasEntry) { if (!hasEntry) {
if (!handlers.isCreationAllowed()) if (!handlers.isCreationAllowed()) {
// we're not doing a set // we're not doing a set
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
else if (!isCreationEnabled()) } else if (!isCreationEnabled())
// we're doing a set but creation is disabled. // we're doing a set but creation is disabled.
throw new throw new
SnmpStatusException(SnmpStatusException.snmpRspNoAccess); SnmpStatusException(SnmpStatusException.snmpRspNoAccess);
...@@ -1922,12 +1924,13 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -1922,12 +1924,13 @@ public abstract class SnmpMibTable extends SnmpMibNode
int length = oid.length; int length = oid.length;
if (handlers == null) if (handlers == null) {
// This should be considered as a genErr, but we do not want to // This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw // abort the whole request, so we're going to throw
// a noSuchObject... // a noSuchObject...
// //
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData(); final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion(); final int pduVersion = handlers.getRequestPduVersion();
...@@ -1961,7 +1964,7 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -1961,7 +1964,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
// so we won't find the next element in this table... (any // so we won't find the next element in this table... (any
// element in this table will have a smaller OID) // element in this table will have a smaller OID)
// //
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (oid[pos] < nodeId) { } else if (oid[pos] < nodeId) {
// we must return the first leaf under the first columnar // we must return the first leaf under the first columnar
// object, so we are back to our first case where pos was // object, so we are back to our first case where pos was
...@@ -2051,8 +2054,9 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -2051,8 +2054,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// in tables can't be properly supported (all rows // in tables can't be properly supported (all rows
// must have the same holes) // must have the same holes)
// //
if (skipEntryVariable(entryoid,var,data,pduVersion)) if (skipEntryVariable(entryoid,var,data,pduVersion)) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} catch(SnmpStatusException se) { } catch(SnmpStatusException se) {
entryoid = getNextOid(data); entryoid = getNextOid(data);
var = getNextVarEntryId(entryoid,var,data,pduVersion); var = getNextVarEntryId(entryoid,var,data,pduVersion);
...@@ -2085,8 +2089,9 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -2085,8 +2089,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// So we throw the exception. // So we throw the exception.
// => will skip to next node in the MIB tree. // => 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) // So here we know both the row (entryoid) and the column (var)
// //
...@@ -2097,8 +2102,9 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -2097,8 +2102,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// for this specific entry, it is not readable for any // for this specific entry, it is not readable for any
// other entry => skip to next column. // other entry => skip to next column.
// //
if (!isReadableEntryId(entryoid,var,data)) if (!isReadableEntryId(entryoid,var,data)) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// Prepare the result and the ACM checker. // Prepare the result and the ACM checker.
// //
...@@ -2161,8 +2167,9 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -2161,8 +2167,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// No need to continue, we throw an exception. // No need to continue, we throw an exception.
// => will skip to next node in the MIB tree. // => will skip to next node in the MIB tree.
// //
if (entryoid == null || var == -1 ) if (entryoid == null || var == -1 ) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} }
} }
...@@ -2182,14 +2189,15 @@ public abstract class SnmpMibTable extends SnmpMibNode ...@@ -2182,14 +2189,15 @@ public abstract class SnmpMibTable extends SnmpMibNode
// Control the length of the oid // Control the length of the oid
// //
if (pos +2 >= length) if (pos +2 >= length) {
throw noSuchInstanceException; throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// Check that the entry identifier is specified // Check that the entry identifier is specified
// //
if (oid[pos] != nodeId) if (oid[pos] != nodeId) {
throw noSuchObjectException; throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
......
...@@ -1146,7 +1146,4 @@ class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions { ...@@ -1146,7 +1146,4 @@ class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions {
static final private String InterruptSysCallMsg = static final private String InterruptSysCallMsg =
"Interrupted system call"; "Interrupted system call";
static final private SnmpStatusException noSuchNameException =
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName) ;
} }
...@@ -56,9 +56,12 @@ public final class FactoryEnumeration { ...@@ -56,9 +56,12 @@ public final class FactoryEnumeration {
* references so as not to prevent GC of the class loader. Each * references so as not to prevent GC of the class loader. Each
* weak reference is tagged with the factory's class name so the * weak reference is tagged with the factory's class name so the
* class can be reloaded if the reference is cleared. * class can be reloaded if the reference is cleared.
*
* @param factories A non-null list * @param factories A non-null list
* @param loader The class loader of the list's contents * @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, FactoryEnumeration(List<NamedWeakReference<Object>> factories,
ClassLoader loader) { ClassLoader loader) {
...@@ -79,7 +82,8 @@ public final class FactoryEnumeration { ...@@ -79,7 +82,8 @@ public final class FactoryEnumeration {
try { try {
if (answer == null) { // reload class if weak ref cleared 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 // Instantiate Class to get factory
answer = ((Class) answer).newInstance(); answer = ((Class) answer).newInstance();
......
...@@ -53,21 +53,24 @@ import javax.naming.*; ...@@ -53,21 +53,24 @@ import javax.naming.*;
final class VersionHelper12 extends VersionHelper { final class VersionHelper12 extends VersionHelper {
private boolean getSystemPropsFailed = false; // Disallow external from creating one of these.
VersionHelper12() {
VersionHelper12() {} // Disallow external from creating one of these. }
public Class<?> loadClass(String className) throws ClassNotFoundException { public Class<?> loadClass(String className) throws ClassNotFoundException {
ClassLoader cl = getContextClassLoader(); return loadClass(className, getContextClassLoader());
return Class.forName(className, true, cl);
} }
/** /**
* 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) Class<?> loadClass(String className, ClassLoader cl)
throws ClassNotFoundException { throws ClassNotFoundException {
return Class.forName(className, true, cl); Class<?> cls = Class.forName(className, true, cl);
return cls;
} }
/** /**
...@@ -76,12 +79,12 @@ final class VersionHelper12 extends VersionHelper { ...@@ -76,12 +79,12 @@ final class VersionHelper12 extends VersionHelper {
*/ */
public Class<?> loadClass(String className, String codebase) public Class<?> loadClass(String className, String codebase)
throws ClassNotFoundException, MalformedURLException { throws ClassNotFoundException, MalformedURLException {
ClassLoader cl;
ClassLoader parent = getContextClassLoader(); 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) { String getJndiProperty(final int i) {
...@@ -99,16 +102,12 @@ final class VersionHelper12 extends VersionHelper { ...@@ -99,16 +102,12 @@ final class VersionHelper12 extends VersionHelper {
} }
String[] getJndiProperties() { String[] getJndiProperties() {
if (getSystemPropsFailed) {
return null; // after one failure, don't bother trying again
}
Properties sysProps = AccessController.doPrivileged( Properties sysProps = AccessController.doPrivileged(
new PrivilegedAction<Properties>() { new PrivilegedAction<Properties>() {
public Properties run() { public Properties run() {
try { try {
return System.getProperties(); return System.getProperties();
} catch (SecurityException e) { } catch (SecurityException e) {
getSystemPropsFailed = true;
return null; return null;
} }
} }
...@@ -173,17 +172,32 @@ final class VersionHelper12 extends VersionHelper { ...@@ -173,17 +172,32 @@ final class VersionHelper12 extends VersionHelper {
return new InputStreamEnumeration(urls); 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() { ClassLoader getContextClassLoader() {
return AccessController.doPrivileged( return AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() { new PrivilegedAction<ClassLoader>() {
public ClassLoader run() { 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 * Given an enumeration of URLs, an instance of this class represents
* an enumeration of their InputStreams. Each operation on the URL * an enumeration of their InputStreams. Each operation on the URL
......
...@@ -276,6 +276,11 @@ public abstract class SctpChannel ...@@ -276,6 +276,11 @@ public abstract class SctpChannel
* *
* @throws IOException * @throws IOException
* If some other I/O error occurs * 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) public abstract SctpChannel bind(SocketAddress local)
throws IOException; throws IOException;
......
...@@ -382,7 +382,8 @@ public abstract class Canonicalizer11 extends CanonicalizerBase { ...@@ -382,7 +382,8 @@ public abstract class Canonicalizer11 extends CanonicalizerBase {
} else if (!isVisible(xmlns)) { } else if (!isVisible(xmlns)) {
//There is a definition but the xmlns is not selected by the xpath. //There is a definition but the xmlns is not selected by the xpath.
//then xmlns="" //then xmlns=""
n = ns.addMappingAndRender(XMLNS, "", nullNode); n = ns.addMappingAndRender(
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
} }
//output the xmlns def if needed. //output the xmlns def if needed.
if (n != null) { if (n != null) {
......
...@@ -327,7 +327,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { ...@@ -327,7 +327,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase {
} else if (!isVisible(xmlns)) { } else if (!isVisible(xmlns)) {
//There is a definition but the xmlns is not selected by the xpath. //There is a definition but the xmlns is not selected by the xpath.
//then xmlns="" //then xmlns=""
n = ns.addMappingAndRender(XMLNS, "", nullNode); n = ns.addMappingAndRender(
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
} }
//output the xmlns def if needed. //output the xmlns def if needed.
if (n != null) { if (n != null) {
......
...@@ -292,7 +292,7 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { ...@@ -292,7 +292,7 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
if (xmlns != null && !isVisible(xmlns)) { if (xmlns != null && !isVisible(xmlns)) {
// There is a definition but the xmlns is not selected by the // There is a definition but the xmlns is not selected by the
// xpath. then xmlns="" // xpath. then xmlns=""
ns.addMapping(XMLNS, "", nullNode); ns.addMapping(XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
} }
String prefix = null; String prefix = null;
......
...@@ -34,8 +34,6 @@ import java.util.ListIterator; ...@@ -34,8 +34,6 @@ import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
...@@ -49,6 +47,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils; ...@@ -49,6 +47,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Attr; import org.w3c.dom.Attr;
import org.w3c.dom.Comment; import org.w3c.dom.Comment;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap; import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.ProcessingInstruction;
...@@ -64,8 +63,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -64,8 +63,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
public static final String XMLNS = "xmlns"; public static final String XMLNS = "xmlns";
protected static final AttrCompare COMPARE = new AttrCompare(); 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[] END_PI = {'?','>'};
private static final byte[] BEGIN_PI = {'<','?'}; private static final byte[] BEGIN_PI = {'<','?'};
private static final byte[] END_COMM = {'-','-','>'}; private static final byte[] END_COMM = {'-','-','>'};
...@@ -78,27 +78,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -78,27 +78,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private static final byte[] LT = {'&','l','t',';'}; private static final byte[] LT = {'&','l','t',';'};
private static final byte[] END_TAG = {'<','/'}; private static final byte[] END_TAG = {'<','/'};
private static final byte[] AMP = {'&','a','m','p',';'}; 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_BEFORE_DOCUMENT_ELEMENT = -1;
protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0; protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
protected static final int NODE_AFTER_DOCUMENT_ELEMENT = 1; 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 List<NodeFilter> nodeFilter;
private boolean includeComments; private boolean includeComments;
private Set<Node> xpathNodeSet; private Set<Node> xpathNodeSet;
/** /**
* The node to be skipped/excluded from the DOM tree * The node to be skipped/excluded from the DOM tree
* in subtree canonicalizations. * in subtree canonicalizations.
...@@ -106,6 +96,11 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -106,6 +96,11 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private Node excludeNode; private Node excludeNode;
private OutputStream writer = new ByteArrayOutputStream(); private OutputStream writer = new ByteArrayOutputStream();
/**
* The null xmlns definition.
*/
private Attr nullNode;
/** /**
* Constructor CanonicalizerBase * Constructor CanonicalizerBase
* *
...@@ -310,7 +305,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -310,7 +305,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
writer.write('>'); writer.write('>');
sibling = currentNode.getFirstChild(); sibling = currentNode.getFirstChild();
if (sibling == null) { if (sibling == null) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeStringToUtf8(name, writer); UtfHelpper.writeStringToUtf8(name, writer);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
...@@ -328,7 +323,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -328,7 +323,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
break; break;
} }
while (sibling == null && parentNode != null) { while (sibling == null && parentNode != null) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache); UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
...@@ -488,7 +483,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -488,7 +483,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (sibling == null) { if (sibling == null) {
if (currentNodeIsVisible) { if (currentNodeIsVisible) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeByte(name, writer, cache); UtfHelpper.writeByte(name, writer, cache);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
...@@ -510,7 +505,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -510,7 +505,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
} }
while (sibling == null && parentNode != null) { while (sibling == null && parentNode != null) {
if (isVisible(parentNode)) { if (isVisible(parentNode)) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache); UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
...@@ -642,7 +637,8 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -642,7 +637,8 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
Attr nsprefix; Attr nsprefix;
if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null) if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null)
&& "".equals(nsprefix.getValue())) { && "".equals(nsprefix.getValue())) {
ns.addMappingAndRender(XMLNS, "", nullNode); ns.addMappingAndRender(
XMLNS, "", getNullNode(nsprefix.getOwnerDocument()));
} }
} }
...@@ -696,7 +692,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -696,7 +692,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
) throws IOException { ) throws IOException {
writer.write(' '); writer.write(' ');
UtfHelpper.writeByte(name, writer, cache); UtfHelpper.writeByte(name, writer, cache);
writer.write(equalsStr); writer.write(EQUALS_STR.clone());
byte[] toWrite; byte[] toWrite;
final int length = value.length(); final int length = value.length();
int i = 0; int i = 0;
...@@ -706,27 +702,27 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -706,27 +702,27 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) { switch (c) {
case '&' : case '&' :
toWrite = AMP; toWrite = AMP.clone();
break; break;
case '<' : case '<' :
toWrite = LT; toWrite = LT.clone();
break; break;
case '"' : case '"' :
toWrite = QUOT; toWrite = QUOT.clone();
break; break;
case 0x09 : // '\t' case 0x09 : // '\t'
toWrite = X9; toWrite = X9.clone();
break; break;
case 0x0A : // '\n' case 0x0A : // '\n'
toWrite = XA; toWrite = XA.clone();
break; break;
case 0x0D : // '\r' case 0x0D : // '\r'
toWrite = XD; toWrite = XD.clone();
break; break;
default : default :
...@@ -756,7 +752,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -756,7 +752,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) { if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
writer.write(BEGIN_PI); writer.write(BEGIN_PI.clone());
final String target = currentPI.getTarget(); final String target = currentPI.getTarget();
int length = target.length(); int length = target.length();
...@@ -764,7 +760,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -764,7 +760,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = target.charAt(i); char c = target.charAt(i);
if (c == 0x0D) { if (c == 0x0D) {
writer.write(XD); writer.write(XD.clone());
} else { } else {
if (c < 0x80) { if (c < 0x80) {
writer.write(c); writer.write(c);
...@@ -784,14 +780,14 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -784,14 +780,14 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = data.charAt(i); char c = data.charAt(i);
if (c == 0x0D) { if (c == 0x0D) {
writer.write(XD); writer.write(XD.clone());
} else { } else {
UtfHelpper.writeCharToUtf8(c, writer); UtfHelpper.writeCharToUtf8(c, writer);
} }
} }
} }
writer.write(END_PI); writer.write(END_PI.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
...@@ -810,7 +806,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -810,7 +806,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) { if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
writer.write(BEGIN_COMM); writer.write(BEGIN_COMM.clone());
final String data = currentComment.getData(); final String data = currentComment.getData();
final int length = data.length(); final int length = data.length();
...@@ -818,7 +814,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -818,7 +814,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = data.charAt(i); char c = data.charAt(i);
if (c == 0x0D) { if (c == 0x0D) {
writer.write(XD); writer.write(XD.clone());
} else { } else {
if (c < 0x80) { if (c < 0x80) {
writer.write(c); writer.write(c);
...@@ -828,7 +824,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -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) { if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
...@@ -852,19 +848,19 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -852,19 +848,19 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) { switch (c) {
case '&' : case '&' :
toWrite = AMP; toWrite = AMP.clone();
break; break;
case '<' : case '<' :
toWrite = LT; toWrite = LT.clone();
break; break;
case '>' : case '>' :
toWrite = GT; toWrite = GT.clone();
break; break;
case 0xD : case 0xD :
toWrite = XD; toWrite = XD.clone();
break; break;
default : default :
...@@ -879,4 +875,18 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ...@@ -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;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -660,7 +660,7 @@ public class XmlReaderContentHandler extends DefaultHandler { ...@@ -660,7 +660,7 @@ public class XmlReaderContentHandler extends DefaultHandler {
//Added the handling for Class tags to take care of maps //Added the handling for Class tags to take care of maps
//Makes an entry into the map upon end of class tag //Makes an entry into the map upon end of class tag
try{ try{
typeMap.put(Key_map,Class.forName(Value_map)); typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map));
}catch(ClassNotFoundException ex) { }catch(ClassNotFoundException ex) {
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage())); throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));
......
...@@ -1114,11 +1114,8 @@ class SecurityManager { ...@@ -1114,11 +1114,8 @@ class SecurityManager {
* calling thread is not allowed to wait for a connection request on * calling thread is not allowed to wait for a connection request on
* the specified local port number. * the specified local port number.
* <p> * <p>
* If port is not 0, this method calls * This method calls <code>checkPermission</code> with the
* <code>checkPermission</code> with the
* <code>SocketPermission("localhost:"+port,"listen")</code>. * <code>SocketPermission("localhost:"+port,"listen")</code>.
* If port is zero, this method calls <code>checkPermission</code>
* with <code>SocketPermission("localhost:1024-","listen").</code>
* <p> * <p>
* If you override this method, then you should make a call to * If you override this method, then you should make a call to
* <code>super.checkListen</code> * <code>super.checkListen</code>
...@@ -1131,13 +1128,9 @@ class SecurityManager { ...@@ -1131,13 +1128,9 @@ class SecurityManager {
* @see #checkPermission(java.security.Permission) checkPermission * @see #checkPermission(java.security.Permission) checkPermission
*/ */
public void checkListen(int port) { public void checkListen(int port) {
if (port == 0) {
checkPermission(SecurityConstants.LOCAL_LISTEN_PERMISSION);
} else {
checkPermission(new SocketPermission("localhost:"+port, checkPermission(new SocketPermission("localhost:"+port,
SecurityConstants.SOCKET_LISTEN_ACTION)); SecurityConstants.SOCKET_LISTEN_ACTION));
} }
}
/** /**
* Throws a <code>SecurityException</code> if the * Throws a <code>SecurityException</code> if the
......
...@@ -638,6 +638,12 @@ class InvokerBytecodeGenerator { ...@@ -638,6 +638,12 @@ class InvokerBytecodeGenerator {
refKind = REF_invokeVirtual; refKind = REF_invokeVirtual;
} }
if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
// Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
// Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
refKind = REF_invokeInterface;
}
// push arguments // push arguments
for (int i = 0; i < name.arguments.length; i++) { for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i); emitPushArgument(name, i);
......
...@@ -272,7 +272,9 @@ class Socket implements java.io.Closeable { ...@@ -272,7 +272,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port. * {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket. * @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its * @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 * @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values, * parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive. * which is between 0 and 65535, inclusive.
...@@ -311,7 +313,9 @@ class Socket implements java.io.Closeable { ...@@ -311,7 +313,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port. * {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket. * @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its * @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 * @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values, * parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive. * which is between 0 and 65535, inclusive.
...@@ -609,6 +613,9 @@ class Socket implements java.io.Closeable { ...@@ -609,6 +613,9 @@ class Socket implements java.io.Closeable {
* is already bound. * is already bound.
* @throws IllegalArgumentException if bindpoint is a * @throws IllegalArgumentException if bindpoint is a
* SocketAddress subclass not supported by this socket * 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 * @since 1.4
* @see #isBound * @see #isBound
...@@ -630,6 +637,10 @@ class Socket implements java.io.Closeable { ...@@ -630,6 +637,10 @@ class Socket implements java.io.Closeable {
InetAddress addr = epoint.getAddress(); InetAddress addr = epoint.getAddress();
int port = epoint.getPort(); int port = epoint.getPort();
checkAddress (addr, "bind"); checkAddress (addr, "bind");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkListen(port);
}
getImpl().bind (addr, port); getImpl().bind (addr, port);
bound = true; bound = true;
} }
......
...@@ -34,6 +34,9 @@ import java.util.StringTokenizer; ...@@ -34,6 +34,9 @@ import java.util.StringTokenizer;
import java.net.InetAddress; import java.net.InetAddress;
import java.security.Permission; import java.security.Permission;
import java.security.PermissionCollection; import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.Security;
import java.io.Serializable; import java.io.Serializable;
import java.io.ObjectStreamField; import java.io.ObjectStreamField;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
...@@ -41,6 +44,7 @@ import java.io.ObjectInputStream; ...@@ -41,6 +44,7 @@ import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import sun.net.util.IPAddressUtil; import sun.net.util.IPAddressUtil;
import sun.net.RegisteredDomain; import sun.net.RegisteredDomain;
import sun.net.PortConfig;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.security.util.Debug; import sun.security.util.Debug;
...@@ -89,6 +93,9 @@ 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 * form "N-", where <i>N</i> is a port number, signifies all ports
* numbered <i>N</i> and above, while a specification of the * numbered <i>N</i> and above, while a specification of the
* form "-N" indicates all ports numbered <i>N</i> and below. * 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> * <p>
* The possible ways to connect to the host are * The possible ways to connect to the host are
* <pre> * <pre>
...@@ -97,7 +104,8 @@ import sun.security.util.Debug; ...@@ -97,7 +104,8 @@ import sun.security.util.Debug;
* listen * listen
* resolve * resolve
* </pre> * </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 "resolve" action is implied when any of the other actions are present.
* The action "resolve" refers to host/ip name service lookups. * The action "resolve" refers to host/ip name service lookups.
* <P> * <P>
...@@ -176,6 +184,7 @@ public final class SocketPermission extends Permission ...@@ -176,6 +184,7 @@ public final class SocketPermission extends Permission
private static final int PORT_MIN = 0; private static final int PORT_MIN = 0;
private static final int PORT_MAX = 65535; private static final int PORT_MAX = 65535;
private static final int PRIV_PORT_MAX = 1023; private static final int PRIV_PORT_MAX = 1023;
private static final int DEF_EPH_LOW = 49152;
// the actions mask // the actions mask
private transient int mask; private transient int mask;
...@@ -226,6 +235,14 @@ public final class SocketPermission extends Permission ...@@ -226,6 +235,14 @@ public final class SocketPermission extends Permission
private static Debug debug = null; private static Debug debug = null;
private static boolean debugInit = false; 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 { static {
Boolean tmp = java.security.AccessController.doPrivileged( Boolean tmp = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction("sun.net.trustNameService")); new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
...@@ -359,6 +376,14 @@ public final class SocketPermission extends Permission ...@@ -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 * Initialize the SocketPermission object. We don't do any DNS lookups
* as this point, instead we hold off until the implies method is * as this point, instead we hold off until the implies method is
...@@ -850,12 +875,23 @@ public final class SocketPermission extends Permission ...@@ -850,12 +875,23 @@ public final class SocketPermission extends Permission
int i,j; int i,j;
if ((that.mask & RESOLVE) != that.mask) { if ((that.mask & RESOLVE) != that.mask) {
// check port range
// check simple port range
if ((that.portrange[0] < this.portrange[0]) || if ((that.portrange[0] < this.portrange[0]) ||
(that.portrange[1] > this.portrange[1])) { (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; return false;
} }
} }
}
// allow a "*" wildcard to always match anything // allow a "*" wildcard to always match anything
if (this.wildcard && "".equals(this.cname)) if (this.wildcard && "".equals(this.cname))
...@@ -1168,6 +1204,75 @@ public final class SocketPermission extends Permission ...@@ -1168,6 +1204,75 @@ public final class SocketPermission extends Permission
init(getName(),getMask(actions)); 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() public String toString()
{ {
......
...@@ -200,6 +200,10 @@ public abstract class AsynchronousSocketChannel ...@@ -200,6 +200,10 @@ public abstract class AsynchronousSocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc} * @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc} * @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc} * @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/ */
@Override @Override
public abstract AsynchronousSocketChannel bind(SocketAddress local) public abstract AsynchronousSocketChannel bind(SocketAddress local)
......
...@@ -227,6 +227,10 @@ public abstract class SocketChannel ...@@ -227,6 +227,10 @@ public abstract class SocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc} * @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc} * @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@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 * @since 1.7
*/ */
......
...@@ -53,6 +53,13 @@ import sun.misc.SharedSecrets; ...@@ -53,6 +53,13 @@ import sun.misc.SharedSecrets;
* or method in this class will cause a {@link NullPointerException} to be * or method in this class will cause a {@link NullPointerException} to be
* thrown. * 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 * @author David Connelly
* @see Manifest * @see Manifest
* @see java.util.zip.ZipFile * @see java.util.zip.ZipFile
......
...@@ -179,7 +179,9 @@ class JarVerifier { ...@@ -179,7 +179,9 @@ class JarVerifier {
name = name.substring(1); name = name.substring(1);
// only set the jev object for entries that have a signature // 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); mev.setEntry(name, je);
return; return;
} }
......
...@@ -248,6 +248,11 @@ public class LogManager { ...@@ -248,6 +248,11 @@ public class LogManager {
* retrieved by calling LogManager.getLogManager. * retrieved by calling LogManager.getLogManager.
*/ */
protected LogManager() { protected LogManager() {
this(checkSubclassPermissions());
}
private LogManager(Void checked) {
// Add a shutdown hook to close the global handlers. // Add a shutdown hook to close the global handlers.
try { try {
Runtime.getRuntime().addShutdownHook(new Cleaner()); Runtime.getRuntime().addShutdownHook(new Cleaner());
...@@ -257,6 +262,19 @@ public class LogManager { ...@@ -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 * Lazy initialization: if this instance of manager is the global
* manager then this method will read the initial configuration and * manager then this method will read the initial configuration and
......
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -446,7 +446,7 @@ abstract class DoublePipeline<E_IN> ...@@ -446,7 +446,7 @@ abstract class DoublePipeline<E_IN>
@Override @Override
public final long count() { public final long count() {
return mapToObj(e -> null).mapToInt(e -> 1).sum(); return mapToLong(e -> 1L).sum();
} }
@Override @Override
......
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -426,7 +426,7 @@ abstract class IntPipeline<E_IN> ...@@ -426,7 +426,7 @@ abstract class IntPipeline<E_IN>
@Override @Override
public final long count() { public final long count() {
return asLongStream().map(e -> 1L).sum(); return mapToLong(e -> 1L).sum();
} }
@Override @Override
......
...@@ -91,7 +91,10 @@ public final class SimpleDoc implements Doc { ...@@ -91,7 +91,10 @@ public final class SimpleDoc implements Doc {
Class repClass = null; Class repClass = null;
try { 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) { } catch (Throwable e) {
throw new IllegalArgumentException("unknown representation class"); throw new IllegalArgumentException("unknown representation class");
} }
......
...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
package javax.security.auth; package javax.security.auth;
import java.security.Security; 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; import sun.security.util.Debug;
/** /**
...@@ -155,22 +159,15 @@ import sun.security.util.Debug; ...@@ -155,22 +159,15 @@ import sun.security.util.Debug;
public abstract class Policy { public abstract class Policy {
private static Policy policy; private static Policy policy;
private static ClassLoader contextClassLoader;
private final static String AUTH_POLICY = private final static String AUTH_POLICY =
"sun.security.provider.AuthPolicyFile"; "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 // true if a custom (not AUTH_POLICY) system-wide policy object is set
private static boolean isCustomPolicy; 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 * Sole constructor. (For invocation by subclass constructors, typically
* implicit.) * implicit.)
...@@ -213,8 +210,8 @@ public abstract class Policy { ...@@ -213,8 +210,8 @@ public abstract class Policy {
if (policy == null) { if (policy == null) {
String policy_class = null; String policy_class = null;
policy_class = java.security.AccessController.doPrivileged policy_class = AccessController.doPrivileged
(new java.security.PrivilegedAction<String>() { (new PrivilegedAction<String>() {
public String run() { public String run() {
return java.security.Security.getProperty return java.security.Security.getProperty
("auth.policy.provider"); ("auth.policy.provider");
...@@ -226,18 +223,28 @@ public abstract class Policy { ...@@ -226,18 +223,28 @@ public abstract class Policy {
try { try {
final String finalClass = policy_class; final String finalClass = policy_class;
policy = java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Policy>() { Policy untrustedImpl = AccessController.doPrivileged(
new PrivilegedExceptionAction<Policy>() {
public Policy run() throws ClassNotFoundException, public Policy run() throws ClassNotFoundException,
InstantiationException, InstantiationException,
IllegalAccessException { IllegalAccessException {
return (Policy) Class.forName Class<? extends Policy> implClass = Class.forName(
(finalClass, finalClass, false,
true, Thread.currentThread().getContextClassLoader()
contextClassLoader).newInstance(); ).asSubclass(Policy.class);
return implClass.newInstance();
} }
}); });
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() {
setPolicy(untrustedImpl);
isCustomPolicy = !finalClass.equals(AUTH_POLICY); isCustomPolicy = !finalClass.equals(AUTH_POLICY);
return null;
}
}, Objects.requireNonNull(untrustedImpl.acc)
);
} catch (Exception e) { } catch (Exception e) {
throw new SecurityException throw new SecurityException
(sun.security.util.ResourcesMgr.getString (sun.security.util.ResourcesMgr.getString
......
...@@ -964,6 +964,10 @@ public final class Subject implements java.io.Serializable { ...@@ -964,6 +964,10 @@ public final class Subject implements java.io.Serializable {
s.defaultReadObject(); 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 // The Credential {@code Set} is not serialized, but we do not
// want the default deserialization routine to set it to null. // want the default deserialization routine to set it to null.
this.pubCredentials = Collections.synchronizedSet this.pubCredentials = Collections.synchronizedSet
......
...@@ -27,9 +27,6 @@ package javax.security.auth.login; ...@@ -27,9 +27,6 @@ package javax.security.auth.login;
import javax.security.auth.AuthPermission; import javax.security.auth.AuthPermission;
import java.io.*;
import java.util.*;
import java.net.URI;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
...@@ -38,7 +35,7 @@ import java.security.NoSuchAlgorithmException; ...@@ -38,7 +35,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.Provider; import java.security.Provider;
import java.security.Security; import java.security.Security;
import java.security.SecurityPermission; import java.util.Objects;
import sun.security.jca.GetInstance; import sun.security.jca.GetInstance;
...@@ -191,16 +188,9 @@ import sun.security.jca.GetInstance; ...@@ -191,16 +188,9 @@ import sun.security.jca.GetInstance;
public abstract class Configuration { public abstract class Configuration {
private static Configuration configuration; private static Configuration configuration;
private static ClassLoader contextClassLoader;
static { private final java.security.AccessControlContext acc =
contextClassLoader = AccessController.doPrivileged java.security.AccessController.getContext();
(new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
};
private static void checkPermission(String type) { private static void checkPermission(String type) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
...@@ -253,17 +243,26 @@ public abstract class Configuration { ...@@ -253,17 +243,26 @@ public abstract class Configuration {
try { try {
final String finalClass = config_class; final String finalClass = config_class;
configuration = AccessController.doPrivileged Configuration untrustedImpl = AccessController.doPrivileged(
(new PrivilegedExceptionAction<Configuration>() { new PrivilegedExceptionAction<Configuration>() {
public Configuration run() throws ClassNotFoundException, public Configuration run() throws ClassNotFoundException,
InstantiationException, InstantiationException,
IllegalAccessException { IllegalAccessException {
return (Configuration)Class.forName Class<? extends Configuration> implClass = Class.forName(
(finalClass, finalClass, false,
true, Thread.currentThread().getContextClassLoader()
contextClassLoader).newInstance(); ).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) { } catch (PrivilegedActionException e) {
Exception ee = e.getException(); Exception ee = e.getException();
if (ee instanceof InstantiationException) { if (ee instanceof InstantiationException) {
......
...@@ -209,8 +209,7 @@ public class LoginContext { ...@@ -209,8 +209,7 @@ public class LoginContext {
private Map<String,?> state = new HashMap<String,Object>(); private Map<String,?> state = new HashMap<String,Object>();
private Configuration config; private Configuration config;
private boolean configProvided = false; private AccessControlContext creatorAcc = null; // customized config only
private AccessControlContext creatorAcc = null;
private ModuleInfo[] moduleStack; private ModuleInfo[] moduleStack;
private ClassLoader contextClassLoader = null; private ClassLoader contextClassLoader = null;
private static final Class<?>[] PARAMS = { }; private static final Class<?>[] PARAMS = { };
...@@ -229,7 +228,7 @@ public class LoginContext { ...@@ -229,7 +228,7 @@ public class LoginContext {
private void init(String name) throws LoginException { private void init(String name) throws LoginException {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null && !configProvided) { if (sm != null && creatorAcc == null) {
sm.checkPermission(new AuthPermission sm.checkPermission(new AuthPermission
("createLoginContext." + name)); ("createLoginContext." + name));
} }
...@@ -252,7 +251,7 @@ public class LoginContext { ...@@ -252,7 +251,7 @@ public class LoginContext {
AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name); AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
if (entries == null) { if (entries == null) {
if (sm != null && !configProvided) { if (sm != null && creatorAcc == null) {
sm.checkPermission(new AuthPermission sm.checkPermission(new AuthPermission
("createLoginContext." + OTHER)); ("createLoginContext." + OTHER));
} }
...@@ -279,7 +278,15 @@ public class LoginContext { ...@@ -279,7 +278,15 @@ public class LoginContext {
contextClassLoader = java.security.AccessController.doPrivileged contextClassLoader = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<ClassLoader>() { (new java.security.PrivilegedAction<ClassLoader>() {
public ClassLoader run() { 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 { ...@@ -298,10 +305,10 @@ public class LoginContext {
(DEFAULT_HANDLER); (DEFAULT_HANDLER);
if (defaultHandler == null || defaultHandler.length() == 0) if (defaultHandler == null || defaultHandler.length() == 0)
return null; return null;
Class<?> c = Class.forName(defaultHandler, Class<? extends CallbackHandler> c = Class.forName(
true, defaultHandler, true,
finalLoader); finalLoader).asSubclass(CallbackHandler.class);
return (CallbackHandler)c.newInstance(); return c.newInstance();
} }
}); });
} catch (java.security.PrivilegedActionException pae) { } catch (java.security.PrivilegedActionException pae) {
...@@ -309,7 +316,7 @@ public class LoginContext { ...@@ -309,7 +316,7 @@ public class LoginContext {
} }
// secure it with the caller's ACC // secure it with the caller's ACC
if (this.callbackHandler != null && !configProvided) { if (this.callbackHandler != null && creatorAcc == null) {
this.callbackHandler = new SecureCallbackHandler this.callbackHandler = new SecureCallbackHandler
(java.security.AccessController.getContext(), (java.security.AccessController.getContext(),
this.callbackHandler); this.callbackHandler);
...@@ -498,8 +505,7 @@ public class LoginContext { ...@@ -498,8 +505,7 @@ public class LoginContext {
CallbackHandler callbackHandler, CallbackHandler callbackHandler,
Configuration config) throws LoginException { Configuration config) throws LoginException {
this.config = config; this.config = config;
configProvided = (config != null) ? true : false; if (config != null) {
if (configProvided) {
creatorAcc = java.security.AccessController.getContext(); creatorAcc = java.security.AccessController.getContext();
} }
...@@ -510,7 +516,7 @@ public class LoginContext { ...@@ -510,7 +516,7 @@ public class LoginContext {
} }
if (callbackHandler == null) { if (callbackHandler == null) {
loadDefaultCallbackHandler(); loadDefaultCallbackHandler();
} else if (!configProvided) { } else if (creatorAcc == null) {
this.callbackHandler = new SecureCallbackHandler this.callbackHandler = new SecureCallbackHandler
(java.security.AccessController.getContext(), (java.security.AccessController.getContext(),
callbackHandler); callbackHandler);
...@@ -577,23 +583,13 @@ public class LoginContext { ...@@ -577,23 +583,13 @@ public class LoginContext {
} }
try { try {
if (configProvided) {
// module invoked in doPrivileged with creatorAcc
invokeCreatorPriv(LOGIN_METHOD);
invokeCreatorPriv(COMMIT_METHOD);
} else {
// module invoked in doPrivileged // module invoked in doPrivileged
invokePriv(LOGIN_METHOD); invokePriv(LOGIN_METHOD);
invokePriv(COMMIT_METHOD); invokePriv(COMMIT_METHOD);
}
loginSucceeded = true; loginSucceeded = true;
} catch (LoginException le) { } catch (LoginException le) {
try { try {
if (configProvided) {
invokeCreatorPriv(ABORT_METHOD);
} else {
invokePriv(ABORT_METHOD); invokePriv(ABORT_METHOD);
}
} catch (LoginException le2) { } catch (LoginException le2) {
throw le; throw le;
} }
...@@ -628,14 +624,9 @@ public class LoginContext { ...@@ -628,14 +624,9 @@ public class LoginContext {
("null.subject.logout.called.before.login")); ("null.subject.logout.called.before.login"));
} }
if (configProvided) {
// module invoked in doPrivileged with creatorAcc
invokeCreatorPriv(LOGOUT_METHOD);
} else {
// module invoked in doPrivileged // module invoked in doPrivileged
invokePriv(LOGOUT_METHOD); invokePriv(LOGOUT_METHOD);
} }
}
/** /**
* Return the authenticated Subject. * Return the authenticated Subject.
...@@ -677,35 +668,13 @@ public class LoginContext { ...@@ -677,35 +668,13 @@ public class LoginContext {
/** /**
* Invokes the login, commit, and logout methods * 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 * This version is called if the caller did not instantiate
* the LoginContext with a Configuration object. * the LoginContext with a Configuration object.
*/ */
private void invokePriv(final String methodName) throws LoginException { 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 { try {
java.security.AccessController.doPrivileged java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Void>() { (new java.security.PrivilegedExceptionAction<Void>() {
...@@ -735,44 +704,53 @@ public class LoginContext { ...@@ -735,44 +704,53 @@ public class LoginContext {
} else { } else {
// instantiate the LoginModule // 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, true,
contextClassLoader); contextClassLoader);
Constructor<?> constructor = c.getConstructor(PARAMS); Constructor<?> constructor = c.getConstructor(PARAMS);
Object[] args = { }; Object[] args = { };
// allow any object to be a LoginModule
// as long as it conforms to the interface
moduleStack[i].module = constructor.newInstance(args); moduleStack[i].module = constructor.newInstance(args);
methods = moduleStack[i].module.getClass().getMethods();
// call the LoginModule's initialize method // call the LoginModule's initialize method
methods = moduleStack[i].module.getClass().getMethods();
for (mIndex = 0; mIndex < methods.length; mIndex++) { for (mIndex = 0; mIndex < methods.length; mIndex++) {
if (methods[mIndex].getName().equals(INIT_METHOD)) if (methods[mIndex].getName().equals(INIT_METHOD)) {
break; break;
} }
}
Object[] initArgs = {subject, Object[] initArgs = {subject,
callbackHandler, callbackHandler,
state, state,
moduleStack[i].entry.getOptions() }; moduleStack[i].entry.getOptions() };
// invoke the LoginModule initialize method // 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); methods[mIndex].invoke(moduleStack[i].module, initArgs);
} }
// find the requested method in the LoginModule // find the requested method in the LoginModule
for (mIndex = 0; mIndex < methods.length; mIndex++) { for (mIndex = 0; mIndex < methods.length; mIndex++) {
if (methods[mIndex].getName().equals(methodName)) if (methods[mIndex].getName().equals(methodName)) {
break; break;
} }
}
// set up the arguments to be passed to the LoginModule method // set up the arguments to be passed to the LoginModule method
Object[] args = { }; Object[] args = { };
// invoke the LoginModule method // 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 boolean status = ((Boolean)methods[mIndex].invoke
(moduleStack[i].module, args)).booleanValue(); (moduleStack[i].module, args)).booleanValue();
......
...@@ -35,6 +35,8 @@ import java.io.FileInputStream; ...@@ -35,6 +35,8 @@ import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.naming.*; import javax.naming.*;
...@@ -348,7 +350,17 @@ public class SyncFactory { ...@@ -348,7 +350,17 @@ public class SyncFactory {
/* /*
* Dependent on application * 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) {
strRowsetProperties = null;
}
if (strRowsetProperties != null) { if (strRowsetProperties != null) {
// Load user's implementation of SyncProvider // Load user's implementation of SyncProvider
// here. -Drowset.properties=/abc/def/pqr.txt // here. -Drowset.properties=/abc/def/pqr.txt
...@@ -393,7 +405,16 @@ public class SyncFactory { ...@@ -393,7 +405,16 @@ public class SyncFactory {
* load additional properties from -D command line * load additional properties from -D command line
*/ */
properties.clear(); 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) { if (providerImpls != null) {
int i = 0; int i = 0;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
package javax.swing; package javax.swing;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
import sun.swing.UIAction; import sun.swing.UIAction;
...@@ -33,9 +34,6 @@ import java.awt.*; ...@@ -33,9 +34,6 @@ import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.dnd.DropTarget; import java.awt.dnd.DropTarget;
import java.util.Vector;
import java.util.Hashtable;
import java.lang.reflect.*; import java.lang.reflect.*;
import javax.accessibility.*; import javax.accessibility.*;
...@@ -1872,6 +1870,7 @@ public class SwingUtilities implements SwingConstants ...@@ -1872,6 +1870,7 @@ public class SwingUtilities implements SwingConstants
static Class<?> loadSystemClass(String className) throws ClassNotFoundException { static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
ReflectUtil.checkPackageAccess(className);
return Class.forName(className, true, Thread.currentThread(). return Class.forName(className, true, Thread.currentThread().
getContextClassLoader()); getContextClassLoader());
} }
......
...@@ -27,6 +27,7 @@ package javax.swing.event; ...@@ -27,6 +27,7 @@ package javax.swing.event;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import sun.reflect.misc.ReflectUtil;
/** /**
* A class that holds a list of EventListeners. A single instance * A class that holds a list of EventListeners. A single instance
...@@ -271,7 +272,9 @@ public class EventListenerList implements Serializable { ...@@ -271,7 +272,9 @@ public class EventListenerList implements Serializable {
while (null != (listenerTypeOrNull = s.readObject())) { while (null != (listenerTypeOrNull = s.readObject())) {
ClassLoader cl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = Thread.currentThread().getContextClassLoader();
EventListener l = (EventListener)s.readObject(); 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);
} }
} }
......
...@@ -428,6 +428,10 @@ abstract class AsynchronousSocketChannelImpl ...@@ -428,6 +428,10 @@ abstract class AsynchronousSocketChannelImpl
throw new AlreadyBoundException(); throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ? InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local); new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd); localAddress = Net.localAddress(fd);
......
...@@ -572,6 +572,10 @@ class SocketChannelImpl ...@@ -572,6 +572,10 @@ class SocketChannelImpl
throw new AlreadyBoundException(); throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ? InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local); new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd); localAddress = Net.localAddress(fd);
......
...@@ -28,7 +28,10 @@ package sun.reflect.generics.reflectiveObjects; ...@@ -28,7 +28,10 @@ package sun.reflect.generics.reflectiveObjects;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.lang.reflect.AnnotatedType; import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration; import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable; import java.lang.reflect.TypeVariable;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
...@@ -40,6 +43,7 @@ import sun.reflect.annotation.AnnotationType; ...@@ -40,6 +43,7 @@ import sun.reflect.annotation.AnnotationType;
import sun.reflect.generics.factory.GenericsFactory; import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.FieldTypeSignature; import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier; import sun.reflect.generics.visitor.Reifier;
import sun.reflect.misc.ReflectUtil;
/** /**
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface * Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
...@@ -95,6 +99,13 @@ public class TypeVariableImpl<D extends GenericDeclaration> ...@@ -95,6 +99,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
TypeVariableImpl<T> make(T decl, String name, TypeVariableImpl<T> make(T decl, String name,
FieldTypeSignature[] bs, FieldTypeSignature[] bs,
GenericsFactory f) { 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); return new TypeVariableImpl<T>(decl, name, bs, f);
} }
...@@ -149,6 +160,13 @@ public class TypeVariableImpl<D extends GenericDeclaration> ...@@ -149,6 +160,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
* @since 1.5 * @since 1.5
*/ */
public D getGenericDeclaration(){ 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; return genericDeclaration;
} }
...@@ -164,7 +182,8 @@ public class TypeVariableImpl<D extends GenericDeclaration> ...@@ -164,7 +182,8 @@ public class TypeVariableImpl<D extends GenericDeclaration>
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof TypeVariable) { if (o instanceof TypeVariable &&
o.getClass() == TypeVariableImpl.class) {
TypeVariable<?> that = (TypeVariable<?>) o; TypeVariable<?> that = (TypeVariable<?>) o;
GenericDeclaration thatDecl = that.getGenericDeclaration(); GenericDeclaration thatDecl = that.getGenericDeclaration();
......
...@@ -26,11 +26,13 @@ ...@@ -26,11 +26,13 @@
package sun.reflect.misc; package sun.reflect.misc;
import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Arrays; import java.util.Arrays;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
public final class ReflectUtil { public final class ReflectUtil {
...@@ -117,6 +119,40 @@ public final class ReflectUtil { ...@@ -117,6 +119,40 @@ public final class ReflectUtil {
return false; 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. * Checks package access on the given class.
* *
......
...@@ -94,8 +94,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer ...@@ -94,8 +94,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
RMIServerSocketFactory ssf) RMIServerSocketFactory ssf)
throws RemoteException throws RemoteException
{ {
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); LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref)); 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 ...@@ -104,8 +119,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl(int port) public RegistryImpl(int port)
throws RemoteException throws RemoteException
{ {
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); LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref)); 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 ...@@ -352,7 +382,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl run() throws RemoteException { public RegistryImpl run() throws RemoteException {
return new RegistryImpl(regPort); return new RegistryImpl(regPort);
} }
}, getAccessControlContext()); }, getAccessControlContext(regPort));
} catch (PrivilegedActionException ex) { } catch (PrivilegedActionException ex) {
throw (RemoteException) ex.getException(); throw (RemoteException) ex.getException();
} }
...@@ -382,7 +412,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer ...@@ -382,7 +412,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* The approach used here is taken from the similar method * The approach used here is taken from the similar method
* getAccessControlContext() in the sun.applet.AppletPanel class. * 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 // begin with permissions granted to all code in current policy
PermissionCollection perms = AccessController.doPrivileged( PermissionCollection perms = AccessController.doPrivileged(
new java.security.PrivilegedAction<PermissionCollection>() { new java.security.PrivilegedAction<PermissionCollection>() {
...@@ -404,6 +434,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer ...@@ -404,6 +434,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* related classes themselves are more tightly limited by RMI. * related classes themselves are more tightly limited by RMI.
*/ */
perms.add(new SocketPermission("*", "connect,accept")); 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.jvmstat.*"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*")); perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*"));
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -45,11 +45,12 @@ public class TlsRsaPremasterSecretParameterSpec ...@@ -45,11 +45,12 @@ public class TlsRsaPremasterSecretParameterSpec
private final int majorVersion; private final int majorVersion;
private final int minorVersion; private final int minorVersion;
private final byte[] encodedSecret;
/** /**
* Constructs a new TlsRsaPremasterSecretParameterSpec. * Constructs a new TlsRsaPremasterSecretParameterSpec.
* * <P>
* <p>The version numbers will be placed inside the premaster secret to * The version numbers will be placed inside the premaster secret to
* detect version rollbacks attacks as described in the TLS specification. * detect version rollbacks attacks as described in the TLS specification.
* Note that they do not indicate the protocol version negotiated for * Note that they do not indicate the protocol version negotiated for
* the handshake. * the handshake.
...@@ -65,7 +66,42 @@ public class TlsRsaPremasterSecretParameterSpec ...@@ -65,7 +66,42 @@ public class TlsRsaPremasterSecretParameterSpec
this.majorVersion = this.majorVersion =
TlsMasterSecretParameterSpec.checkVersion(majorVersion); TlsMasterSecretParameterSpec.checkVersion(majorVersion);
this.minorVersion = 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. * Returns the major version.
...@@ -84,4 +120,13 @@ public class TlsRsaPremasterSecretParameterSpec ...@@ -84,4 +120,13 @@ public class TlsRsaPremasterSecretParameterSpec
public int getMinorVersion() { public int getMinorVersion() {
return minorVersion; 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();
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -451,30 +451,7 @@ final class P11RSACipher extends CipherSpi { ...@@ -451,30 +451,7 @@ final class P11RSACipher extends CipherSpi {
// see JCE spec // see JCE spec
protected Key engineUnwrap(byte[] wrappedKey, String algorithm, protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
int type) throws InvalidKeyException, NoSuchAlgorithmException { 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 // XXX implement unwrap using C_Unwrap() for all keys
implInit(Cipher.DECRYPT_MODE, p11Key); implInit(Cipher.DECRYPT_MODE, p11Key);
if (wrappedKey.length > maxInputSize) { if (wrappedKey.length > maxInputSize) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -88,23 +88,33 @@ final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi { ...@@ -88,23 +88,33 @@ final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
throw new IllegalStateException throw new IllegalStateException
("TlsRsaPremasterSecretGenerator must be initialized"); ("TlsRsaPremasterSecretGenerator must be initialized");
} }
CK_VERSION version =
new CK_VERSION(spec.getMajorVersion(), spec.getMinorVersion()); byte[] b = spec.getEncodedSecret();
if (b == null) {
CK_VERSION version = new CK_VERSION(
spec.getMajorVersion(), spec.getMinorVersion());
Session session = null; Session session = null;
try { try {
session = token.getObjSession(); session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes CK_ATTRIBUTE[] attributes = token.getAttributes(
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); O_GENERATE, CKO_SECRET_KEY,
long keyID = token.p11.C_GenerateKey CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
(session.id(), new CK_MECHANISM(mechanism, version), attributes); long keyID = token.p11.C_GenerateKey(session.id(),
SecretKey key = P11Key.secretKey new CK_MECHANISM(mechanism, version), attributes);
(session, keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); SecretKey key = P11Key.secretKey(session,
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
return key; return key;
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
throw new ProviderException("Could not generate premaster secret", e); throw new ProviderException(
"Could not generate premaster secret", e);
} finally { } finally {
token.releaseSession(session); token.releaseSession(session);
} }
} }
// Won't worry, the TlsRsaPremasterSecret will be soon converted to
// TlsMasterSecret.
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,10 +43,8 @@ import sun.misc.Unsafe; ...@@ -43,10 +43,8 @@ import sun.misc.Unsafe;
* These are the only platforms we currently support, but other optimized * These are the only platforms we currently support, but other optimized
* variants could be added as needed. * variants could be added as needed.
* *
* NOTE that because this code performs unchecked direct memory access, it * NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks
* MUST be restricted to trusted code. It is imperative that the caller protects * failed.
* against out of bounds memory access by performing the necessary bounds
* checks before calling methods in this class.
* *
* This class may also be helpful in improving the performance of the * 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 * crypto code in the SunJCE provider. However, for now it is only accessible by
...@@ -103,6 +101,10 @@ final class ByteArrayAccess { ...@@ -103,6 +101,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, little endian byte order. * byte[] to int[] conversion, little endian byte order.
*/ */
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) { 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) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
len += inOfs; len += inOfs;
...@@ -131,6 +133,10 @@ final class ByteArrayAccess { ...@@ -131,6 +133,10 @@ final class ByteArrayAccess {
// Special optimization of b2iLittle(in, inOfs, out, 0, 64) // Special optimization of b2iLittle(in, inOfs, out, 0, 64)
static void b2iLittle64(byte[] in, int inOfs, int[] out) { static void b2iLittle64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
out[ 0] = unsafe.getInt(in, (long)(inOfs )); out[ 0] = unsafe.getInt(in, (long)(inOfs ));
...@@ -176,6 +182,10 @@ final class ByteArrayAccess { ...@@ -176,6 +182,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, little endian byte order. * int[] to byte[] conversion, little endian byte order.
*/ */
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) { 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) { if (littleEndianUnaligned) {
outOfs += byteArrayOfs; outOfs += byteArrayOfs;
len += outOfs; len += outOfs;
...@@ -204,6 +214,9 @@ final class ByteArrayAccess { ...@@ -204,6 +214,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order. // Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.
static void i2bLittle4(int val, byte[] out, int outOfs) { static void i2bLittle4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val); unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
} else if (bigEndian && ((outOfs & 3) == 0)) { } else if (bigEndian && ((outOfs & 3) == 0)) {
...@@ -220,6 +233,10 @@ final class ByteArrayAccess { ...@@ -220,6 +233,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, big endian byte order. * byte[] to int[] conversion, big endian byte order.
*/ */
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) { 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) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
len += inOfs; len += inOfs;
...@@ -248,6 +265,10 @@ final class ByteArrayAccess { ...@@ -248,6 +265,10 @@ final class ByteArrayAccess {
// Special optimization of b2iBig(in, inOfs, out, 0, 64) // Special optimization of b2iBig(in, inOfs, out, 0, 64)
static void b2iBig64(byte[] in, int inOfs, int[] out) { static void b2iBig64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs ))); out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
...@@ -293,6 +314,10 @@ final class ByteArrayAccess { ...@@ -293,6 +314,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, big endian byte order. * int[] to byte[] conversion, big endian byte order.
*/ */
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) { 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) { if (littleEndianUnaligned) {
outOfs += byteArrayOfs; outOfs += byteArrayOfs;
len += outOfs; len += outOfs;
...@@ -321,6 +346,9 @@ final class ByteArrayAccess { ...@@ -321,6 +346,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order. // Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
static void i2bBig4(int val, byte[] out, int outOfs) { static void i2bBig4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val)); unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
} else if (bigEndian && ((outOfs & 3) == 0)) { } else if (bigEndian && ((outOfs & 3) == 0)) {
...@@ -337,6 +365,10 @@ final class ByteArrayAccess { ...@@ -337,6 +365,10 @@ final class ByteArrayAccess {
* byte[] to long[] conversion, big endian byte order. * byte[] to long[] conversion, big endian byte order.
*/ */
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) { 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) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
len += inOfs; len += inOfs;
...@@ -378,6 +410,10 @@ final class ByteArrayAccess { ...@@ -378,6 +410,10 @@ final class ByteArrayAccess {
// Special optimization of b2lBig(in, inOfs, out, 0, 128) // Special optimization of b2lBig(in, inOfs, out, 0, 128)
static void b2lBig128(byte[] in, int inOfs, long[] out) { static void b2lBig128(byte[] in, int inOfs, long[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 128) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs ))); out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs )));
...@@ -406,6 +442,10 @@ final class ByteArrayAccess { ...@@ -406,6 +442,10 @@ final class ByteArrayAccess {
* long[] to byte[] conversion, big endian byte order. * long[] to byte[] conversion, big endian byte order.
*/ */
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) { 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; len += outOfs;
while (outOfs < len) { while (outOfs < len) {
long i = in[inOfs++]; long i = in[inOfs++];
...@@ -419,5 +459,4 @@ final class ByteArrayAccess { ...@@ -419,5 +459,4 @@ final class ByteArrayAccess {
out[outOfs++] = (byte)(i ); out[outOfs++] = (byte)(i );
} }
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -318,33 +318,53 @@ public final class RSAPadding { ...@@ -318,33 +318,53 @@ public final class RSAPadding {
/** /**
* PKCS#1 v1.5 unpadding (blocktype 1 and 2). * 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 { private byte[] unpadV15(byte[] padded) throws BadPaddingException {
int k = 0; int k = 0;
BadPaddingException bpe = null;
if (padded[k++] != 0) { if (padded[k++] != 0) {
throw new BadPaddingException("Data must start with zero"); bpe = new BadPaddingException("Data must start with zero");
} }
if (padded[k++] != type) { if (padded[k++] != type && bpe == null) {
throw new BadPaddingException("Blocktype mismatch: " + padded[1]); bpe = new BadPaddingException("Blocktype mismatch: " + padded[1]);
} }
while (true) { int p = 0;
while (k < padded.length) {
int b = padded[k++] & 0xff; int b = padded[k++] & 0xff;
if (b == 0) { if (b == 0 && p == 0) {
break; p = k;
} }
if (k == padded.length) { if (k == padded.length && p == 0 && bpe == null) {
throw new BadPaddingException("Padding string not terminated"); bpe = new BadPaddingException("Padding string not terminated");
} }
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff)) { if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
throw new BadPaddingException("Padding byte not 0xff: " + b); p == 0 && bpe == null) {
bpe = new BadPaddingException("Padding byte not 0xff: " + b);
} }
} }
int n = padded.length - k; int n = padded.length - p;
if (n > maxDataSize) { if (n > maxDataSize && bpe == null) {
throw new BadPaddingException("Padding string too short"); 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]; 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; return data;
} }
......
...@@ -1104,94 +1104,23 @@ abstract class Handshaker { ...@@ -1104,94 +1104,23 @@ abstract class Handshaker {
clnt_random.random_bytes, svr_random.random_bytes, clnt_random.random_bytes, svr_random.random_bytes,
prfHashAlg, prfHashLength, prfBlockSize); prfHashAlg, prfHashLength, prfBlockSize);
SecretKey masterSecret;
try { try {
KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg); KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
kg.init(spec); kg.init(spec);
masterSecret = kg.generateKey(); return kg.generateKey();
} catch (GeneralSecurityException e) { } catch (InvalidAlgorithmParameterException |
NoSuchAlgorithmException iae) {
// unlikely to happen, otherwise, must be a provider exception
//
// For RSA premaster secrets, do not signal a protocol error // For RSA premaster secrets, do not signal a protocol error
// due to the Bleichenbacher attack. See comments further down. // due to the Bleichenbacher attack. See comments further down.
if (!preMasterSecret.getAlgorithm().equals(
"TlsRsaPremasterSecret")) {
throw new ProviderException(e);
}
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA master secret generation error:"); System.out.println("RSA master secret generation error:");
e.printStackTrace(System.out); iae.printStackTrace(System.out);
}
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;
} }
throw new ProviderException(iae);
// 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);
} }
/* /*
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -133,26 +133,37 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -133,26 +133,37 @@ final class RSAClientKeyExchange extends HandshakeMessage {
} else { } else {
encrypted = new byte [messageSize]; encrypted = new byte [messageSize];
if (input.read(encrypted) != messageSize) { if (input.read(encrypted) != messageSize) {
throw new SSLProtocolException throw new SSLProtocolException(
("SSL: read PreMasterSecret: short read"); "SSL: read PreMasterSecret: short read");
} }
} }
Exception failover = null;
byte[] encoded = null;
try { try {
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
cipher.init(Cipher.UNWRAP_MODE, privateKey); // Cannot generate key here, please don't use Cipher.UNWRAP_MODE!
preMaster = (SecretKey)cipher.unwrap(encrypted, cipher.init(Cipher.DECRYPT_MODE, privateKey);
"TlsRsaPremasterSecret", Cipher.SECRET_KEY); encoded = cipher.doFinal(encrypted);
} catch (BadPaddingException bpe) {
// polish the premaster secret failover = bpe;
preMaster = polishPreMasterSecretKey(currentVersion, maxVersion, encoded = null;
generator, preMaster, 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) { } catch (Exception e) {
// polish the premaster secret // unlikely to happen, otherwise, must be a provider exception
preMaster = if (debug != null && Debug.isOn("handshake")) {
polishPreMasterSecretKey(currentVersion, maxVersion, System.out.println("RSA premaster secret decryption error:");
generator, null, e); 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,57 +174,51 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -163,57 +174,51 @@ final class RSAClientKeyExchange extends HandshakeMessage {
* *
* RFC 5246 describes the approach as : * 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 * 2. Decrypt the message to recover the plaintext M
* *
* 3. If the PKCS#1 padding is not correct, or the length of message * 3. If the PKCS#1 padding is not correct, or the length of message
* M is not exactly 48 bytes: * 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 * else If ClientHello.client_version <= TLS 1.0, and version
* number check is explicitly disabled: * number check is explicitly disabled:
* pre_master_secret = M * premaster secret = M
* else If M[0..1] != ClientHello.client_version:
* premaster secret = R
* else: * 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, private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion,
ProtocolVersion clientHelloVersion, SecureRandom generator, ProtocolVersion clientHelloVersion, SecureRandom generator,
SecretKey secretKey, Exception failoverException) { byte[] encoded, Exception failoverException) {
this.protocolVersion = clientHelloVersion; this.protocolVersion = clientHelloVersion;
if (generator == null) {
if (failoverException == null && secretKey != null) { generator = new SecureRandom();
// 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");
} }
byte[] random = new byte[48];
generator.nextBytes(random);
int keySize = KeyUtil.getKeySize(secretKey); if (failoverException == null && encoded != null) {
if (keySize > 0 && keySize != 384) { // 384 = 48 * 8 // check the length
if (encoded.length != 48) {
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println( System.out.println(
"incorrect length of premaster secret: " + "incorrect length of premaster secret: " +
(keySize/8)); encoded.length);
} }
return generateDummySecret(clientHelloVersion); return generatePreMasterSecret(
clientHelloVersion, random, generator);
} }
// The key size is exactly 48 bytes or not accessible. if (clientHelloVersion.major != encoded[0] ||
// clientHelloVersion.minor != encoded[1]) {
// Conservatively, pass the checking to master secret
// calculation. if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
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.major == encoded[0] &&
currentVersion.minor == encoded[1]) { currentVersion.minor == encoded[1]) {
/* /*
...@@ -222,26 +227,21 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -222,26 +227,21 @@ final class RSAClientKeyExchange extends HandshakeMessage {
* version for TLS v1.0 and SSL v3.0. * version for TLS v1.0 and SSL v3.0.
*/ */
this.protocolVersion = currentVersion; this.protocolVersion = currentVersion;
return secretKey; } else {
}
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println("Mismatching Protocol Versions, " + System.out.println("Mismatching Protocol Versions, " +
"ClientHello.client_version is " + clientHelloVersion + "ClientHello.client_version is " +
clientHelloVersion +
", while PreMasterSecret.client_version is " + ", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1])); ProtocolVersion.valueOf(encoded[0], encoded[1]));
} }
return generateDummySecret(clientHelloVersion); encoded = random;
} else {
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"incorrect length of premaster secret: " +
encoded.length);
} }
return generateDummySecret(clientHelloVersion);
} }
return generatePreMasterSecret(
clientHelloVersion, encoded, generator);
} }
if (debug != null && Debug.isOn("handshake") && if (debug != null && Debug.isOn("handshake") &&
...@@ -250,11 +250,14 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -250,11 +250,14 @@ final class RSAClientKeyExchange extends HandshakeMessage {
failoverException.printStackTrace(System.out); failoverException.printStackTrace(System.out);
} }
return generateDummySecret(clientHelloVersion); return generatePreMasterSecret(clientHelloVersion, random, generator);
} }
// generate a premaster secret with the specified version number // 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")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println("Generating a random fake premaster secret"); System.out.println("Generating a random fake premaster secret");
} }
...@@ -263,11 +266,17 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -263,11 +266,17 @@ final class RSAClientKeyExchange extends HandshakeMessage {
String s = ((version.v >= ProtocolVersion.TLS12.v) ? String s = ((version.v >= ProtocolVersion.TLS12.v) ?
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret"); "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
KeyGenerator kg = JsseJce.getKeyGenerator(s); KeyGenerator kg = JsseJce.getKeyGenerator(s);
kg.init(new TlsRsaPremasterSecretParameterSpec kg.init(new TlsRsaPremasterSecretParameterSpec(
(version.major, version.minor)); version.major, version.minor, encodedSecret), generator);
return kg.generateKey(); return kg.generateKey();
} catch (GeneralSecurityException e) { } catch (InvalidAlgorithmParameterException |
throw new RuntimeException("Could not generate dummy secret", e); 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);
} }
} }
......
...@@ -158,8 +158,13 @@ public class Main { ...@@ -158,8 +158,13 @@ public class Main {
private String altSignerClasspath = null; private String altSignerClasspath = null;
private ZipFile zipFile = null; private ZipFile zipFile = null;
private boolean hasExpiredCert = false; // Informational warnings
private boolean hasExpiringCert = false; 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 notYetValidCert = false;
private boolean chainNotValidated = false; private boolean chainNotValidated = false;
private boolean notSignedByAlias = false; private boolean notSignedByAlias = false;
...@@ -258,9 +263,6 @@ public class Main { ...@@ -258,9 +263,6 @@ public class Main {
if (strict) { if (strict) {
int exitCode = 0; int exitCode = 0;
if (hasExpiringCert) {
exitCode |= 2;
}
if (chainNotValidated || hasExpiredCert || notYetValidCert) { if (chainNotValidated || hasExpiredCert || notYetValidCert) {
exitCode |= 4; exitCode |= 4;
} }
...@@ -754,14 +756,25 @@ public class Main { ...@@ -754,14 +756,25 @@ public class Main {
System.out.println(rb.getString( System.out.println(rb.getString(
"jar.is.unsigned.signatures.missing.or.not.parsable.")); "jar.is.unsigned.signatures.missing.or.not.parsable."));
} else { } else {
System.out.println(rb.getString("jar.verified.")); boolean warningAppeared = false;
if (hasUnsignedEntry || hasExpiredCert || hasExpiringCert || boolean errorAppeared = false;
badKeyUsage || badExtendedKeyUsage || badNetscapeCertType || if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated || notYetValidCert || chainNotValidated || hasExpiredCert ||
hasUnsignedEntry ||
aliasNotInStore || notSignedByAlias) { 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();
System.out.println(rb.getString("Warning.")); System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
if (badKeyUsage) { if (badKeyUsage) {
System.out.println( System.out.println(
rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing.")); rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
...@@ -785,10 +798,6 @@ public class Main { ...@@ -785,10 +798,6 @@ public class Main {
System.out.println(rb.getString( System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.has.expired.")); "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) { if (notYetValidCert) {
System.out.println(rb.getString( System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid.")); "This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid."));
...@@ -807,6 +816,25 @@ public class Main { ...@@ -807,6 +816,25 @@ public class Main {
if (aliasNotInStore) { if (aliasNotInStore) {
System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore.")); 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)) { if (! (verbose != null && showcerts)) {
System.out.println(); System.out.println();
System.out.println(rb.getString( System.out.println(rb.getString(
...@@ -870,6 +898,9 @@ public class Main { ...@@ -870,6 +898,9 @@ public class Main {
try { try {
boolean printValidity = true; boolean printValidity = true;
if (timestamp == null) { if (timestamp == null) {
if (expireDate.getTime() == 0 || expireDate.after(notAfter)) {
expireDate = notAfter;
}
x509Cert.checkValidity(); x509Cert.checkValidity();
// test if cert will expire within six months // test if cert will expire within six months
if (notAfter.getTime() < System.currentTimeMillis() + SIX_MONTHS) { if (notAfter.getTime() < System.currentTimeMillis() + SIX_MONTHS) {
...@@ -1233,6 +1264,10 @@ public class Main { ...@@ -1233,6 +1264,10 @@ public class Main {
tsaCert = getTsaCert(tsaAlias); tsaCert = getTsaCert(tsaAlias);
} }
if (tsaUrl == null && tsaCert == null) {
noTimestamp = true;
}
SignatureFile.Block block = null; SignatureFile.Block block = null;
try { try {
...@@ -1380,12 +1415,20 @@ public class Main { ...@@ -1380,12 +1415,20 @@ public class Main {
} }
} }
if (hasExpiredCert || hasExpiringCert || notYetValidCert boolean warningAppeared = false;
|| badKeyUsage || badExtendedKeyUsage if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
|| badNetscapeCertType || chainNotValidated) { 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();
System.out.println(rb.getString("Warning.")); System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
if (badKeyUsage) { if (badKeyUsage) {
System.out.println( System.out.println(
rb.getString("The.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing.")); rb.getString("The.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
...@@ -1404,9 +1447,6 @@ public class Main { ...@@ -1404,9 +1447,6 @@ public class Main {
if (hasExpiredCert) { if (hasExpiredCert) {
System.out.println( System.out.println(
rb.getString("The.signer.certificate.has.expired.")); 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) { } else if (notYetValidCert) {
System.out.println( System.out.println(
rb.getString("The.signer.certificate.is.not.yet.valid.")); rb.getString("The.signer.certificate.is.not.yet.valid."));
...@@ -1416,6 +1456,24 @@ public class Main { ...@@ -1416,6 +1456,24 @@ public class Main {
System.out.println( System.out.println(
rb.getString("The.signer.s.certificate.chain.is.not.validated.")); 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 // no IOException thrown in the above try clause, so disable
...@@ -1502,6 +1560,7 @@ public class Main { ...@@ -1502,6 +1560,7 @@ public class Main {
timestamp = ts.getTimestamp(); timestamp = ts.getTimestamp();
} else { } else {
timestamp = null; timestamp = null;
noTimestamp = true;
} }
// display the certificate(s). The first one is end-entity cert and // display the certificate(s). The first one is end-entity cert and
// its KeyUsage should be checked. // its KeyUsage should be checked.
......
...@@ -112,9 +112,9 @@ public class Resources extends java.util.ListResourceBundle { ...@@ -112,9 +112,9 @@ public class Resources extends java.util.ListResourceBundle {
{"Please.specify.alias.name", "Please specify alias name"}, {"Please.specify.alias.name", "Please specify alias name"},
{"Only.one.alias.can.be.specified", "Only one alias can be specified"}, {"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 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's not signed by alias in this keystore."}, "This jar contains signed entries that are not signed by alias in this keystore."},
{"s", "s"}, {"s", "s"},
{"m", "m"}, {"m", "m"},
{"k", "k"}, {"k", "k"},
...@@ -135,7 +135,10 @@ public class Resources extends java.util.ListResourceBundle { ...@@ -135,7 +135,10 @@ public class Resources extends java.util.ListResourceBundle {
{".Unsigned.entries.", "(Unsigned entries)"}, {".Unsigned.entries.", "(Unsigned entries)"},
{"jar.is.unsigned.signatures.missing.or.not.parsable.", {"jar.is.unsigned.signatures.missing.or.not.parsable.",
"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.", "jar verified."},
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
{"jarsigner.", "jarsigner: "}, {"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.",
"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 { ...@@ -193,6 +196,7 @@ public class Resources extends java.util.ListResourceBundle {
"using an alternative signing mechanism"}, "using an alternative signing mechanism"},
{"entry.was.signed.on", "entry was signed on {0}"}, {"entry.was.signed.on", "entry was signed on {0}"},
{"Warning.", "Warning: "}, {"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 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.", {"This.jar.contains.entries.whose.signer.certificate.has.expired.",
...@@ -229,6 +233,10 @@ public class Resources extends java.util.ListResourceBundle { ...@@ -229,6 +233,10 @@ public class Resources extends java.util.ListResourceBundle {
"The signer's certificate chain is not validated."}, "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.",
"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: "}, {"Unknown.password.type.", "Unknown password type: "},
{"Cannot.find.environment.variable.", {"Cannot.find.environment.variable.",
"Cannot find environment variable: "}, "Cannot find environment variable: "},
......
...@@ -222,5 +222,5 @@ public final class SecurityConstants { ...@@ -222,5 +222,5 @@ public final class SecurityConstants {
// java.lang.SecurityManager // java.lang.SecurityManager
public static final SocketPermission LOCAL_LISTEN_PERMISSION = public static final SocketPermission LOCAL_LISTEN_PERMISSION =
new SocketPermission("localhost:1024-", SOCKET_LISTEN_ACTION); new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION);
} }
...@@ -19,8 +19,8 @@ grant { ...@@ -19,8 +19,8 @@ grant {
// information. // information.
permission java.lang.RuntimePermission "stopThread"; permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on un-privileged ports // allows anyone to listen on dynamic ports
permission java.net.SocketPermission "localhost:1024-", "listen"; permission java.net.SocketPermission "localhost:0", "listen";
// "standard" properies that can be read by anyone // "standard" properies that can be read by anyone
......
...@@ -182,6 +182,7 @@ package.access=sun.,\ ...@@ -182,6 +182,7 @@ package.access=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -228,6 +229,7 @@ package.definition=sun.,\ ...@@ -228,6 +229,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 ...@@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048 # jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
...@@ -183,6 +183,7 @@ package.access=sun.,\ ...@@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -229,6 +230,7 @@ package.definition=sun.,\ ...@@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 ...@@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048 # jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
...@@ -184,6 +184,7 @@ package.access=sun.,\ ...@@ -184,6 +184,7 @@ package.access=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -229,6 +230,7 @@ package.definition=sun.,\ ...@@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 ...@@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048 # jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
...@@ -183,6 +183,7 @@ package.access=sun.,\ ...@@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -229,6 +230,7 @@ package.definition=sun.,\ ...@@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.media.sound.,\ com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.corba.se.,\ com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\ com.sun.org.apache.bcel.internal.,\
...@@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 ...@@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048 # jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
...@@ -111,8 +111,9 @@ SplashDone(Splash * splash) ...@@ -111,8 +111,9 @@ SplashDone(Splash * splash)
int int
SplashIsStillLooping(Splash * splash) SplashIsStillLooping(Splash * splash)
{ {
if (splash->currentFrame < 0) if (splash->currentFrame < 0) {
return 0; return 0;
}
return splash->loopCount != 1 || return splash->loopCount != 1 ||
splash->currentFrame + 1 < splash->frameCount; splash->currentFrame + 1 < splash->frameCount;
} }
...@@ -121,17 +122,22 @@ void ...@@ -121,17 +122,22 @@ void
SplashUpdateScreenData(Splash * splash) SplashUpdateScreenData(Splash * splash)
{ {
ImageRect srcRect, dstRect; ImageRect srcRect, dstRect;
if (splash->currentFrame < 0) {
return;
}
initRect(&srcRect, 0, 0, splash->width, splash->height, 1, initRect(&srcRect, 0, 0, splash->width, splash->height, 1,
splash->width * sizeof(rgbquad_t), splash->width * sizeof(rgbquad_t),
splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat); splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat);
if (splash->screenData) if (splash->screenData) {
free(splash->screenData); free(splash->screenData);
}
splash->screenStride = splash->width * splash->screenFormat.depthBytes; splash->screenStride = splash->width * splash->screenFormat.depthBytes;
if (splash->byteAlignment > 1) if (splash->byteAlignment > 1) {
splash->screenStride = splash->screenStride =
(splash->screenStride + splash->byteAlignment - 1) & (splash->screenStride + splash->byteAlignment - 1) &
~(splash->byteAlignment - 1); ~(splash->byteAlignment - 1);
}
splash->screenData = malloc(splash->height * splash->screenStride); splash->screenData = malloc(splash->height * splash->screenStride);
initRect(&dstRect, 0, 0, splash->width, splash->height, 1, initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
splash->screenStride, splash->screenData, &splash->screenFormat); splash->screenStride, splash->screenData, &splash->screenFormat);
...@@ -146,17 +152,20 @@ SplashUpdateScreenData(Splash * splash) ...@@ -146,17 +152,20 @@ SplashUpdateScreenData(Splash * splash)
void void
SplashNextFrame(Splash * splash) SplashNextFrame(Splash * splash)
{ {
if (splash->currentFrame < 0) if (splash->currentFrame < 0) {
return; return;
}
do { do {
if (!SplashIsStillLooping(splash)) if (!SplashIsStillLooping(splash)) {
return; return;
}
splash->time += splash->frames[splash->currentFrame].delay; splash->time += splash->frames[splash->currentFrame].delay;
if (++splash->currentFrame >= splash->frameCount) { if (++splash->currentFrame >= splash->frameCount) {
splash->currentFrame = 0; splash->currentFrame = 0;
if (splash->loopCount > 0) if (splash->loopCount > 0) {
splash->loopCount--; splash->loopCount--;
} }
}
} while (splash->time + splash->frames[splash->currentFrame].delay - } while (splash->time + splash->frames[splash->currentFrame].delay -
SplashTime() <= 0); SplashTime() <= 0);
} }
...@@ -183,8 +192,9 @@ BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out) ...@@ -183,8 +192,9 @@ BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out)
pSrc += pSrcRect->depthBytes; pSrc += pSrcRect->depthBytes;
++i; ++i;
} }
if (i >= pSrcRect->numSamples) if (i >= pSrcRect->numSamples) {
break; break;
}
i0 = i; i0 = i;
while (i < pSrcRect->numSamples && while (i < pSrcRect->numSamples &&
getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) { getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) {
......
...@@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu ...@@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset)); (const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]); 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])); glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
} }
......
...@@ -37,55 +37,54 @@ ...@@ -37,55 +37,54 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, void AnchorTable::getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const LEPoint &anchor, LEErrorCode &success) const
{ {
switch(SWAPW(anchorFormat)) { switch(SWAPW(anchorFormat)) {
case 1: case 1:
{ {
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this; LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
f1->getAnchor(fontInstance, anchor);
break; break;
} }
case 2: case 2:
{ {
const Format2AnchorTable *f2 = (const Format2AnchorTable *) this; LEReferenceTo<Format2AnchorTable> f2(base, success);
f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
f2->getAnchor(glyphID, fontInstance, anchor);
break; break;
} }
case 3: case 3:
{ {
const Format3AnchorTable *f3 = (const Format3AnchorTable *) this; LEReferenceTo<Format3AnchorTable> f3(base, success);
f3->getAnchor(f3, fontInstance, anchor, success);
f3->getAnchor(fontInstance, anchor);
break; break;
} }
default: default:
{
// unknown format: just use x, y coordinate, like format 1... // unknown format: just use x, y coordinate, like format 1...
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this; LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
f1->getAnchor(fontInstance, anchor);
break; 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 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate); le_int16 y = SWAPW(yCoordinate);
LEPoint pixels; LEPoint pixels;
fontInstance->transformFunits(x, y, pixels); fontInstance->transformFunits(x, y, pixels);
fontInstance->pixelsToUnits(pixels, anchor); 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; LEPoint point;
...@@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font ...@@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font
fontInstance->pixelsToUnits(point, anchor); 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 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate); le_int16 y = SWAPW(yCoordinate);
...@@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint & ...@@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &
fontInstance->transformFunits(x, y, pixels); fontInstance->transformFunits(x, y, pixels);
if (dtxOffset != 0) { if (dtxOffset != 0) {
const DeviceTable *dtx = (const DeviceTable *) ((char *) this + dtxOffset); LEReferenceTo<DeviceTable> dt(base, success, dtxOffset);
le_int16 adjx = dtx->getAdjustment((le_int16) fontInstance->getXPixelsPerEm()); le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
pixels.fX += adjx; pixels.fX += adjx;
} }
if (dtyOffset != 0) { if (dtyOffset != 0) {
const DeviceTable *dty = (const DeviceTable *) ((char *) this + dtyOffset); LEReferenceTo<DeviceTable> dt(base, success, dtyOffset);
le_int16 adjy = dty->getAdjustment((le_int16) fontInstance->getYPixelsPerEm()); le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
pixels.fY += adjy; pixels.fY += adjy;
} }
......
...@@ -49,20 +49,23 @@ struct AnchorTable ...@@ -49,20 +49,23 @@ struct AnchorTable
le_int16 xCoordinate; le_int16 xCoordinate;
le_int16 yCoordinate; le_int16 yCoordinate;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, void getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const; LEPoint &anchor, LEErrorCode &success) const;
}; };
struct Format1AnchorTable : AnchorTable 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 struct Format2AnchorTable : AnchorTable
{ {
le_uint16 anchorPoint; 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 struct Format3AnchorTable : AnchorTable
...@@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable ...@@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable
Offset xDeviceTableOffset; Offset xDeviceTableOffset;
Offset yDeviceTableOffset; 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 U_NAMESPACE_END
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const
{ {
return fFontInstance->canDisplay((LEUnicode) glyph); return fFontInstance->canDisplay((LEUnicode) glyph);
} }
...@@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l ...@@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
GDEFMarkFilter filter(fGDEFTable, success); GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success); adjustMarkGlyphs(glyphStorage, &filter, success);
} else { } else {
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,
CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable, success); GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
...@@ -157,8 +159,8 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l ...@@ -157,8 +159,8 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) 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) : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{ {
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; fGSUBTable.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
/* OpenTypeLayoutEngine will allocate a substitution filter */ /* OpenTypeLayoutEngine will allocate a substitution filter */
} }
......
...@@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] = ...@@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{ {
LEErrorCode success = LE_NO_ERROR; 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); ArabicShaping::shapingTypeTableLen);
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success); le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
......
...@@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le ...@@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
LEUnicode *outChars, LEGlyphStorage &glyphStorage) LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{ {
LEErrorCode success = LE_NO_ERROR; 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); LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount); le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount); le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
......
...@@ -43,6 +43,8 @@ class LEFontInstance; ...@@ -43,6 +43,8 @@ class LEFontInstance;
* This filter is used by character-based GSUB processors. It * This filter is used by character-based GSUB processors. It
* accepts only those characters which the given font can display. * accepts only those characters which the given font can display.
* *
* Note: Implementation is in ArabicLayoutEngine.cpp
*
* @internal * @internal
*/ */
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
...@@ -97,7 +99,7 @@ public: ...@@ -97,7 +99,7 @@ public:
* *
* @internal * @internal
*/ */
le_bool accept(LEGlyphID glyph) const; le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -49,6 +49,7 @@ struct ClassDefinitionTable ...@@ -49,6 +49,7 @@ struct ClassDefinitionTable
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const; le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, 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 { le_int32 getGlyphClass(LEGlyphID glyphID) const {
LETableReference base((const le_uint8*)this); LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR; LEErrorCode ignored = LE_NO_ERROR;
...@@ -60,6 +61,7 @@ struct ClassDefinitionTable ...@@ -60,6 +61,7 @@ struct ClassDefinitionTable
LEErrorCode ignored = LE_NO_ERROR; LEErrorCode ignored = LE_NO_ERROR;
return hasGlyphClass(base,glyphClass,ignored); return hasGlyphClass(base,glyphClass,ignored);
} }
#endif
}; };
struct ClassDefFormat1Table : ClassDefinitionTable struct ClassDefFormat1Table : ClassDefinitionTable
......
...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN ...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
*/ */
void ContextualSubstitutionBase::applySubstitutionLookups( void ContextualSubstitutionBase::applySubstitutionLookups(
const LookupProcessor *lookupProcessor, const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray, const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount, le_uint16 substCount,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
...@@ -60,10 +60,11 @@ void ContextualSubstitutionBase::applySubstitutionLookups( ...@@ -60,10 +60,11 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
} }
GlyphIterator tempIterator(*glyphIterator); 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) { for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex); le_uint16 sequenceIndex = SWAPW(substLookupRecordArrayPtr[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex); le_uint16 lookupListIndex = SWAPW(substLookupRecordArrayPtr[subst].lookupListIndex);
tempIterator.setCurrStreamPosition(position); tempIterator.setCurrStreamPosition(position);
tempIterator.next(sequenceIndex); tempIterator.next(sequenceIndex);
...@@ -72,7 +73,7 @@ void ContextualSubstitutionBase::applySubstitutionLookups( ...@@ -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) GlyphIterator *glyphIterator, le_bool backtrack)
{ {
le_int32 direction = 1; le_int32 direction = 1;
...@@ -101,9 +102,12 @@ le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, l ...@@ -101,9 +102,12 @@ le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, l
return TRUE; return TRUE;
} }
le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArray, le_uint16 glyphCount, le_bool ContextualSubstitutionBase::matchGlyphClasses(
const LEReferenceToArrayOf<le_uint16> &classArray,
le_uint16 glyphCount,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable, const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable,
LEErrorCode &success,
le_bool backtrack) le_bool backtrack)
{ {
le_int32 direction = 1; le_int32 direction = 1;
...@@ -120,7 +124,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra ...@@ -120,7 +124,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
} }
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 glyphClass = classDefinitionTable->getGlyphClass(glyph); le_int32 glyphClass = classDefinitionTable->getGlyphClass(classDefinitionTable, glyph, success);
le_int32 matchClass = SWAPW(classArray[match]); le_int32 matchClass = SWAPW(classArray[match]);
if (glyphClass != matchClass) { if (glyphClass != matchClass) {
...@@ -128,7 +132,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra ...@@ -128,7 +132,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
// in the class array which aren't in the class definition // in the class array which aren't in the class definition
// table. If we're looking for such a class, pretend that // table. If we're looking for such a class, pretend that
// we found it. // we found it.
if (classDefinitionTable->hasGlyphClass(matchClass)) { if (classDefinitionTable->hasGlyphClass(classDefinitionTable, matchClass, success)) {
return FALSE; return FALSE;
} }
} }
...@@ -140,8 +144,8 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra ...@@ -140,8 +144,8 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
return TRUE; return TRUE;
} }
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTableOffsetArray, le_uint16 glyphCount, le_bool ContextualSubstitutionBase::matchGlyphCoverages(const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack) GlyphIterator *glyphIterator, const LETableReference &offsetBase, LEErrorCode &success, le_bool backtrack)
{ {
le_int32 direction = 1; le_int32 direction = 1;
le_int32 glyph = 0; le_int32 glyph = 0;
...@@ -153,13 +157,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa ...@@ -153,13 +157,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
while (glyphCount > 0) { while (glyphCount > 0) {
Offset coverageTableOffset = SWAPW(coverageTableOffsetArray[glyph]); 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; return FALSE;
} }
if (coverageTable->getGlyphCoverage((LEGlyphID) glyphIterator->getCurrGlyphID()) < 0) { if (coverageTable->getGlyphCoverage(coverageTable,
(LEGlyphID) glyphIterator->getCurrGlyphID(),
success) < 0) {
return FALSE; return FALSE;
} }
...@@ -170,7 +176,7 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa ...@@ -170,7 +176,7 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
return TRUE; return TRUE;
} }
le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, le_uint32 ContextualSubstitutionSubtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -186,20 +192,29 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP ...@@ -186,20 +192,29 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
case 1: case 1:
{ {
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this; LEReferenceTo<ContextualSubstitutionFormat1Subtable> subtable(base, success, (const ContextualSubstitutionFormat1Subtable *) this);
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
} }
case 2: case 2:
{ {
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this; LEReferenceTo<ContextualSubstitutionFormat2Subtable> subtable(base, success, (const ContextualSubstitutionFormat2Subtable *) this);
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
} }
case 3: case 3:
{ {
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this; LEReferenceTo<ContextualSubstitutionFormat3Subtable> subtable(base, success, (const ContextualSubstitutionFormat3Subtable *) this);
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
} }
default: default:
...@@ -207,7 +222,7 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP ...@@ -207,7 +222,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, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -227,22 +242,22 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * ...@@ -227,22 +242,22 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
if (coverageIndex < srSetCount) { if (coverageIndex < srSetCount) {
Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]);
const SubRuleSetTable *subRuleSetTable = LEReferenceTo<SubRuleSetTable>
(const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset); subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset));
le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount); le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition(); le_int32 position = glyphIterator->getCurrStreamPosition();
for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) { for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) {
Offset subRuleTableOffset = Offset subRuleTableOffset =
SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]); SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]);
const SubRuleTable *subRuleTable = LEReferenceTo<SubRuleTable>
(const SubRuleTable *) ((char *) subRuleSetTable + subRuleTableOffset); subRuleTable(subRuleSetTable, success, subRuleTableOffset);
le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1; le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1;
le_uint16 substCount = SWAPW(subRuleTable->substCount); le_uint16 substCount = SWAPW(subRuleTable->substCount);
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2);
if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) { if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray = LEReferenceToArrayOf<SubstitutionLookupRecord>
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount]; substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
...@@ -259,7 +274,8 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * ...@@ -259,7 +274,8 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
return 0; return 0;
} }
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -275,29 +291,33 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * ...@@ -275,29 +291,33 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
} }
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
const ClassDefinitionTable *classDefinitionTable = LEReferenceTo<ClassDefinitionTable> classDefinitionTable(base, success,
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)); (const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)));
le_uint16 scSetCount = SWAPW(subClassSetCount); 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) { if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) {
Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]);
const SubClassSetTable *subClassSetTable = LEReferenceTo<SubClassSetTable>
(const SubClassSetTable *) ((char *) this + subClassSetTableOffset); subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset));
le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition(); le_int32 position = glyphIterator->getCurrStreamPosition();
for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) {
Offset subClassRuleTableOffset = Offset subClassRuleTableOffset =
SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]);
const SubClassRuleTable *subClassRuleTable = LEReferenceTo<SubClassRuleTable>
(const SubClassRuleTable *) ((char *) subClassSetTable + subClassRuleTableOffset); subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset);
le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1;
le_uint16 substCount = SWAPW(subClassRuleTable->substCount); le_uint16 substCount = SWAPW(subClassRuleTable->substCount);
if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) { LEReferenceToArrayOf<le_uint16> classArray(base, success, subClassRuleTable->classArray, matchCount+1);
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount]; 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); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
...@@ -314,7 +334,8 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * ...@@ -314,7 +334,8 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
return 0; return 0;
} }
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, le_uint32 ContextualSubstitutionFormat3Subtable::process(const LETableReference &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success)const LEErrorCode& success)const
...@@ -333,9 +354,13 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * ...@@ -333,9 +354,13 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
// that matched when we're done. // that matched when we're done.
glyphIterator->prev(); glyphIterator->prev();
if (ContextualSubstitutionBase::matchGlyphCoverages(coverageTableOffsetArray, gCount, glyphIterator, (const char *) this)) { LEReferenceToArrayOf<Offset> covTableOffsetArray(base, success, coverageTableOffsetArray, gCount);
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &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); ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
...@@ -347,7 +372,8 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * ...@@ -347,7 +372,8 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
return 0; return 0;
} }
le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, le_uint32 ChainingContextualSubstitutionSubtable::process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -363,20 +389,23 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor ...@@ -363,20 +389,23 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
case 1: case 1:
{ {
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this; LEReferenceTo<ChainingContextualSubstitutionFormat1Subtable> subtable(base, success, (ChainingContextualSubstitutionFormat1Subtable *) this);
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); if(LE_FAILURE(success)) return 0;
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
} }
case 2: case 2:
{ {
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this; LEReferenceTo<ChainingContextualSubstitutionFormat2Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat2Subtable *) this);
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); if( LE_FAILURE(success) ) { return 0; }
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
} }
case 3: case 3:
{ {
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this; LEReferenceTo<ChainingContextualSubstitutionFormat3Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat3Subtable *) this);
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); if( LE_FAILURE(success) ) { return 0; }
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
} }
default: default:
...@@ -390,7 +419,7 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor ...@@ -390,7 +419,7 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
// emptyFeatureList matches an le_uint32 or an le_uint16... // emptyFeatureList matches an le_uint32 or an le_uint16...
static const FeatureMask emptyFeatureList = 0x00000000UL; static const FeatureMask emptyFeatureList = 0x00000000UL;
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -410,8 +439,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -410,8 +439,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
if (coverageIndex < srSetCount) { if (coverageIndex < srSetCount) {
Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]);
const ChainSubRuleSetTable *chainSubRuleSetTable = LEReferenceTo<ChainSubRuleSetTable>
(const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset); chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset));
le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition(); le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
...@@ -419,13 +448,19 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -419,13 +448,19 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) {
Offset chainSubRuleTableOffset = Offset chainSubRuleTableOffset =
SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]); SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]);
const ChainSubRuleTable *chainSubRuleTable = LEReferenceTo<ChainSubRuleTable>
(const ChainSubRuleTable *) ((char *) chainSubRuleSetTable + chainSubRuleTableOffset); chainSubRuleTable = LEReferenceTo<ChainSubRuleTable>(chainSubRuleSetTable, success, chainSubRuleTableOffset);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount); 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; 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]); 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]); le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]);
tempIterator.setCurrStreamPosition(position); tempIterator.setCurrStreamPosition(position);
...@@ -435,7 +470,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -435,7 +470,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
} }
tempIterator.prev(); tempIterator.prev();
if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
if (! matchGlyphIDs(backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
continue; continue;
} }
...@@ -446,8 +482,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -446,8 +482,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
} }
if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) { if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray = LEReferenceToArrayOf<SubstitutionLookupRecord>
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1]; substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadGlyphArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
...@@ -464,7 +500,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -464,7 +500,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
return 0; return 0;
} }
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -480,19 +516,21 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -480,19 +516,21 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
} }
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
const ClassDefinitionTable *backtrackClassDefinitionTable = LEReferenceTo<ClassDefinitionTable>
(const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset)); backtrackClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset)));
const ClassDefinitionTable *inputClassDefinitionTable = LEReferenceTo<ClassDefinitionTable>
(const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset)); inputClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset)));
const ClassDefinitionTable *lookaheadClassDefinitionTable = LEReferenceTo<ClassDefinitionTable>
(const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset)); lookaheadClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset)));
le_uint16 scSetCount = SWAPW(chainSubClassSetCount); 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) { if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) {
Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]); Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]);
const ChainSubClassSetTable *chainSubClassSetTable = LEReferenceTo<ChainSubClassSetTable>
(const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset); chainSubClassSetTable(base, success, (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset));
le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition(); le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
...@@ -500,13 +538,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -500,13 +538,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) {
Offset chainSubClassRuleTableOffset = Offset chainSubClassRuleTableOffset =
SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]); SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]);
const ChainSubClassRuleTable *chainSubClassRuleTable = LEReferenceTo<ChainSubClassRuleTable>
(const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset); chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset);
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount); le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1; le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1]; LEReferenceToArrayOf<le_uint16> inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]); le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success));
const le_uint16 *lookaheadClassArray = &inputClassArray[inputGlyphCount + 1]; 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]); le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]);
...@@ -517,20 +557,22 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -517,20 +557,22 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
} }
tempIterator.prev(); tempIterator.prev();
if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount, LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
&tempIterator, backtrackClassDefinitionTable, TRUE)) { if( LE_FAILURE(success) ) { return 0; }
if (! matchGlyphClasses(backtrackClassArray, backtrackGlyphCount,
&tempIterator, backtrackClassDefinitionTable, success, TRUE)) {
continue; continue;
} }
tempIterator.setCurrStreamPosition(position); tempIterator.setCurrStreamPosition(position);
tempIterator.next(inputGlyphCount); tempIterator.next(inputGlyphCount);
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable)) { if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable, success)) {
continue; continue;
} }
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) { if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable, success)) {
const SubstitutionLookupRecord *substLookupRecordArray = LEReferenceToArrayOf<SubstitutionLookupRecord>
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1]; substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
...@@ -547,7 +589,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -547,7 +589,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
return 0; return 0;
} }
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode & success) const LEErrorCode & success) const
...@@ -558,9 +600,13 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro ...@@ -558,9 +600,13 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); 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
const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]); 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_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]);
le_int32 position = glyphIterator->getCurrStreamPosition(); le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
...@@ -571,14 +617,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro ...@@ -571,14 +617,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
tempIterator.prev(); tempIterator.prev();
if (! ContextualSubstitutionBase::matchGlyphCoverages(backtrackCoverageTableOffsetArray, if (! ContextualSubstitutionBase::matchGlyphCoverages(backtrackCoverageTableOffsetArray,
backtrkGlyphCount, &tempIterator, (const char *) this, TRUE)) { backtrkGlyphCount, &tempIterator, base, success, TRUE)) {
return 0; return 0;
} }
tempIterator.setCurrStreamPosition(position); tempIterator.setCurrStreamPosition(position);
tempIterator.next(inputGlyphCount - 1); tempIterator.next(inputGlyphCount - 1);
if (! ContextualSubstitutionBase::matchGlyphCoverages(lookaheadCoverageTableOffsetArray, if (! ContextualSubstitutionBase::matchGlyphCoverages(lookaheadCoverageTableOffsetArray,
lookaheadGlyphCount, &tempIterator, (const char *) this)) { lookaheadGlyphCount, &tempIterator, base, success)) {
return 0; return 0;
} }
...@@ -589,9 +635,10 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro ...@@ -589,9 +635,10 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
glyphIterator->prev(); glyphIterator->prev();
if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray, if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray,
inputGlyphCount, glyphIterator, (const char *) this)) { inputGlyphCount, glyphIterator, base, success)) {
const SubstitutionLookupRecord *substLookupRecordArray = LEReferenceToArrayOf<SubstitutionLookupRecord>
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1]; substLookupRecordArray(base, success,
(const SubstitutionLookupRecord *) lookaheadCoverageTableOffsetArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
......
...@@ -56,20 +56,32 @@ struct SubstitutionLookupRecord ...@@ -56,20 +56,32 @@ struct SubstitutionLookupRecord
struct ContextualSubstitutionBase : GlyphSubstitutionSubtable struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
{ {
static le_bool matchGlyphIDs( 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); le_bool backtrack = FALSE);
static le_bool matchGlyphClasses( static le_bool matchGlyphClasses(
const le_uint16 *classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator, const LEReferenceToArrayOf<le_uint16> &classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable, le_bool backtrack = FALSE); const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable, LEErrorCode &success, le_bool backtrack = FALSE);
static le_bool matchGlyphCoverages(
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( static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount, const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack = FALSE); 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( static void applySubstitutionLookups(
const LookupProcessor *lookupProcessor, const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray, const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount, le_uint16 substCount,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
...@@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable ...@@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase 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 struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
...@@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable ...@@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint16 subRuleSetCount; le_uint16 subRuleSetCount;
Offset subRuleSetTableOffsetArray[ANY_NUMBER]; 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) LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
...@@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable ...@@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint16 subClassSetCount; le_uint16 subClassSetCount;
Offset subClassSetTableOffsetArray[ANY_NUMBER]; 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) LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
...@@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable ...@@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable
Offset coverageTableOffsetArray[ANY_NUMBER]; Offset coverageTableOffsetArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecord[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) LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase 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 struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
...@@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit ...@@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint16 chainSubRuleSetCount; le_uint16 chainSubRuleSetCount;
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER]; 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) LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
...@@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit ...@@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint16 chainSubClassSetCount; le_uint16 chainSubClassSetCount;
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER]; 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) LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
...@@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable ...@@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
//le_uint16 substCount; //le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecord[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(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray) LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
......
...@@ -37,8 +37,10 @@ ...@@ -37,8 +37,10 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const le_int32 CoverageTable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return -1;
switch(SWAPW(coverageFormat)) switch(SWAPW(coverageFormat))
{ {
case 0: case 0:
...@@ -46,16 +48,16 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -46,16 +48,16 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
case 1: case 1:
{ {
const CoverageFormat1Table *f1Table = (const CoverageFormat1Table *) this; LEReferenceTo<CoverageFormat1Table> f1Table(base, success);
return f1Table->getGlyphCoverage(glyphID); return f1Table->getGlyphCoverage(f1Table, glyphID, success);
} }
case 2: case 2:
{ {
const CoverageFormat2Table *f2Table = (const CoverageFormat2Table *) this; LEReferenceTo<CoverageFormat2Table> f2Table(base, success);
return f2Table->getGlyphCoverage(glyphID); return f2Table->getGlyphCoverage(f2Table, glyphID, success);
} }
default: default:
...@@ -63,8 +65,10 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -63,8 +65,10 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
} }
} }
le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const le_int32 CoverageFormat1Table::getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return -1;
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 count = SWAPW(glyphCount); le_uint16 count = SWAPW(glyphCount);
le_uint8 bit = OpenTypeUtilities::highBit(count); le_uint8 bit = OpenTypeUtilities::highBit(count);
...@@ -77,6 +81,10 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -77,6 +81,10 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
return -1; return -1;
} }
LEReferenceToArrayOf<TTGlyphID>(base, success, glyphArray, count);
if(LE_FAILURE(success)) return -1; // range checks array
if (SWAPW(glyphArray[extra]) <= ttGlyphID) { if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
index = extra; index = extra;
} }
...@@ -96,14 +104,18 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -96,14 +104,18 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
return -1; return -1;
} }
le_int32 CoverageFormat2Table::getGlyphCoverage(LEGlyphID glyphID) const le_int32 CoverageFormat2Table::getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return -1;
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 count = SWAPW(rangeCount); le_uint16 count = SWAPW(rangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> rangeRecordArrayRef(base, success, rangeRecordArray, count);
le_int32 rangeIndex = le_int32 rangeIndex =
OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArray, count); OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArrayRef, success);
if (rangeIndex < 0) { if (rangeIndex < 0 || LE_FAILURE(success)) { // could fail if array out of bounds
return -1; return -1;
} }
......
...@@ -46,7 +46,7 @@ struct CoverageTable ...@@ -46,7 +46,7 @@ struct CoverageTable
{ {
le_uint16 coverageFormat; le_uint16 coverageFormat;
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
}; };
struct CoverageFormat1Table : CoverageTable struct CoverageFormat1Table : CoverageTable
...@@ -54,7 +54,7 @@ struct CoverageFormat1Table : CoverageTable ...@@ -54,7 +54,7 @@ struct CoverageFormat1Table : CoverageTable
le_uint16 glyphCount; le_uint16 glyphCount;
TTGlyphID glyphArray[ANY_NUMBER]; TTGlyphID glyphArray[ANY_NUMBER];
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(CoverageFormat1Table, glyphArray) LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
...@@ -64,7 +64,7 @@ struct CoverageFormat2Table : CoverageTable ...@@ -64,7 +64,7 @@ struct CoverageFormat2Table : CoverageTable
le_uint16 rangeCount; le_uint16 rangeCount;
GlyphRangeRecord rangeRecordArray[ANY_NUMBER]; GlyphRangeRecord rangeRecordArray[ANY_NUMBER];
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray) LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
......
...@@ -51,23 +51,27 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachme ...@@ -51,23 +51,27 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachme
} }
LEPoint entryAnchor, exitAnchor; LEPoint entryAnchor, exitAnchor;
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor); Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
if (entryOffset != 0) { if (entryOffset != 0) {
const AnchorTable *entryAnchorTable = (const AnchorTable *) ((char *) this + entryOffset); LEReferenceTo<AnchorTable> entryAnchorTable(base, success, entryOffset);
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor); if( LE_SUCCESS(success) ) {
entryAnchorTable->getAnchor(entryAnchorTable, glyphID, fontInstance, entryAnchor, success);
glyphIterator->setCursiveEntryPoint(entryAnchor); glyphIterator->setCursiveEntryPoint(entryAnchor);
}
} else { } else {
//glyphIterator->clearCursiveEntryPoint(); //glyphIterator->clearCursiveEntryPoint();
} }
if (exitOffset != 0) { if (exitOffset != 0) {
const AnchorTable *exitAnchorTable = (const AnchorTable *) ((char *) this + exitOffset); LEReferenceTo<AnchorTable> exitAnchorTable(base, success, exitOffset);
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor); if( LE_SUCCESS(success) ) {
exitAnchorTable->getAnchor(exitAnchorTable, glyphID, fontInstance, exitAnchor, success);
glyphIterator->setCursiveExitPoint(exitAnchor); glyphIterator->setCursiveExitPoint(exitAnchor);
}
} else { } else {
//glyphIterator->clearCursiveExitPoint(); //glyphIterator->clearCursiveExitPoint();
} }
......
...@@ -43,7 +43,7 @@ const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8}; ...@@ -43,7 +43,7 @@ const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
#define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits) #define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits)
le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const le_int16 DeviceTable::getAdjustment(const LEReferenceTo<DeviceTable>&base, le_uint16 ppem, LEErrorCode &success) const
{ {
le_uint16 start = SWAPW(startSize); le_uint16 start = SWAPW(startSize);
le_uint16 format = SWAPW(deltaFormat) - 1; le_uint16 format = SWAPW(deltaFormat) - 1;
...@@ -53,6 +53,13 @@ le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const ...@@ -53,6 +53,13 @@ le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
le_uint16 sizeIndex = ppem - start; le_uint16 sizeIndex = ppem - start;
le_uint16 bits = fieldBits[format]; le_uint16 bits = fieldBits[format];
le_uint16 count = 16 / bits; le_uint16 count = 16 / bits;
LEReferenceToArrayOf<le_uint16> deltaValuesRef(base, success, deltaValues, (sizeIndex / count));
if(LE_FAILURE(success)) {
return result;
}
le_uint16 word = SWAPW(deltaValues[sizeIndex / count]); le_uint16 word = SWAPW(deltaValues[sizeIndex / count]);
le_uint16 fieldIndex = sizeIndex % count; le_uint16 fieldIndex = sizeIndex % count;
le_uint16 shift = 16 - (bits * (fieldIndex + 1)); le_uint16 shift = 16 - (bits * (fieldIndex + 1));
......
...@@ -50,7 +50,7 @@ struct DeviceTable ...@@ -50,7 +50,7 @@ struct DeviceTable
le_uint16 deltaFormat; le_uint16 deltaFormat;
le_uint16 deltaValues[ANY_NUMBER]; le_uint16 deltaValues[ANY_NUMBER];
le_int16 getAdjustment(le_uint16 ppem) const; le_int16 getAdjustment(const LEReferenceTo<DeviceTable> &base, le_uint16 ppem, LEErrorCode &success) const;
private: private:
static const le_uint16 fieldMasks[]; static const le_uint16 fieldMasks[];
......
...@@ -48,7 +48,6 @@ le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thi ...@@ -48,7 +48,6 @@ le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thi
const LookupProcessor *lookupProcessor, le_uint16 lookupType, const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return 0; return 0;
} }
......
...@@ -52,8 +52,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable ...@@ -52,8 +52,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable
le_uint16 extensionLookupType; le_uint16 extensionLookupType;
le_uint32 extensionOffset; le_uint32 extensionOffset;
le_uint32 process(const LEReferenceTo<ExtensionSubtable> &extRef, le_uint32 process(const LEReferenceTo<ExtensionSubtable> &base, const LookupProcessor *lookupProcessor, le_uint16 lookupType,
const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
......
...@@ -49,9 +49,9 @@ GDEFMarkFilter::~GDEFMarkFilter() ...@@ -49,9 +49,9 @@ GDEFMarkFilter::~GDEFMarkFilter()
// nothing to do? // nothing to do?
} }
le_bool GDEFMarkFilter::accept(LEGlyphID glyph) const le_bool GDEFMarkFilter::accept(LEGlyphID glyph, LEErrorCode &success) const
{ {
le_int32 glyphClass = classDefTable->getGlyphClass(glyph); le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
return glyphClass == gcdMarkGlyph; return glyphClass == gcdMarkGlyph;
} }
......
...@@ -55,7 +55,7 @@ public: ...@@ -55,7 +55,7 @@ public:
GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success); GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~GDEFMarkFilter(); virtual ~GDEFMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const; virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -41,14 +41,13 @@ ...@@ -41,14 +41,13 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader) FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success)
: direction(1), position(-1), nextLimit(-1), prevLimit(-1), : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
glyphClassDefinitionTable(), markAttachClassDefinitionTable() glyphClassDefinitionTable(), markAttachClassDefinitionTable()
{ {
LEErrorCode success = LE_NO_ERROR; // TODO
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
if (theGlyphDefinitionTableHeader.isValid()) { if (theGlyphDefinitionTableHeader.isValid()) {
...@@ -388,7 +387,7 @@ void GlyphIterator::setCursiveGlyph() ...@@ -388,7 +387,7 @@ void GlyphIterator::setCursiveGlyph()
void GlyphIterator::filterResetCache(void) { void GlyphIterator::filterResetCache(void) {
filterCacheValid = FALSE; filterCacheValid = FALSE;
} }
le_bool GlyphIterator::filterGlyph(le_uint32 index) le_bool GlyphIterator::filterGlyph(le_uint32 index)
{ {
......
...@@ -49,7 +49,7 @@ class GlyphPositionAdjustments; ...@@ -49,7 +49,7 @@ class GlyphPositionAdjustments;
class GlyphIterator : public UMemory { class GlyphIterator : public UMemory {
public: public:
GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader); FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success);
GlyphIterator(GlyphIterator &that); GlyphIterator(GlyphIterator &that);
......
...@@ -95,6 +95,8 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo ...@@ -95,6 +95,8 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
le_uint32 delta = 0; le_uint32 delta = 0;
//_LETRACE("attempting lookupType #%d", lookupType);
switch(lookupType) switch(lookupType)
{ {
case 0: case 0:
...@@ -152,21 +154,21 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo ...@@ -152,21 +154,21 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
{ {
LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success); LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this , glyphIterator, fontInstance, success);
break; break;
} }
case gpstChainedContext: case gpstChainedContext:
{ {
LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break; break;
} }
case gpstExtension: case gpstExtension:
{ {
LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success);
break; break;
...@@ -176,6 +178,12 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo ...@@ -176,6 +178,12 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
break; break;
} }
#if LE_TRACE
if(delta != 0) {
_LETRACE("GlyphPositioningLookupProcessor applied #%d -> delta %d @ %d", lookupType, delta, glyphIterator->getCurrStreamPosition());
}
#endif
return delta; return delta;
} }
......
...@@ -123,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo ...@@ -123,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
{ {
const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break; break;
} }
...@@ -131,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo ...@@ -131,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
{ {
const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break; break;
} }
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "LEGlyphStorage.h" #include "LEGlyphStorage.h"
#include "IndicReordering.h" #include "IndicReordering.h"
#include <stdio.h>
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
...@@ -90,6 +90,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_ ...@@ -90,6 +90,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
return 0; return 0;
} }
_LETRACE("IOTLE::gp, calling parent");
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success); le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
...@@ -97,10 +98,14 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_ ...@@ -97,10 +98,14 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
} }
if (fVersion2) { if (fVersion2) {
_LETRACE("IOTLE::gp, v2 final,");
IndicReordering::finalReordering(glyphStorage,retCount); IndicReordering::finalReordering(glyphStorage,retCount);
_LETRACE("IOTLE::gp, v2 pres");
IndicReordering::applyPresentationForms(glyphStorage,retCount); IndicReordering::applyPresentationForms(glyphStorage,retCount);
_LETRACE("IOTLE::gp, parent gsub");
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success); OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
} else { } else {
_LETRACE("IOTLE::gp, adjust mpres");
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success); IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
} }
return retCount; return retCount;
...@@ -116,6 +121,8 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], ...@@ -116,6 +121,8 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
return 0; return 0;
} }
_LETRACE("IOTLE: charProc");
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
success = LE_ILLEGAL_ARGUMENT_ERROR; success = LE_ILLEGAL_ARGUMENT_ERROR;
return 0; return 0;
...@@ -143,8 +150,10 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], ...@@ -143,8 +150,10 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
le_int32 outCharCount; le_int32 outCharCount;
if (fVersion2) { if (fVersion2) {
_LETRACE("v2process");
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage); outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
} else { } else {
_LETRACE("reorder");
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success); outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <stdio.h> #include <stdio.h>
#define DEBUG 0 #define DEBUG_KERN_TABLE 0
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success) ...@@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
: pairsSwapped(NULL), fTable(base) : pairsSwapped(NULL), fTable(base)
{ {
if(LE_FAILURE(success) || (fTable.isEmpty())) { if(LE_FAILURE(success) || (fTable.isEmpty())) {
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stderr, "no kern data\n"); fprintf(stderr, "no kern data\n");
#endif #endif
return; return;
} }
LEReferenceTo<KernTableHeader> header(fTable, success); LEReferenceTo<KernTableHeader> header(fTable, success);
#if DEBUG #if DEBUG_KERN_TABLE
// dump first 32 bytes of header // dump first 32 bytes of header
for (int i = 0; i < 64; ++i) { for (int i = 0; i < 64; ++i) {
fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff); fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
...@@ -171,13 +171,13 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success) ...@@ -171,13 +171,13 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift); fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift)); fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
#endif #endif
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped); fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped);
fprintf(stderr, fprintf(stderr,
" searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n", " searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n",
searchRange, entrySelector, rangeShift); searchRange, entrySelector, rangeShift);
{ if (LE_SUCCESS(success)) {
// dump part of the pair list // dump part of the pair list
char ids[256]; char ids[256];
for (int i = 256; --i >= 0;) { for (int i = 256; --i >= 0;) {
...@@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success) ...@@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
p = tp; p = tp;
} }
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stderr, "binary search for %0.8x\n", key); fprintf(stderr, "binary search for %0.8x\n", key);
#endif #endif
...@@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success) ...@@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
probe >>= 1; probe >>= 1;
tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE)); tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
le_uint32 tkey = tp->key; le_uint32 tkey = tp->key;
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey); fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
#endif #endif
if (tkey <= key) { if (tkey <= key) {
if (tkey == key) { if (tkey == key) {
le_int16 value = SWAPW(tp->value); le_int16 value = SWAPW(tp->value);
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n", fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value)); storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
fflush(stdout); fflush(stdout);
......
...@@ -181,6 +181,10 @@ public: ...@@ -181,6 +181,10 @@ public:
* *
* Subclasses which represent composite fonts should always return <code>NULL</code>. * Subclasses which represent composite fonts should always return <code>NULL</code>.
* *
* Note that implementing this function does not allow for range checking.
* Subclasses that desire the safety of range checking must implement the
* variation which has a length parameter.
*
* @param tableTag - the four byte table tag. (e.g. 'cmap') * @param tableTag - the four byte table tag. (e.g. 'cmap')
* *
* @return the address of the table in memory, or <code>NULL</code> * @return the address of the table in memory, or <code>NULL</code>
...@@ -200,6 +204,8 @@ public: ...@@ -200,6 +204,8 @@ public:
* Subclasses which represent composite fonts should always return <code>NULL</code>. * Subclasses which represent composite fonts should always return <code>NULL</code>.
* *
* This version sets a length, for range checking. * This version sets a length, for range checking.
* Note that range checking can only be accomplished if this function is
* implemented in subclasses.
* *
* @param tableTag - the four byte table tag. (e.g. 'cmap') * @param tableTag - the four byte table tag. (e.g. 'cmap')
* @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown. * @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown.
...@@ -572,5 +578,3 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat) ...@@ -572,5 +578,3 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -62,7 +62,7 @@ public: ...@@ -62,7 +62,7 @@ public:
* *
* @internal * @internal
*/ */
virtual le_bool accept(LEGlyphID glyph) const = 0; virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const = 0;
}; };
#endif /* U_HIDE_INTERNAL_API */ #endif /* U_HIDE_INTERNAL_API */
......
...@@ -458,7 +458,7 @@ void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorC ...@@ -458,7 +458,7 @@ void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorC
success = LE_INDEX_OUT_OF_BOUNDS_ERROR; success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
return; return;
} }
_LETRACE("set%-4d\t(%.2f, %.2f)", glyphIndex, x, y);
fPositions[glyphIndex * 2] = x; fPositions[glyphIndex * 2] = x;
fPositions[glyphIndex * 2 + 1] = y; fPositions[glyphIndex * 2 + 1] = y;
} }
...@@ -694,4 +694,3 @@ le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGl ...@@ -694,4 +694,3 @@ le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGl
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -568,4 +568,3 @@ inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const ...@@ -568,4 +568,3 @@ inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING. * YOU REALLY KNOW WHAT YOU'RE DOING.
* *
* Generated on: 10/26/2010 02:53:33 PM PDT * Generated on: 11/01/2011 04:08:09 PM PDT
*/ */
#ifndef __LESCRIPTS_H #ifndef __LESCRIPTS_H
...@@ -262,7 +262,16 @@ enum ScriptCodes { ...@@ -262,7 +262,16 @@ enum ScriptCodes {
khojScriptCode = 157, khojScriptCode = 157,
tirhScriptCode = 158, tirhScriptCode = 158,
scriptCodeCount = 159 /**
* @stable ICU 52
*/
aghbScriptCode = 159,
mahjScriptCode = 160,
/**
* @stable ICU 2.2
*/
scriptCodeCount
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -132,6 +132,9 @@ enum LEErrorCode { ...@@ -132,6 +132,9 @@ enum LEErrorCode {
#define uprv_memcpy memcpy #define uprv_memcpy memcpy
#define uprv_realloc realloc #define uprv_realloc realloc
#define U_EXPORT2
#define U_CAPI extern "C"
#if !defined(U_IS_BIG_ENDIAN) #if !defined(U_IS_BIG_ENDIAN)
#ifdef _LITTLE_ENDIAN #ifdef _LITTLE_ENDIAN
#define U_IS_BIG_ENDIAN 0 #define U_IS_BIG_ENDIAN 0
......
...@@ -37,34 +37,47 @@ ...@@ -37,34 +37,47 @@
#include "LETypes.h" #include "LETypes.h"
#include "LEFontInstance.h" #include "LEFontInstance.h"
/**
* \def LE_ENABLE_RAW
* If this is 1, enables old non-safe raw access
*/
#ifndef LE_ENABLE_RAW
#define LE_ENABLE_RAW 0
#endif
#define kQuestionmarkTableTag 0x3F3F3F3FUL #define kQuestionmarkTableTag 0x3F3F3F3FUL /* ???? */
#define kTildeTableTag 0x7e7e7e7eUL #define kStaticTableTag 0x30303030UL /* 0000 */
#define kTildeTableTag 0x7e7e7e7eUL /* ~~~~ */
#ifdef __cplusplus #ifdef __cplusplus
// internal - interface for range checking // internal - interface for range checking
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
#if LE_ASSERT_BAD_FONT #if LE_ASSERT_BAD_FONT
#ifndef LE_TRACE_TR
#define LE_TRACE_TR 0
#endif
class LETableReference; // fwd class LETableReference; // fwd
/** /**
* defined in OpenTypeUtilities.cpp * defined in OpenTypeUtilities.cpp
* @internal * @internal
*/ */
extern void _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len); U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0); #define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z); #define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
#if 0 #if LE_TRACE_TR
#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0); #define _TRTRACE(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#else #else
#define LE_TRACE_TR(x) #define _TRTRACE(x)
#endif #endif
#else #else
#define LE_DEBUG_TR(x) #define LE_DEBUG_TR(x)
#define LE_DEBUG_TR3(x,y,z) #define LE_DEBUG_TR3(x,y,z)
#define LE_TRACE_TR(x) #define _TRTRACE(x)
#endif #endif
/** /**
...@@ -72,6 +85,13 @@ extern void _debug_LETableReference(const char *f, int l, const char *msg, const ...@@ -72,6 +85,13 @@ extern void _debug_LETableReference(const char *f, int l, const char *msg, const
*/ */
class LETableReference { class LETableReference {
public: public:
/**
* Dummy enum asserting that a value is actually static data
* and does not need to be range checked
*/
enum EStaticData { kStaticData = 0 };
/** /**
* @internal * @internal
* Construct from a specific tag * Construct from a specific tag
...@@ -79,28 +99,42 @@ public: ...@@ -79,28 +99,42 @@ public:
LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) : LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) { fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
loadTable(success); loadTable(success);
LE_TRACE_TR("INFO: new table load") _TRTRACE("INFO: new table load")
} }
LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) { LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
if(LE_FAILURE(success)) { if(LE_FAILURE(success)) {
clear(); clear();
} }
LE_TRACE_TR("INFO: new clone") _TRTRACE("INFO: new clone")
} }
#if LE_ENABLE_RAW
/**
* Construct without a parent LETR.
*/
LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) : LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) { fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
LE_TRACE_TR("INFO: new raw") _TRTRACE("INFO: new raw")
} }
#endif
/**
* Construct without a parent LETR.
*/
LETableReference(EStaticData /* NOTUSED */, const le_uint8* data, size_t length) :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
_TRTRACE("INFO: new EStaticData")
}
LETableReference() : LETableReference() :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) { fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
LE_TRACE_TR("INFO: new empty") _TRTRACE("INFO: new empty")
} }
~LETableReference() { ~LETableReference() {
fTag=kTildeTableTag; fTag= (LETag)kTildeTableTag;
LE_TRACE_TR("INFO: new dtor") _TRTRACE("INFO: new dtor")
} }
/** /**
...@@ -126,7 +160,7 @@ public: ...@@ -126,7 +160,7 @@ public:
fLength = (fParent->fLength) - offset; // decrement length as base address is incremented fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
} }
if(fLength != LE_UINTPTR_MAX) { // if we have bounds: if(fLength != LE_UINTPTR_MAX) { // if we have bounds:
if(offset+fLength > fParent->fLength) { if((offset+fLength < offset) || (offset+fLength > fParent->fLength)) {
LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength); LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
clear(); clear();
...@@ -136,11 +170,13 @@ public: ...@@ -136,11 +170,13 @@ public:
} else { } else {
clear(); clear();
} }
LE_TRACE_TR("INFO: new subset") _TRTRACE("INFO: new subset")
} }
const void* getAlias() const { return (const void*)fStart; } const void* getAlias() const { return (const void*)fStart; }
const void* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); return (const void*)fStart; } #ifndef LE_ENABLE_RAW
const void* getAliasRAW() const { LE_DEBUG_TR("getAliasRAW()"); return (const void*)fStart; }
#endif
le_bool isEmpty() const { return fStart==NULL || fLength==0; } le_bool isEmpty() const { return fStart==NULL || fLength==0; }
le_bool isValid() const { return !isEmpty(); } le_bool isValid() const { return !isEmpty(); }
le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; } le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
...@@ -233,7 +269,18 @@ protected: ...@@ -233,7 +269,18 @@ protected:
void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) { void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
fFont = NULL; fFont = NULL;
fTag = kQuestionmarkTableTag; fTag = (LETag)kQuestionmarkTableTag;
fParent = NULL;
fStart = (const le_uint8*)data;
fLength = length;
}
/**
* set this object pointing to static data
*/
void setTo(EStaticData /*notused*/, const void *data, size_t length) {
fFont = NULL;
fTag = (LETag)kStaticTableTag;
fParent = NULL; fParent = NULL;
fStart = (const le_uint8*)data; fStart = (const le_uint8*)data;
fLength = length; fLength = length;
...@@ -276,6 +323,90 @@ size_t LETableVarSizer<T>::getSize() { ...@@ -276,6 +323,90 @@ size_t LETableVarSizer<T>::getSize() {
* Open a new entry based on an existing table * Open a new entry based on an existing table
*/ */
template<class T>
class LEReferenceTo : public LETableReference {
public:
/**
* open a sub reference.
* @param parent parent reference
* @param success error status
* @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds.
*/
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr)
: LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
/**
* ptr plus offset
*/
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset)
: LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset)
: LETableReference(parent, offset, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
: LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
: LETableReference(font, tableTag, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
#if LE_ENABLE_RAW
inline LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
inline LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
#endif
inline LEReferenceTo(EStaticData staticData, const le_uint8 *data, size_t length) : LETableReference(staticData, data, length) {}
inline LEReferenceTo(EStaticData staticData, const T *data, size_t length) : LETableReference(staticData, (const le_uint8*)data, length) {}
inline LEReferenceTo() : LETableReference() {}
#if LE_ENABLE_RAW
inline LEReferenceTo<T>& operator=(const T* other) {
setRaw(other);
return *this;
}
#endif
LEReferenceTo<T>& setTo(LETableReference::EStaticData staticData, const T* other, size_t length) {
LETableReference::setTo(staticData, other, length);
return *this;
}
LEReferenceTo<T> &reparent(const LETableReference &base) {
fParent = &base;
return *this;
}
/**
* roll forward by one <T> size.
* same as addOffset(LETableVarSizer<T>::getSize(),success)
*/
void addObject(LEErrorCode &success) {
addOffset(LETableVarSizer<T>::getSize(), success);
}
void addObject(size_t count, LEErrorCode &success) {
addOffset(LETableVarSizer<T>::getSize()*count, success);
}
const T *operator->() const { return getAlias(); }
const T *operator*() const { return getAlias(); }
const T *getAlias() const { return (const T*)fStart; }
#if LE_ENABLE_RAW
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
#endif
};
/** /**
* \def LE_UNBOUNDED_ARRAY * \def LE_UNBOUNDED_ARRAY
* define an array with no *known* bound. Will trim to available size. * define an array with no *known* bound. Will trim to available size.
...@@ -288,12 +419,12 @@ class LEReferenceToArrayOf : public LETableReference { ...@@ -288,12 +419,12 @@ class LEReferenceToArrayOf : public LETableReference {
public: public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count) LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
: LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) { : LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO by offset") _TRTRACE("INFO: new RTAO by offset")
if(LE_SUCCESS(success)) { if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
} }
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
} }
if(LE_FAILURE(success)) { if(LE_FAILURE(success)) {
fCount=0; fCount=0;
...@@ -303,23 +434,23 @@ public: ...@@ -303,23 +434,23 @@ public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count) LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
: LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) { : LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO") _TRTRACE("INFO: new RTAO")
if(LE_SUCCESS(success)) { if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
} }
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
} }
if(LE_FAILURE(success)) clear(); if(LE_FAILURE(success)) clear();
} }
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count) LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
: LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) { : LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO") _TRTRACE("INFO: new RTAO")
if(LE_SUCCESS(success)) { if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
} }
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
} }
if(LE_FAILURE(success)) clear(); if(LE_FAILURE(success)) clear();
} }
...@@ -328,18 +459,40 @@ LE_TRACE_TR("INFO: new RTAO") ...@@ -328,18 +459,40 @@ LE_TRACE_TR("INFO: new RTAO")
le_uint32 getCount() const { return fCount; } le_uint32 getCount() const { return fCount; }
using LETableReference::getAlias; const T *getAlias() const { return (const T*)fStart; }
const T *getAlias(le_uint32 i, LEErrorCode &success) const { const T *getAlias(le_uint32 i, LEErrorCode &success) const {
return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success))); return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
} }
const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; } #ifndef LE_ENABLE_RAW
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
#endif
const T& getObject(le_uint32 i, LEErrorCode &success) const { const T& getObject(le_uint32 i, LEErrorCode &success) const {
return *getAlias(i,success); return *getAlias(i,success);
} }
/**
* by-value array accessor for integral types.
*/
const T operator[](le_uint32 i) const {
LEErrorCode success = LE_NO_ERROR;
const T *ret = getAlias(i, success);
if(LE_FAILURE(success) || ret==NULL) {
#if LE_ASSERT_BAD_FONT
LE_DEBUG_TR3("Range error, out of bounds? (%p) #%d", NULL, i);
#endif
return T(0); // will not work for all types.
}
return *ret;
}
const LEReferenceTo<T> getReference(le_uint32 i, LEErrorCode &success) const {
if(LE_FAILURE(success)) return LEReferenceTo<T>();
return LEReferenceTo<T>(*this, success, getAlias(i,success));
}
const T& operator()(le_uint32 i, LEErrorCode &success) const { const T& operator()(le_uint32 i, LEErrorCode &success) const {
return *getAlias(i,success); return *getAlias(i,success);
} }
...@@ -348,6 +501,7 @@ LE_TRACE_TR("INFO: new RTAO") ...@@ -348,6 +501,7 @@ LE_TRACE_TR("INFO: new RTAO")
if(LE_SUCCESS(success)&&i<getCount()) { if(LE_SUCCESS(success)&&i<getCount()) {
return LETableVarSizer<T>::getSize()*i; return LETableVarSizer<T>::getSize()*i;
} else { } else {
LE_DEBUG_TR3("getOffsetFor failed (%p) index=%d",NULL, i);
success = LE_INDEX_OUT_OF_BOUNDS_ERROR; success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
} }
return 0; return 0;
...@@ -359,7 +513,7 @@ LE_TRACE_TR("INFO: new RTAO") ...@@ -359,7 +513,7 @@ LE_TRACE_TR("INFO: new RTAO")
} }
LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) { LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
LE_TRACE_TR("INFO: null RTAO") _TRTRACE("INFO: null RTAO")
} }
private: private:
...@@ -367,73 +521,11 @@ private: ...@@ -367,73 +521,11 @@ private:
}; };
template<class T>
class LEReferenceTo : public LETableReference {
public:
/**
* open a sub reference.
* @param parent parent reference
* @param success error status
* @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds.
*/
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr)
: LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
/**
* ptr plus offset
*/
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset)
: LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset)
: LETableReference(parent, offset, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
: LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
: LETableReference(font, tableTag, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
inline LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
inline LEReferenceTo() : LETableReference(NULL) {}
inline LEReferenceTo<T>& operator=(const T* other) {
setRaw(other);
return *this;
}
LEReferenceTo<T> &reparent(const LETableReference &base) {
fParent = &base;
return *this;
}
/**
* roll forward by one <T> size.
* same as addOffset(LETableVarSizer<T>::getSize(),success)
*/
void addObject(LEErrorCode &success) {
addOffset(LETableVarSizer<T>::getSize(), success);
}
void addObject(size_t count, LEErrorCode &success) {
addOffset(LETableVarSizer<T>::getSize()*count, success);
}
const T *operator->() const { return getAlias(); }
const T *getAlias() const { return (const T*)fStart; }
const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
};
#ifdef _TRTRACE
#undef _TRTRACE
#endif
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -337,6 +337,20 @@ struct LEPoint ...@@ -337,6 +337,20 @@ struct LEPoint
typedef struct LEPoint LEPoint; typedef struct LEPoint LEPoint;
#endif #endif
/**
* \def LE_TRACE
* @internal
*/
#ifndef LE_TRACE
# define LE_TRACE 0
#endif
#if LE_TRACE
# include <stdio.h>
# define _LETRACE printf("\n%s:%d: LE: ", __FILE__, __LINE__),printf
#else
# define _LETRACE 0&&
#endif
#ifndef U_HIDE_INTERNAL_API #ifndef U_HIDE_INTERNAL_API
...@@ -701,6 +715,12 @@ enum LEFeatureENUMs { ...@@ -701,6 +715,12 @@ enum LEFeatureENUMs {
LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM
}; };
/**
* Flags for typographic features.
* @internal
* @{
*/
#define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM) #define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM)
#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM) #define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM) #define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM)
...@@ -727,6 +747,9 @@ enum LEFeatureENUMs { ...@@ -727,6 +747,9 @@ enum LEFeatureENUMs {
#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM) #define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM)
#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM) #define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM)
/**
* @}
*/
#define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */ #define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */
...@@ -768,7 +791,7 @@ typedef enum LEErrorCode LEErrorCode; ...@@ -768,7 +791,7 @@ typedef enum LEErrorCode LEErrorCode;
* *
* @stable ICU 2.4 * @stable ICU 2.4
*/ */
#ifndef LE_FAILURE #ifndef LE_SUCCESS
#define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code)) #define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code))
#endif #endif
...@@ -781,4 +804,4 @@ typedef enum LEErrorCode LEErrorCode; ...@@ -781,4 +804,4 @@ typedef enum LEErrorCode LEErrorCode;
#define LE_FAILURE(code) (U_FAILURE((UErrorCode)code)) #define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
#endif #endif
#endif /* __LETYPES_H */ #endif
...@@ -156,7 +156,7 @@ public: ...@@ -156,7 +156,7 @@ public:
CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success); CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~CanonMarkFilter(); virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const; virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
}; };
CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success) CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
...@@ -169,9 +169,8 @@ CanonMarkFilter::~CanonMarkFilter() ...@@ -169,9 +169,8 @@ CanonMarkFilter::~CanonMarkFilter()
// nothing to do? // nothing to do?
} }
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const le_bool CanonMarkFilter::accept(LEGlyphID glyph, LEErrorCode &success) const
{ {
LEErrorCode success = LE_NO_ERROR;
le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success); le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
if(LE_FAILURE(success)) return false; if(LE_FAILURE(success)) return false;
return glyphClass != 0; return glyphClass != 0;
...@@ -207,7 +206,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, ...@@ -207,7 +206,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
fGlyphStorage = new LEGlyphStorage(); fGlyphStorage = new LEGlyphStorage();
if (fGlyphStorage == NULL) { if (fGlyphStorage == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
} }
} }
le_int32 LayoutEngine::getGlyphCount() const le_int32 LayoutEngine::getGlyphCount() const
...@@ -263,7 +262,9 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -263,7 +262,9 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return count; return count;
} }
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable); LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable(LETableReference::kStaticData,
(GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable,
CanonShaping::glyphSubstitutionTableLen);
LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
le_int32 i, dir = 1, out = 0, outCharCount = count; le_int32 i, dir = 1, out = 0, outCharCount = count;
...@@ -323,7 +324,8 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -323,7 +324,8 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
LE_DELETE_ARRAY(reordered); LE_DELETE_ARRAY(reordered);
} }
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); const LEReferenceTo<GlyphDefinitionTableHeader> noGDEF; // empty gdef header
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, noGDEF, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
delete substitutionFilter; delete substitutionFilter;
...@@ -403,10 +405,13 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y ...@@ -403,10 +405,13 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y
LEPoint advance; LEPoint advance;
glyphStorage.setPosition(i, x, y, success); glyphStorage.setPosition(i, x, y, success);
_LETRACE("g#%-4d (%.2f, %.2f)", i, x, y);
fFontInstance->getGlyphAdvance(glyphStorage[i], advance); fFontInstance->getGlyphAdvance(glyphStorage[i], advance);
x += advance.fX; x += advance.fX;
y += advance.fY; y += advance.fY;
} }
glyphStorage.setPosition(glyphCount, x, y, success); glyphStorage.setPosition(glyphCount, x, y, success);
...@@ -424,7 +429,7 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset ...@@ -424,7 +429,7 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
return; return;
} }
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen); CanonShaping::glyphDefinitionTableLen);
CanonMarkFilter filter(gdefTable, success); CanonMarkFilter filter(gdefTable, success);
...@@ -464,9 +469,10 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter ...@@ -464,9 +469,10 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter
glyphStorage.getGlyphPosition(p + 1, next, ignore, success); glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
xAdvance = next - prev; xAdvance = next - prev;
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
glyphStorage.adjustPosition(p, xAdjust, 0, success); glyphStorage.adjustPosition(p, xAdjust, 0, success);
if (markFilter->accept(glyphStorage[p])) { if (markFilter->accept(glyphStorage[p], success)) {
xAdjust -= xAdvance; xAdjust -= xAdvance;
} }
...@@ -506,9 +512,13 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, ...@@ -506,9 +512,13 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
glyphStorage.getGlyphPosition(p + 1, next, ignore, success); glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
xAdvance = next - prev; xAdvance = next - prev;
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
glyphStorage.adjustPosition(p, xAdjust, 0, success); glyphStorage.adjustPosition(p, xAdjust, 0, success);
if (markFilter->accept(chars[c])) { if (markFilter->accept(chars[c], success)) {
xAdjust -= xAdvance; xAdjust -= xAdvance;
} }
...@@ -662,8 +672,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -662,8 +672,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
break; break;
} }
} else { } else {
MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag); LEReferenceTo<MorphTableHeader2> morxTable(fontInstance, morxTableTag, success);
if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) { if (LE_SUCCESS(success) &&
morxTable.isValid() &&
SWAPL(morxTable->version)==0x00020000) {
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success); result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
} else { } else {
LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success); LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
...@@ -687,7 +699,6 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -687,7 +699,6 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
} }
case arabScriptCode: case arabScriptCode:
//case hebrScriptCode:
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
......
...@@ -156,8 +156,8 @@ protected: ...@@ -156,8 +156,8 @@ protected:
* @param fontInstance - the font for the text * @param fontInstance - the font for the text
* @param scriptCode - the script for the text * @param scriptCode - the script for the text
* @param languageCode - the language for the text * @param languageCode - the language for the text
* @param typoFlags - the typographic control flags for the text. Set bit 1 if kerning * @param typoFlags - the typographic control flags for the text (a bitfield). Use kTypoFlagKern
* is desired, set bit 2 if ligature formation is desired. Others are reserved. * if kerning is desired, kTypoFlagLiga if ligature formation is desired. Others are reserved.
* @param success - set to an error code if the operation fails * @param success - set to an error code if the operation fails
* *
* @see LEFontInstance * @see LEFontInstance
......
...@@ -49,14 +49,20 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -49,14 +49,20 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
return 0; return 0;
} }
if (coverageIndex >= 0) { LEReferenceToArrayOf<Offset> ligSetTableOffsetArrayRef(base, success, ligSetTableOffsetArray, SWAPW(ligSetCount));
if (coverageIndex >= 0 && LE_SUCCESS(success) && (le_uint32)coverageIndex < ligSetTableOffsetArrayRef.getCount()) {
Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]); Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
const LigatureSetTable *ligSetTable = (const LigatureSetTable *) ((char *) this + ligSetTableOffset); LEReferenceTo<LigatureSetTable> ligSetTable(base, success, ligSetTableOffset);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount); le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount);
for (le_uint16 lig = 0; lig < ligCount; lig += 1) { LEReferenceTo<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount);
for (le_uint16 lig = 0; LE_SUCCESS(success) && lig < ligCount; lig += 1) {
Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]); Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]);
const LigatureTable *ligTable = (const LigatureTable *) ((char *)ligSetTable + ligTableOffset); LEReferenceTo<LigatureTable> ligTable(ligSetTable, success, ligTableOffset);
if(LE_FAILURE(success)) { return 0; }
le_uint16 compCount = SWAPW(ligTable->compCount) - 1; le_uint16 compCount = SWAPW(ligTable->compCount) - 1;
le_int32 startPosition = glyphIterator->getCurrStreamPosition(); le_int32 startPosition = glyphIterator->getCurrStreamPosition();
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph); TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
...@@ -72,7 +78,7 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -72,7 +78,7 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
} }
} }
if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph)))) { if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph), success))) {
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF; TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
......
...@@ -60,8 +60,10 @@ le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lo ...@@ -60,8 +60,10 @@ le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lo
LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success); LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success); delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
if (delta > 0 && LE_FAILURE(success)) {
if (delta > 0 || LE_FAILURE(success)) { #if LE_TRACE
_LETRACE("Posn #%d, type %X, applied subtable #%d/%d - %s\n", startPosition, lookupType, subtable, subtableCount, u_errorName((UErrorCode)success));
#endif
return 1; return 1;
} }
...@@ -86,7 +88,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -86,7 +88,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
} }
GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments, GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
rightToLeft, 0, 0, glyphDefinitionTableHeader); rightToLeft, 0, 0, glyphDefinitionTableHeader, success);
le_int32 newGlyphCount = glyphCount; le_int32 newGlyphCount = glyphCount;
for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) { for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
...@@ -94,6 +96,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -94,6 +96,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
FeatureMask selectMask = lookupSelectArray[lookup]; FeatureMask selectMask = lookupSelectArray[lookup];
if (selectMask != 0) { if (selectMask != 0) {
_LETRACE("Processing order#%d/%d", order, lookupOrderCount);
const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success); const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
if (!lookupTable.isValid() ||LE_FAILURE(success) ) { if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
continue; continue;
...@@ -103,8 +106,11 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -103,8 +106,11 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
glyphIterator.reset(lookupFlags, selectMask); glyphIterator.reset(lookupFlags, selectMask);
while (glyphIterator.findFeatureTag()) { while (glyphIterator.findFeatureTag()) {
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
#if LE_TRACE
_LETRACE("Failure for lookup 0x%x - %s\n", lookup, u_errorName((UErrorCode)success));
#endif
return 0; return 0;
} }
} }
...@@ -138,7 +144,7 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt ...@@ -138,7 +144,7 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success) le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success)
{ {
le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0; le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0;
le_int32 store = order; le_uint32 store = (le_uint32)order;
LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount); LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
...@@ -147,6 +153,9 @@ le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featu ...@@ -147,6 +153,9 @@ le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featu
if (lookupListIndex >= lookupSelectCount) { if (lookupListIndex >= lookupSelectCount) {
continue; continue;
} }
if (store >= lookupOrderCount) {
continue;
}
lookupSelectArray[lookupListIndex] |= featureMask; lookupSelectArray[lookupListIndex] |= featureMask;
lookupOrderArray[store++] = lookupListIndex; lookupOrderArray[store++] = lookupListIndex;
...@@ -246,7 +255,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress, ...@@ -246,7 +255,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
if (requiredFeatureIndex != 0xFFFF) { if (requiredFeatureIndex != 0xFFFF) {
requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success); requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
featureReferences += SWAPW(featureTable->lookupCount); featureReferences += SWAPW(requiredFeatureTable->lookupCount);
} }
lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences); lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
...@@ -254,6 +263,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress, ...@@ -254,6 +263,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
return; return;
} }
lookupOrderCount = featureReferences;
for (le_int32 f = 0; f < featureMapCount; f += 1) { for (le_int32 f = 0; f < featureMapCount; f += 1) {
FeatureMap fm = featureMap[f]; FeatureMap fm = featureMap[f];
......
...@@ -65,7 +65,7 @@ le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &b ...@@ -65,7 +65,7 @@ le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &b
if(LE_FAILURE(success)) return 0; if(LE_FAILURE(success)) return 0;
return coverageTable->getGlyphCoverage(glyphID); return coverageTable->getGlyphCoverage(coverageTable, glyphID, success);
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -38,20 +38,28 @@ ...@@ -38,20 +38,28 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 MarkArray::getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance, le_int32 MarkArray::getMarkClass(const LETableReference &base, LEGlyphID glyphID,
LEPoint &anchor) const le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{ {
le_int32 markClass = -1; le_int32 markClass = -1;
if (coverageIndex >= 0) { if ( coverageIndex >= 0 && LE_SUCCESS(success) ) {
le_uint16 mCount = SWAPW(markCount); le_uint16 mCount = SWAPW(markCount);
if (coverageIndex < mCount) { if (coverageIndex < mCount) {
LEReferenceToArrayOf<MarkRecord> markRecordArrayRef(base, success, markRecordArray, mCount);
if(LE_FAILURE(success)) {
return markClass;
}
const MarkRecord *markRecord = &markRecordArray[coverageIndex]; const MarkRecord *markRecord = &markRecordArray[coverageIndex];
Offset anchorTableOffset = SWAPW(markRecord->markAnchorTableOffset); Offset anchorTableOffset = SWAPW(markRecord->markAnchorTableOffset);
const AnchorTable *anchorTable = (AnchorTable *) ((char *) this + anchorTableOffset); LEReferenceTo<AnchorTable> anchorTable(base, success, anchorTableOffset);
if(LE_FAILURE(success)) {
return markClass;
}
anchorTable->getAnchor(glyphID, fontInstance, anchor); anchorTable->getAnchor(anchorTable, glyphID, fontInstance, anchor, success);
markClass = SWAPW(markRecord->markClass); markClass = SWAPW(markRecord->markClass);
} }
......
...@@ -54,8 +54,9 @@ struct MarkArray ...@@ -54,8 +54,9 @@ struct MarkArray
le_uint16 markCount; le_uint16 markCount;
MarkRecord markRecordArray[ANY_NUMBER]; MarkRecord markRecordArray[ANY_NUMBER];
le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance, le_int32 getMarkClass(const LETableReference &base, LEGlyphID glyphID,
LEPoint &anchor) const; le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(MarkArray, markRecordArray) LE_VAR_ARRAY(MarkArray, markRecordArray)
......
...@@ -66,11 +66,11 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -66,11 +66,11 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
} }
LEPoint markAnchor; LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); LEReferenceTo<MarkArray> markArray(base, success, (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount); le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) { if (markClass < 0 || markClass >= mcCount || LE_FAILURE(success)) {
// markGlyph isn't in the mark array or its // markGlyph isn't in the mark array or its
// mark class is too big. The table is mal-formed! // mark class is too big. The table is mal-formed!
return 0; return 0;
...@@ -80,7 +80,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -80,7 +80,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/)); GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator); LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success); le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)); LEReferenceTo<BaseArray> baseArray(base, success, (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0;
le_uint16 baseCount = SWAPW(baseArray->baseRecordCount); le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
if (baseCoverage < 0 || baseCoverage >= baseCount) { if (baseCoverage < 0 || baseCoverage >= baseCount) {
...@@ -89,19 +90,23 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -89,19 +90,23 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
// table is mal-formed... // table is mal-formed...
return 0; return 0;
} }
LEReferenceTo<BaseRecord> baseRecord(base, success, &baseArray->baseRecordArray[baseCoverage * mcCount]);
if( LE_FAILURE(success) ) { return 0; }
LEReferenceToArrayOf<Offset> baseAnchorTableOffsetArray(base, success, &(baseRecord->baseAnchorTableOffsetArray[0]), markClass+1);
const BaseRecord *baseRecord = &baseArray->baseRecordArray[baseCoverage * mcCount]; if( LE_FAILURE(success) ) { return 0; }
Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]); Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) baseArray + anchorTableOffset); if (anchorTableOffset <= 0) {
LEPoint baseAnchor, markAdvance, pixels;
if (anchorTableOffset == 0) {
// this means the table is mal-formed... // this means the table is mal-formed...
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition()); glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
return 0; return 0;
} }
anchorTable->getAnchor(baseGlyph, fontInstance, baseAnchor); LEReferenceTo<AnchorTable> anchorTable(baseArray, success, anchorTableOffset);
LEPoint baseAnchor, markAdvance, pixels;
anchorTable->getAnchor(anchorTable, baseGlyph, fontInstance, baseAnchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels); fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance); fontInstance->pixelsToUnits(pixels, markAdvance);
...@@ -109,6 +114,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -109,6 +114,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
float anchorDiffX = baseAnchor.fX - markAnchor.fX; float anchorDiffX = baseAnchor.fX - markAnchor.fX;
float anchorDiffY = baseAnchor.fY - markAnchor.fY; float anchorDiffY = baseAnchor.fY - markAnchor.fY;
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X", anchorDiffX, anchorDiffY, markGlyph);
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition()); glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) { if (glyphIterator->isRightToLeft()) {
...@@ -132,7 +139,6 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -132,7 +139,6 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
gi.next(); gi.next();
} }
// end of JK patch // end of JK patch
fontInstance->pixelsToUnits(pixels, baseAdvance); fontInstance->pixelsToUnits(pixels, baseAdvance);
glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY); glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY);
......
...@@ -65,8 +65,11 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -65,8 +65,11 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
} }
LEPoint markAnchor; LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); if( LE_FAILURE(success) ) {
return 0;
}
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount); le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) { if (markClass < 0 || markClass >= mcCount) {
...@@ -79,7 +82,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -79,7 +82,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/)); GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator); LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success); le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset)); LEReferenceTo<LigatureArray> ligatureArray(base, success, SWAPW(baseArrayOffset));
le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount); le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) { if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) {
...@@ -91,7 +94,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -91,7 +94,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
le_int32 markPosition = glyphIterator->getCurrStreamPosition(); le_int32 markPosition = glyphIterator->getCurrStreamPosition();
Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]); Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]);
const LigatureAttachTable *ligatureAttachTable = (const LigatureAttachTable *) ((char *) ligatureArray + ligatureAttachOffset); LEReferenceTo<LigatureAttachTable> ligatureAttachTable(ligatureArray, success, ligatureAttachOffset);
le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount); le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount);
le_int32 component = ligatureIterator.getMarkComponent(markPosition); le_int32 component = ligatureIterator.getMarkComponent(markPosition);
...@@ -100,12 +103,14 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -100,12 +103,14 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
component = componentCount - 1; component = componentCount - 1;
} }
const ComponentRecord *componentRecord = &ligatureAttachTable->componentRecordArray[component * mcCount]; LEReferenceTo<ComponentRecord> componentRecord(base, success, &ligatureAttachTable->componentRecordArray[component * mcCount]);
LEReferenceToArrayOf<Offset> ligatureAnchorTableOffsetArray(base, success, &(componentRecord->ligatureAnchorTableOffsetArray[0]), markClass+1);
if( LE_FAILURE(success) ) { return 0; }
Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]); Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) ligatureAttachTable + anchorTableOffset); LEReferenceTo<AnchorTable> anchorTable(ligatureAttachTable, success, anchorTableOffset);
LEPoint ligatureAnchor, markAdvance, pixels; LEPoint ligatureAnchor, markAdvance, pixels;
anchorTable->getAnchor(ligatureGlyph, fontInstance, ligatureAnchor); anchorTable->getAnchor(anchorTable, ligatureGlyph, fontInstance, ligatureAnchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels); fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance); fontInstance->pixelsToUnits(pixels, markAdvance);
......
...@@ -66,8 +66,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -66,8 +66,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
} }
LEPoint markAnchor; LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); if(LE_FAILURE(success)) {
return 0;
}
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount); le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) { if (markClass < 0 || markClass >= mcCount) {
...@@ -79,7 +82,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -79,7 +82,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator mark2Iterator(*glyphIterator); GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator); LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success); le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)); LEReferenceTo<Mark2Array> mark2Array(base, success, (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0;
le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount); le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
if (mark2Coverage < 0 || mark2Coverage >= mark2Count) { if (mark2Coverage < 0 || mark2Coverage >= mark2Count) {
...@@ -89,9 +93,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -89,9 +93,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
return 0; return 0;
} }
const Mark2Record *mark2Record = &mark2Array->mark2RecordArray[mark2Coverage * mcCount]; LEReferenceTo<Mark2Record> mark2Record(base, success, &mark2Array->mark2RecordArray[mark2Coverage * mcCount]);
if(LE_FAILURE(success)) return 0;
Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]); Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset); LEReferenceTo<AnchorTable> anchorTable(mark2Array, success, anchorTableOffset);
if(LE_FAILURE(success)) return 0;
LEPoint mark2Anchor, markAdvance, pixels; LEPoint mark2Anchor, markAdvance, pixels;
if (anchorTableOffset == 0) { if (anchorTableOffset == 0) {
...@@ -99,7 +105,7 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -99,7 +105,7 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
return 0; return 0;
} }
anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor); anchorTable->getAnchor(anchorTable, mark2Glyph, fontInstance, mark2Anchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels); fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance); fontInstance->pixelsToUnits(pixels, markAdvance);
...@@ -107,6 +113,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -107,6 +113,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
float anchorDiffX = mark2Anchor.fX - markAnchor.fX; float anchorDiffX = mark2Anchor.fX - markAnchor.fX;
float anchorDiffY = mark2Anchor.fY - markAnchor.fY; float anchorDiffY = mark2Anchor.fY - markAnchor.fY;
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X mark2 0x%X", anchorDiffX, anchorDiffY, markGlyph, mark2Glyph);
glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition()); glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) { if (glyphIterator->isRightToLeft()) {
......
...@@ -54,9 +54,10 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -54,9 +54,10 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
// FIXME: is this always the right thing to do? // FIXME: is this always the right thing to do?
// FIXME: should this only be done for a non-zero // FIXME: should this only be done for a non-zero
// glyphCount? // glyphCount?
if (filter != NULL && filter->accept(glyph)) { if (filter != NULL && filter->accept(glyph, success)) {
return 0; return 0;
} }
if(LE_FAILURE(success)) return 0;
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount); le_uint16 seqCount = SWAPW(sequenceCount);
...@@ -67,7 +68,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -67,7 +68,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
if (coverageIndex >= 0 && coverageIndex < seqCount) { if (coverageIndex >= 0 && coverageIndex < seqCount) {
Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset); LEReferenceTo<SequenceTable> sequenceTable(base, success, sequenceTableOffset);
le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount); le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount);
if (glyphCount == 0) { if (glyphCount == 0) {
...@@ -76,7 +77,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -76,7 +77,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
} else if (glyphCount == 1) { } else if (glyphCount == 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]); TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) { if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
return 0; return 0;
} }
...@@ -89,7 +90,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -89,7 +90,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
for (le_int32 i = 0; i < glyphCount; i += 1) { for (le_int32 i = 0; i < glyphCount; i += 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]); TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
if (! filter->accept(substitute)) { if (! filter->accept(substitute, success)) {
return 0; return 0;
} }
} }
......
...@@ -470,6 +470,7 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o ...@@ -470,6 +470,7 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
LEGlyphStorage &glyphStorage, LEErrorCode &success) LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
_LETRACE("OTLE::adjustGPOS");
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return; return;
} }
...@@ -510,14 +511,17 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -510,14 +511,17 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
if (!fGPOSTable.isEmpty()) { if (!fGPOSTable.isEmpty()) {
if (fScriptTagV2 != nullScriptTag && if (fScriptTagV2 != nullScriptTag &&
fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) { fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
_LETRACE("OTLE::process [0]");
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} else { } else {
_LETRACE("OTLE::process [1]");
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} }
} else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ } else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
_LETRACE("OTLE::kerning");
LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success); KernTable kt(kernTable, success);
kt.process(glyphStorage, success); kt.process(glyphStorage, success);
...@@ -546,6 +550,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -546,6 +550,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
xPlacement = fFontInstance->xUnitsToPoints(xPlacement); xPlacement = fFontInstance->xUnitsToPoints(xPlacement);
yPlacement = fFontInstance->yUnitsToPoints(yPlacement); yPlacement = fFontInstance->yUnitsToPoints(yPlacement);
_LETRACE("OTLE GPOS: #%d, (%.2f,%.2f)", i, xPlacement, yPlacement);
glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success); glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success);
xAdjust += fFontInstance->xUnitsToPoints(xAdvance); xAdjust += fFontInstance->xUnitsToPoints(xAdvance);
......
...@@ -46,15 +46,14 @@ class OpenTypeUtilities /* not : public UObject because all methods are static * ...@@ -46,15 +46,14 @@ class OpenTypeUtilities /* not : public UObject because all methods are static *
public: public:
static le_int8 highBit(le_int32 value); static le_int8 highBit(le_int32 value);
static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success); static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success);
/** #if LE_ENABLE_RAW
* @deprecated TODO remove
*/
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) { static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) {
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
LETableReference recordRef0((const le_uint8*)records); LETableReference recordRef0((const le_uint8*)records);
LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount); LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount);
return getGlyphRangeIndex(glyphID, recordRef, success); return getGlyphRangeIndex(glyphID, recordRef, success);
} }
#endif
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success); static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success);
static le_int32 search(le_uint16 value, const le_uint16 array[], le_int32 count); static le_int32 search(le_uint16 value, const le_uint16 array[], le_int32 count);
static le_int32 search(le_uint32 value, const le_uint32 array[], le_int32 count); static le_int32 search(le_uint32 value, const le_uint32 array[], le_int32 count);
......
...@@ -76,19 +76,17 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi ...@@ -76,19 +76,17 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
{ {
LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success); le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
if (LE_FAILURE(success)) {
return 0;
}
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
if (coverageIndex >= 0 && glyphIterator->next()) { LEReferenceToArrayOf<Offset> pairSetTableOffsetArrayRef(base, success, pairSetTableOffsetArray, SWAPW(pairSetCount));
if (LE_SUCCESS(success) && coverageIndex >= 0 && glyphIterator->next() && (le_uint32)coverageIndex < pairSetTableOffsetArrayRef.getCount()) {
Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]); Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]);
LEReferenceTo<PairSetTable> pairSetTable(base, success, ((char *) this + pairSetTableOffset)); LEReferenceTo<PairSetTable> pairSetTable(base, success, pairSetTableOffset);
if (LE_FAILURE(success)) { if( LE_FAILURE(success) ) return 0;
return 0;
}
le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount); le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount);
LEReferenceTo<PairValueRecord> pairValueRecordArray(pairSetTable, success, pairSetTable->pairValueRecordArray);
if( LE_FAILURE(success) ) return 0;
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1)); le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2)); le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
le_int16 recordSize = sizeof(PairValueRecord) - sizeof(ValueRecord) + valueRecord1Size + valueRecord2Size; le_int16 recordSize = sizeof(PairValueRecord) - sizeof(ValueRecord) + valueRecord1Size + valueRecord2Size;
...@@ -96,21 +94,22 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi ...@@ -96,21 +94,22 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
LEReferenceTo<PairValueRecord> pairValueRecord; LEReferenceTo<PairValueRecord> pairValueRecord;
if (pairValueCount != 0) { if (pairValueCount != 0) {
pairValueRecord = findPairValueRecord(base, (TTGlyphID) LE_GET_GLYPH(secondGlyph), pairSetTable->pairValueRecordArray, pairValueCount, recordSize, success); pairValueRecord = findPairValueRecord((TTGlyphID) LE_GET_GLYPH(secondGlyph), pairValueRecordArray, pairValueCount, recordSize, success);
} }
if (pairValueRecord.isEmpty()) { if (pairValueRecord.isEmpty() || LE_FAILURE(success)) {
return 0; return 0;
} }
if (valueFormat1 != 0) { if (valueFormat1 != 0) {
pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance); pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
} }
if (valueFormat2 != 0) { if (valueFormat2 != 0) {
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size); LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size));
if(LE_SUCCESS(success)) {
valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, *glyphIterator, fontInstance); valueRecord2->adjustPosition(SWAPW(valueFormat2), base, *glyphIterator, fontInstance, success);
}
} }
// back up glyphIterator so second glyph can be // back up glyphIterator so second glyph can be
...@@ -135,26 +134,28 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi ...@@ -135,26 +134,28 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
if (coverageIndex >= 0 && glyphIterator->next()) { if (coverageIndex >= 0 && glyphIterator->next()) {
LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID(); LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID();
const ClassDefinitionTable *classDef1 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef1Offset)); const LEReferenceTo<ClassDefinitionTable> classDef1(base, success, SWAPW(classDef1Offset));
const ClassDefinitionTable *classDef2 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef2Offset)); const LEReferenceTo<ClassDefinitionTable> classDef2(base, success, SWAPW(classDef2Offset));
le_int32 class1 = classDef1->getGlyphClass(firstGlyph); le_int32 class1 = classDef1->getGlyphClass(classDef1, firstGlyph, success);
le_int32 class2 = classDef2->getGlyphClass(secondGlyph); le_int32 class2 = classDef2->getGlyphClass(classDef2, secondGlyph, success);
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1)); le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2)); le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size; le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size;
le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count); le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count);
const Class1Record *class1Record = (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)); const LEReferenceTo<Class1Record> class1Record(base, success, (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)));
const Class2Record *class2Record = (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)); const LEReferenceTo<Class2Record> class2Record(base, success, (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)));
if( LE_SUCCESS(success) ) {
if (valueFormat1 != 0) { if (valueFormat1 != 0) {
class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance); class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
} }
if (valueFormat2 != 0) { if (valueFormat2 != 0) {
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &class2Record->valueRecord1 + valueRecord1Size); const LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &class2Record->valueRecord1) + valueRecord1Size);
LEReferenceTo<PairPositioningFormat2Subtable> thisRef(base, success, this);
valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, *glyphIterator, fontInstance); if(LE_SUCCESS(success)) {
valueRecord2->adjustPosition(SWAPW(valueFormat2), thisRef, *glyphIterator, fontInstance, success);
}
}
} }
// back up glyphIterator so second glyph can be // back up glyphIterator so second glyph can be
...@@ -166,23 +167,24 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi ...@@ -166,23 +167,24 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
return 0; return 0;
} }
LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const LEReferenceTo<PairValueRecord>
PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, LEReferenceTo<PairValueRecord>& records,
le_uint16 recordCount,
le_uint16 recordSize, LEErrorCode &success) const
{ {
#if 1 #if 1
// The OpenType spec. says that the ValueRecord table is // The OpenType spec. says that the ValueRecord table is
// sorted by secondGlyph. Unfortunately, there are fonts // sorted by secondGlyph. Unfortunately, there are fonts
// around that have an unsorted ValueRecord table. // around that have an unsorted ValueRecord table.
LEReferenceTo<PairValueRecord> record(base, success, records); LEReferenceTo<PairValueRecord> record(records);
record.verifyLength(0, recordSize, success);
for(le_int32 r = 0; r < recordCount; r += 1) { for(le_int32 r = 0; r < recordCount; r += 1) {
if (LE_FAILURE(success)) return (const PairValueRecord*)NULL; if(LE_FAILURE(success)) return LEReferenceTo<PairValueRecord>();
if (SWAPW(record->secondGlyph) == glyphID) { if (SWAPW(record->secondGlyph) == glyphID) {
return record; return record;
} }
record = LEReferenceTo<PairValueRecord>(base, success, ((const char*)record.getAlias())+ recordSize); record.addOffset(recordSize, success);
record.verifyLength(0, recordSize, success);
} }
#else #else
#error dead code - not updated. #error dead code - not updated.
...@@ -211,7 +213,7 @@ LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueReco ...@@ -211,7 +213,7 @@ LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueReco
} }
#endif #endif
return (const PairValueRecord*)NULL; return LEReferenceTo<PairValueRecord>();
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -77,9 +77,8 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable ...@@ -77,9 +77,8 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable
le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
private: private:
LEReferenceTo<PairValueRecord> findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, LEReferenceTo<PairValueRecord> findPairValueRecord(TTGlyphID glyphID, LEReferenceTo<PairValueRecord> &records,
le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const; le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray) LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray)
......
...@@ -106,7 +106,8 @@ LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &b ...@@ -106,7 +106,8 @@ LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &b
} }
} else { } else {
LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count); LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success);
} }
if (scriptTableOffset != 0) { if (scriptTableOffset != 0) {
......
...@@ -126,13 +126,13 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { ...@@ -126,13 +126,13 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
linaScriptTag, /* 'lina' (LINA) */ linaScriptTag, /* 'lina' (LINA) */
mandScriptTag, /* 'mand' (MANDAIC) */ mandScriptTag, /* 'mand' (MANDAIC) */
mayaScriptTag, /* 'maya' (MAYA) */ mayaScriptTag, /* 'maya' (MAYA) */
meroScriptTag, /* 'mero' (MERO) */ meroScriptTag, /* 'mero' (MEROITIC_HIEROGLYPHS) */
nkooScriptTag, /* 'nko ' (NKO) */ nkooScriptTag, /* 'nko ' (NKO) */
orkhScriptTag, /* 'orkh' (OLD_TURKIC) */ orkhScriptTag, /* 'orkh' (OLD_TURKIC) */
permScriptTag, /* 'perm' (PERM) */ permScriptTag, /* 'perm' (PERM) */
phagScriptTag, /* 'phag' (PHAGS_PA) */ phagScriptTag, /* 'phag' (PHAGS_PA) */
phnxScriptTag, /* 'phnx' (PHOENICIAN) */ phnxScriptTag, /* 'phnx' (PHOENICIAN) */
plrdScriptTag, /* 'plrd' (PLRD) */ plrdScriptTag, /* 'plrd' (MIAO/POLLARD) */
roroScriptTag, /* 'roro' (RORO) */ roroScriptTag, /* 'roro' (RORO) */
saraScriptTag, /* 'sara' (SARA) */ saraScriptTag, /* 'sara' (SARA) */
syreScriptTag, /* 'syre' (SYRE) */ syreScriptTag, /* 'syre' (SYRE) */
...@@ -158,7 +158,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { ...@@ -158,7 +158,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
mteiScriptTag, /* 'mtei' (MEETEI_MAYEK) */ mteiScriptTag, /* 'mtei' (MEETEI_MAYEK) */
armiScriptTag, /* 'armi' (IMPERIAL_ARAMAIC) */ armiScriptTag, /* 'armi' (IMPERIAL_ARAMAIC) */
avstScriptTag, /* 'avst' (AVESTAN) */ avstScriptTag, /* 'avst' (AVESTAN) */
cakmScriptTag, /* 'cakm' (CAKM) */ cakmScriptTag, /* 'cakm' (CHAKMA) */
koreScriptTag, /* 'kore' (KORE) */ koreScriptTag, /* 'kore' (KORE) */
kthiScriptTag, /* 'kthi' (KAITHI) */ kthiScriptTag, /* 'kthi' (KAITHI) */
maniScriptTag, /* 'mani' (MANI) */ maniScriptTag, /* 'mani' (MANI) */
...@@ -181,7 +181,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { ...@@ -181,7 +181,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
kpelScriptTag, /* 'kpel' (KPEL) */ kpelScriptTag, /* 'kpel' (KPEL) */
lomaScriptTag, /* 'loma' (LOMA) */ lomaScriptTag, /* 'loma' (LOMA) */
mendScriptTag, /* 'mend' (MEND) */ mendScriptTag, /* 'mend' (MEND) */
mercScriptTag, /* 'merc' (MERC) */ mercScriptTag, /* 'merc' (MEROITIC_CURSIVE) */
narbScriptTag, /* 'narb' (NARB) */ narbScriptTag, /* 'narb' (NARB) */
nbatScriptTag, /* 'nbat' (NBAT) */ nbatScriptTag, /* 'nbat' (NBAT) */
palmScriptTag, /* 'palm' (PALM) */ palmScriptTag, /* 'palm' (PALM) */
......
...@@ -140,13 +140,13 @@ const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPCHA) */ ...@@ -140,13 +140,13 @@ const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPCHA) */
const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */ const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */
const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MANDAIC) */ const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MANDAIC) */
const LETag mayaScriptTag = 0x6D617961; /* 'maya' (MAYA) */ const LETag mayaScriptTag = 0x6D617961; /* 'maya' (MAYA) */
const LETag meroScriptTag = 0x6D65726F; /* 'mero' (MERO) */ const LETag meroScriptTag = 0x6D65726F; /* 'mero' (MEROITIC_HIEROGLYPHS) */
const LETag nkooScriptTag = 0x6E6B6F20; /* 'nko ' (NKO) */ const LETag nkooScriptTag = 0x6E6B6F20; /* 'nko ' (NKO) */
const LETag orkhScriptTag = 0x6F726B68; /* 'orkh' (OLD_TURKIC) */ const LETag orkhScriptTag = 0x6F726B68; /* 'orkh' (OLD_TURKIC) */
const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */ const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */
const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */ const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */
const LETag phnxScriptTag = 0x70686E78; /* 'phnx' (PHOENICIAN) */ const LETag phnxScriptTag = 0x70686E78; /* 'phnx' (PHOENICIAN) */
const LETag plrdScriptTag = 0x706C7264; /* 'plrd' (PLRD) */ const LETag plrdScriptTag = 0x706C7264; /* 'plrd' (MIAO) */
const LETag roroScriptTag = 0x726F726F; /* 'roro' (RORO) */ const LETag roroScriptTag = 0x726F726F; /* 'roro' (RORO) */
const LETag saraScriptTag = 0x73617261; /* 'sara' (SARA) */ const LETag saraScriptTag = 0x73617261; /* 'sara' (SARA) */
const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */ const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */
...@@ -172,7 +172,7 @@ const LETag moonScriptTag = 0x6D6F6F6E; /* 'moon' (MOON) */ ...@@ -172,7 +172,7 @@ const LETag moonScriptTag = 0x6D6F6F6E; /* 'moon' (MOON) */
const LETag mteiScriptTag = 0x6D746569; /* 'mtei' (MEETEI_MAYEK) */ const LETag mteiScriptTag = 0x6D746569; /* 'mtei' (MEETEI_MAYEK) */
const LETag armiScriptTag = 0x61726D69; /* 'armi' (IMPERIAL_ARAMAIC) */ const LETag armiScriptTag = 0x61726D69; /* 'armi' (IMPERIAL_ARAMAIC) */
const LETag avstScriptTag = 0x61767374; /* 'avst' (AVESTAN) */ const LETag avstScriptTag = 0x61767374; /* 'avst' (AVESTAN) */
const LETag cakmScriptTag = 0x63616B6D; /* 'cakm' (CAKM) */ const LETag cakmScriptTag = 0x63616B6D; /* 'cakm' (CHAKMA) */
const LETag koreScriptTag = 0x6B6F7265; /* 'kore' (KORE) */ const LETag koreScriptTag = 0x6B6F7265; /* 'kore' (KORE) */
const LETag kthiScriptTag = 0x6B746869; /* 'kthi' (KAITHI) */ const LETag kthiScriptTag = 0x6B746869; /* 'kthi' (KAITHI) */
const LETag maniScriptTag = 0x6D616E69; /* 'mani' (MANI) */ const LETag maniScriptTag = 0x6D616E69; /* 'mani' (MANI) */
...@@ -195,7 +195,7 @@ const LETag granScriptTag = 0x6772616E; /* 'gran' (GRAN) */ ...@@ -195,7 +195,7 @@ const LETag granScriptTag = 0x6772616E; /* 'gran' (GRAN) */
const LETag kpelScriptTag = 0x6B70656C; /* 'kpel' (KPEL) */ const LETag kpelScriptTag = 0x6B70656C; /* 'kpel' (KPEL) */
const LETag lomaScriptTag = 0x6C6F6D61; /* 'loma' (LOMA) */ const LETag lomaScriptTag = 0x6C6F6D61; /* 'loma' (LOMA) */
const LETag mendScriptTag = 0x6D656E64; /* 'mend' (MEND) */ const LETag mendScriptTag = 0x6D656E64; /* 'mend' (MEND) */
const LETag mercScriptTag = 0x6D657263; /* 'merc' (MERC) */ const LETag mercScriptTag = 0x6D657263; /* 'merc' (MEROITIC_CURSIVE) */
const LETag narbScriptTag = 0x6E617262; /* 'narb' (NARB) */ const LETag narbScriptTag = 0x6E617262; /* 'narb' (NARB) */
const LETag nbatScriptTag = 0x6E626174; /* 'nbat' (NBAT) */ const LETag nbatScriptTag = 0x6E626174; /* 'nbat' (NBAT) */
const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */ const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */
......
...@@ -65,16 +65,17 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode & ...@@ -65,16 +65,17 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
// lookupSegment already range checked by lookupSegment() function.
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success); const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) { if (lookupSegment != NULL&& LE_SUCCESS(success)) {
TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph); TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
TTGlyphID lastGlyph = SWAPW(lookupSegment->lastGlyph);
le_int16 offset = SWAPW(lookupSegment->value); le_int16 offset = SWAPW(lookupSegment->value);
TTGlyphID thisGlyphId= LE_GET_GLYPH(thisGlyph);
if (offset != 0) { LEReferenceToArrayOf<TTGlyphID> glyphArray(subtableHeader, success, offset, lastGlyph - firstGlyph + 1);
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader.getAliasTODO() + offset); if (offset != 0 && thisGlyphId <= lastGlyph && thisGlyphId >= firstGlyph && LE_SUCCESS(success) ) {
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); TTGlyphID newGlyph = SWAPW(glyphArray[thisGlyphId]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
} }
......
...@@ -75,7 +75,7 @@ le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePo ...@@ -75,7 +75,7 @@ le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePo
} }
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); valueRecord.adjustPosition(SWAPW(valueFormat), base, *glyphIterator, fontInstance, success);
return 1; return 1;
} }
...@@ -92,7 +92,7 @@ le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePo ...@@ -92,7 +92,7 @@ le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePo
} }
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), base, *glyphIterator, fontInstance, success);
return 1; return 1;
} }
......
...@@ -76,7 +76,7 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleS ...@@ -76,7 +76,7 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleS
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID); TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) { if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
glyphIterator->setCurrGlyphID(substitute); glyphIterator->setCurrGlyphID(substitute);
} }
...@@ -97,7 +97,7 @@ le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleS ...@@ -97,7 +97,7 @@ le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleS
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]); TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) { if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
glyphIterator->setCurrGlyphID(substitute); glyphIterator->setCurrGlyphID(substitute);
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
*/ */
#ifndef __TIBETANREORDERING_H #ifndef __TIBETANREORDERING_H
#define __TIBETANORDERING_H #define __TIBETANREORDERING_H
/** /**
* \file * \file
......
...@@ -59,8 +59,8 @@ le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, Val ...@@ -59,8 +59,8 @@ le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, Val
return SWAPW(value); return SWAPW(value);
} }
void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void ValueRecord::adjustPosition(ValueFormat valueFormat, const LETableReference& base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
float xPlacementAdjustment = 0; float xPlacementAdjustment = 0;
float yPlacementAdjustment = 0; float yPlacementAdjustment = 0;
...@@ -118,8 +118,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -118,8 +118,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice); Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj); xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -129,8 +129,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -129,8 +129,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice); Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj); yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
...@@ -140,8 +140,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -140,8 +140,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice); Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj); xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -151,8 +151,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -151,8 +151,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice); Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
...@@ -163,8 +163,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -163,8 +163,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment); xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
} }
void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const LETableReference& base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
float xPlacementAdjustment = 0; float xPlacementAdjustment = 0;
float yPlacementAdjustment = 0; float yPlacementAdjustment = 0;
...@@ -222,8 +222,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -222,8 +222,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj); xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -233,8 +233,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -233,8 +233,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj); yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
...@@ -244,8 +244,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -244,8 +244,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj); xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -255,8 +255,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -255,8 +255,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
......
...@@ -53,10 +53,10 @@ struct ValueRecord ...@@ -53,10 +53,10 @@ struct ValueRecord
le_int16 getFieldValue(ValueFormat valueFormat, ValueRecordField field) const; le_int16 getFieldValue(ValueFormat valueFormat, ValueRecordField field) const;
le_int16 getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const; le_int16 getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const;
void adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void adjustPosition(ValueFormat valueFormat, const LETableReference &base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const; const LEFontInstance *fontInstance, LEErrorCode &success) const;
void adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void adjustPosition(le_int16 index, ValueFormat valueFormat, const LETableReference &base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const; const LEFontInstance *fontInstance, LEErrorCode &success) const;
static le_int16 getSize(ValueFormat valueFormat); static le_int16 getSize(ValueFormat valueFormat);
......
...@@ -215,6 +215,11 @@ void LinLerp1D(register const cmsUInt16Number Value[], ...@@ -215,6 +215,11 @@ void LinLerp1D(register const cmsUInt16Number Value[],
Output[0] = LinearInterp(rest, y0, y1); Output[0] = LinearInterp(rest, y0, y1);
} }
// To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
{
return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
}
// Floating-point version of 1D interpolation // Floating-point version of 1D interpolation
static static
...@@ -227,13 +232,15 @@ void LinLerp1Dfloat(const cmsFloat32Number Value[], ...@@ -227,13 +232,15 @@ void LinLerp1Dfloat(const cmsFloat32Number Value[],
int cell0, cell1; int cell0, cell1;
const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
val2 = fclamp(Value[0]);
// if last value... // if last value...
if (Value[0] == 1.0) { if (val2 == 1.0) {
Output[0] = LutTable[p -> Domain[0]]; Output[0] = LutTable[p -> Domain[0]];
return; return;
} }
val2 = p -> Domain[0] * Value[0]; val2 *= p -> Domain[0];
cell0 = (int) floor(val2); cell0 = (int) floor(val2);
cell1 = (int) ceil(val2); cell1 = (int) ceil(val2);
...@@ -292,13 +299,15 @@ void Eval1InputFloat(const cmsFloat32Number Value[], ...@@ -292,13 +299,15 @@ void Eval1InputFloat(const cmsFloat32Number Value[],
cmsUInt32Number OutChan; cmsUInt32Number OutChan;
const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
val2 = fclamp(Value[0]);
// if last value... // if last value...
if (Value[0] == 1.0) { if (val2 == 1.0) {
Output[0] = LutTable[p -> Domain[0]]; Output[0] = LutTable[p -> Domain[0]];
return; return;
} }
val2 = p -> Domain[0] * Value[0]; val2 *= p -> Domain[0];
cell0 = (int) floor(val2); cell0 = (int) floor(val2);
cell1 = (int) ceil(val2); cell1 = (int) ceil(val2);
...@@ -339,8 +348,8 @@ void BilinearInterpFloat(const cmsFloat32Number Input[], ...@@ -339,8 +348,8 @@ void BilinearInterpFloat(const cmsFloat32Number Input[],
dxy; dxy;
TotalOut = p -> nOutputs; TotalOut = p -> nOutputs;
px = Input[0] * p->Domain[0]; px = fclamp(Input[0]) * p->Domain[0];
py = Input[1] * p->Domain[1]; py = fclamp(Input[1]) * p->Domain[1];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
...@@ -454,20 +463,9 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[], ...@@ -454,20 +463,9 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
TotalOut = p -> nOutputs; TotalOut = p -> nOutputs;
// We need some clipping here // We need some clipping here
px = Input[0]; px = fclamp(Input[0]) * p->Domain[0];
py = Input[1]; py = fclamp(Input[1]) * p->Domain[1];
pz = Input[2]; pz = fclamp(Input[2]) * p->Domain[2];
if (px < 0) px = 0;
if (px > 1) px = 1;
if (py < 0) py = 0;
if (py > 1) py = 1;
if (pz < 0) pz = 0;
if (pz > 1) pz = 1;
px *= p->Domain[0];
py *= p->Domain[1];
pz *= p->Domain[2];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
...@@ -609,20 +607,9 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[], ...@@ -609,20 +607,9 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
TotalOut = p -> nOutputs; TotalOut = p -> nOutputs;
// We need some clipping here // We need some clipping here
px = Input[0]; px = fclamp(Input[0]) * p->Domain[0];
py = Input[1]; py = fclamp(Input[1]) * p->Domain[1];
pz = Input[2]; pz = fclamp(Input[2]) * p->Domain[2];
if (px < 0) px = 0;
if (px > 1) px = 1;
if (py < 0) py = 0;
if (py > 1) py = 1;
if (pz < 0) pz = 0;
if (pz > 1) pz = 1;
px *= p->Domain[0];
py *= p->Domain[1];
pz *= p->Domain[2];
x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0); x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0);
y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0); y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0);
...@@ -1039,8 +1026,7 @@ void Eval4InputsFloat(const cmsFloat32Number Input[], ...@@ -1039,8 +1026,7 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1; cmsInterpParams p1;
pk = fclamp(Input[0]) * p->Domain[0];
pk = Input[0] * p->Domain[0];
k0 = _cmsQuickFloor(pk); k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
...@@ -1127,7 +1113,7 @@ void Eval5InputsFloat(const cmsFloat32Number Input[], ...@@ -1127,7 +1113,7 @@ void Eval5InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1; cmsInterpParams p1;
pk = Input[0] * p->Domain[0]; pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk); k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
...@@ -1214,7 +1200,7 @@ void Eval6InputsFloat(const cmsFloat32Number Input[], ...@@ -1214,7 +1200,7 @@ void Eval6InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1; cmsInterpParams p1;
pk = Input[0] * p->Domain[0]; pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk); k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
...@@ -1299,7 +1285,7 @@ void Eval7InputsFloat(const cmsFloat32Number Input[], ...@@ -1299,7 +1285,7 @@ void Eval7InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1; cmsInterpParams p1;
pk = Input[0] * p->Domain[0]; pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk); k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
...@@ -1384,7 +1370,7 @@ void Eval8InputsFloat(const cmsFloat32Number Input[], ...@@ -1384,7 +1370,7 @@ void Eval8InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1; cmsInterpParams p1;
pk = Input[0] * p->Domain[0]; pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk); k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
......
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.net;
import java.security.AccessController;
/**
* Determines the ephemeral port range in use on this system.
* If this cannot be determined, then the default settings
* of the OS are returned.
*/
public final class PortConfig {
private static int defaultUpper, defaultLower;
private final static int upper, lower;
private PortConfig() {}
static {
AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("net");
String os = System.getProperty("os.name");
if (os.startsWith("Linux")) {
defaultLower = 32768;
defaultUpper = 61000;
} else if (os.startsWith("SunOS")) {
defaultLower = 32768;
defaultUpper = 65535;
} else if (os.contains("OS X")) {
defaultLower = 49152;
defaultUpper = 65535;
} else {
throw new InternalError(
"sun.net.PortConfig: unknown OS");
}
return null;
}
});
int v = getLower0();
if (v == -1) {
v = defaultLower;
}
lower = v;
v = getUpper0();
if (v == -1) {
v = defaultUpper;
}
upper = v;
}
static native int getLower0();
static native int getUpper0();
public static int getLower() {
return lower;
}
public static int getUpper() {
return upper;
}
}
...@@ -187,6 +187,10 @@ public class SctpChannelImpl extends SctpChannel ...@@ -187,6 +187,10 @@ public class SctpChannelImpl extends SctpChannel
SctpNet.throwAlreadyBoundException(); SctpNet.throwAlreadyBoundException();
InetSocketAddress isa = (local == null) ? InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local); new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
InetSocketAddress boundIsa = Net.localAddress(fd); InetSocketAddress boundIsa = Net.localAddress(fd);
port = boundIsa.getPort(); port = boundIsa.getPort();
......
...@@ -138,8 +138,7 @@ static int useExclBind = 0; ...@@ -138,8 +138,7 @@ static int useExclBind = 0;
* of the parameter is assumed to be an 'int'. If the parameter * of the parameter is assumed to be an 'int'. If the parameter
* cannot be obtained return -1 * cannot be obtained return -1
*/ */
static int int net_getParam(char *driver, char *param)
getParam(char *driver, char *param)
{ {
struct strioctl stri; struct strioctl stri;
char buf [64]; char buf [64];
...@@ -166,7 +165,7 @@ getParam(char *driver, char *param) ...@@ -166,7 +165,7 @@ getParam(char *driver, char *param)
/* /*
* Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF
* for Solaris versions that do not support the ioctl() in getParam(). * for Solaris versions that do not support the ioctl() in net_getParam().
* Ugly, but only called once (for each sotype). * Ugly, but only called once (for each sotype).
* *
* As an optimization, we make a guess using the default values for Solaris * As an optimization, we make a guess using the default values for Solaris
...@@ -1359,7 +1358,7 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg, ...@@ -1359,7 +1358,7 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg,
* If that fails, we use the search algorithm in findMaxBuf() * If that fails, we use the search algorithm in findMaxBuf()
*/ */
if (!init_tcp_max_buf && sotype == SOCK_STREAM) { if (!init_tcp_max_buf && sotype == SOCK_STREAM) {
tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf"); tcp_max_buf = net_getParam("/dev/tcp", "tcp_max_buf");
if (tcp_max_buf == -1) { if (tcp_max_buf == -1) {
tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM); tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM);
if (tcp_max_buf == -1) { if (tcp_max_buf == -1) {
...@@ -1368,7 +1367,7 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg, ...@@ -1368,7 +1367,7 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg,
} }
init_tcp_max_buf = 1; init_tcp_max_buf = 1;
} else if (!init_udp_max_buf && sotype == SOCK_DGRAM) { } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) {
udp_max_buf = getParam("/dev/udp", "udp_max_buf"); udp_max_buf = net_getParam("/dev/udp", "udp_max_buf");
if (udp_max_buf == -1) { if (udp_max_buf == -1) {
udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM); udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM);
if (udp_max_buf == -1) { if (udp_max_buf == -1) {
......
...@@ -81,6 +81,9 @@ extern int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout); ...@@ -81,6 +81,9 @@ extern int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout);
int getDefaultIPv6Interface(struct in6_addr *target_addr); int getDefaultIPv6Interface(struct in6_addr *target_addr);
#endif #endif
#ifdef __solaris__
extern int net_getParam(char *driver, char *param);
#endif
/* needed from libsocket on Solaris 8 */ /* needed from libsocket on Solaris 8 */
......
...@@ -577,8 +577,8 @@ SplashEventLoop(Splash * splash) { ...@@ -577,8 +577,8 @@ SplashEventLoop(Splash * splash) {
SplashUnlock(splash); SplashUnlock(splash);
rc = poll(pfd, 2, timeout); rc = poll(pfd, 2, timeout);
SplashLock(splash); SplashLock(splash);
if (splash->isVisible>0 && SplashTime() >= splash->time + if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
splash->frames[splash->currentFrame].delay) { SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
SplashNextFrame(splash); SplashNextFrame(splash);
SplashUpdateShape(splash); SplashUpdateShape(splash);
SplashRedrawWindow(splash); SplashRedrawWindow(splash);
......
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#if defined(_ALLBSD_SOURCE)
#include <sys/sysctl.h>
#endif
#include "jni.h"
#include "net_util.h"
#include "sun_net_PortConfig.h"
#ifdef __cplusplus
extern "C" {
#endif
struct portrange {
int lower;
int higher;
};
static int getPortRange(struct portrange *range)
{
#ifdef __linux__
{
FILE *f;
int ret;
f = fopen("/proc/sys/net/ipv4/ip_local_port_range", "r");
if (f != NULL) {
ret = fscanf(f, "%d %d", &range->lower, &range->higher);
fclose(f);
return ret == 2 ? 0 : -1;
}
return -1;
}
#elif defined(__solaris__)
{
range->higher = net_getParam("/dev/tcp", "tcp_largest_anon_port");
range->lower = net_getParam("/dev/tcp", "tcp_smallest_anon_port");
return 0;
}
#elif defined(_ALLBSD_SOURCE)
{
int ret;
size_t size = sizeof(range->lower);
ret = sysctlbyname(
"net.inet.ip.portrange.first", &range->lower, &size, 0, 0
);
if (ret == -1) {
return -1;
}
size = sizeof(range->higher);
ret = sysctlbyname(
"net.inet.ip.portrange.last", &range->higher, &size, 0, 0
);
return ret;
}
#else
return -1;
#endif
}
/*
* Class: sun_net_PortConfig
* Method: getLower0
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_sun_net_PortConfig_getLower0
(JNIEnv *env, jclass clazz)
{
struct portrange range;
if (getPortRange(&range) < 0) {
return -1;
}
return range.lower;
}
/*
* Class: sun_net_PortConfig
* Method: getUpper0
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_sun_net_PortConfig_getUpper0
(JNIEnv *env, jclass clazz)
{
struct portrange range;
if (getPortRange(&range) < 0) {
return -1;
}
return range.higher;
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.net;
import java.security.AccessController;
/**
* Determines the ephemeral port range in use on this system.
* If this cannot be determined, then the default settings
* of the OS are returned.
*/
public final class PortConfig {
private static int defaultUpper, defaultLower;
private final static int upper, lower;
static {
AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("net");
return null;
}
});
int v = getLower0();
if (v == -1) {
v = defaultLower;
}
lower = v;
v = getUpper0();
if (v == -1) {
v = defaultUpper;
}
upper = v;
}
static native int getLower0();
static native int getUpper0();
public static int getLower() {
return lower;
}
public static int getUpper() {
return upper;
}
}
...@@ -31,6 +31,9 @@ import java.nio.BufferOverflowException; ...@@ -31,6 +31,9 @@ import java.nio.BufferOverflowException;
import java.net.*; import java.net.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.io.IOException; import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import sun.misc.Unsafe; import sun.misc.Unsafe;
/** /**
...@@ -300,6 +303,19 @@ class WindowsAsynchronousSocketChannelImpl ...@@ -300,6 +303,19 @@ class WindowsAsynchronousSocketChannelImpl
} }
} }
private void doPrivilegedBind(final SocketAddress sa) throws IOException {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws IOException {
bind(sa);
return null;
}
});
} catch (PrivilegedActionException e) {
throw (IOException) e.getException();
}
}
@Override @Override
<A> Future<Void> implConnect(SocketAddress remote, <A> Future<Void> implConnect(SocketAddress remote,
A attachment, A attachment,
...@@ -330,7 +346,12 @@ class WindowsAsynchronousSocketChannelImpl ...@@ -330,7 +346,12 @@ class WindowsAsynchronousSocketChannelImpl
throw new ConnectionPendingException(); throw new ConnectionPendingException();
if (localAddress == null) { if (localAddress == null) {
try { try {
bind(new InetSocketAddress(0)); SocketAddress any = new InetSocketAddress(0);
if (sm == null) {
bind(any);
} else {
doPrivilegedBind(any);
}
} catch (IOException x) { } catch (IOException x) {
bindException = x; bindException = x;
} }
......
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <windows.h>
#include "jni.h"
#include "net_util.h"
#include "sun_net_PortConfig.h"
#ifdef __cplusplus
extern "C" {
#endif
struct portrange {
int lower;
int higher;
};
static int getPortRange(struct portrange *range)
{
OSVERSIONINFO ver;
ver.dwOSVersionInfoSize = sizeof(ver);
GetVersionEx(&ver);
/* Check for major version 5 or less = Windows XP/2003 or older */
if (ver.dwMajorVersion <= 5) {
LONG ret;
HKEY hKey;
range->lower = 1024;
range->higher = 4999;
/* check registry to see if upper limit was raised */
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0, KEY_READ, (PHKEY)&hKey
);
if (ret == ERROR_SUCCESS) {
DWORD maxuserport;
ULONG ulType;
DWORD dwLen = sizeof(maxuserport);
ret = RegQueryValueEx(hKey, "MaxUserPort", NULL, &ulType,
(LPBYTE)&maxuserport, &dwLen);
RegCloseKey(hKey);
if (ret == ERROR_SUCCESS) {
range->higher = maxuserport;
}
}
} else {
/* There doesn't seem to be an API to access this. "MaxUserPort"
* is affected, but is not sufficient to determine.
* so we just use the defaults, which are less likely to change
*/
range->lower = 49152;
range->higher = 65535;
}
return 0;
}
/*
* Class: sun_net_PortConfig
* Method: getLower0
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_sun_net_PortConfig_getLower0
(JNIEnv *env, jclass clazz)
{
struct portrange range;
getPortRange(&range);
return range.lower;
}
/*
* Class: sun_net_PortConfig
* Method: getUpper0
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_sun_net_PortConfig_getUpper0
(JNIEnv *env, jclass clazz)
{
struct portrange range;
getPortRange(&range);
return range.higher;
}
#ifdef __cplusplus
}
#endif
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 6741606 7146431 8000450 8019830 * @bug 6741606 7146431 8000450 8019830 8022945
* @summary Make sure all restricted packages listed in the package.access * @summary Make sure all restricted packages listed in the package.access
* property in the java.security file are blocked * property in the java.security file are blocked
* @run main/othervm CheckPackageAccess * @run main/othervm CheckPackageAccess
...@@ -56,6 +56,7 @@ public class CheckPackageAccess { ...@@ -56,6 +56,7 @@ public class CheckPackageAccess {
"com.sun.istack.internal.", "com.sun.istack.internal.",
"com.sun.jmx.", "com.sun.jmx.",
"com.sun.media.sound.", "com.sun.media.sound.",
"com.sun.naming.internal.",
"com.sun.proxy.", "com.sun.proxy.",
"com.sun.corba.se.", "com.sun.corba.se.",
"com.sun.org.apache.bcel.internal.", "com.sun.org.apache.bcel.internal.",
......
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8031502
* @summary JSR292: IncompatibleClassChangeError in LambdaForm for CharSequence.toString() method handle type converter
* @compile ObjectMethodInInterfaceTest.java
* @run main/othervm -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=0 test.java.lang.invoke.ObjectMethodInInterfaceTest
*/
package test.java.lang.invoke;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class ObjectMethodInInterfaceTest {
public static void main(String[] args) throws Throwable {
MethodHandle mh = MethodHandles.lookup().findVirtual(CharSequence.class, "toString", MethodType.methodType(String.class));
MethodType mt = MethodType.methodType(Object.class, CharSequence.class);
mh = mh.asType(mt);
Object res = mh.invokeExact((CharSequence)"123");
System.out.println("TEST PASSED");
}
}
...@@ -88,6 +88,17 @@ public class RmidViaInheritedChannel implements Callback { ...@@ -88,6 +88,17 @@ public class RmidViaInheritedChannel implements Callback {
TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT); TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT);
rmid.addOptions(new String[]{ rmid.addOptions(new String[]{
"-Djava.nio.channels.spi.SelectorProvider=RmidViaInheritedChannel$RmidSelectorProvider"}); "-Djava.nio.channels.spi.SelectorProvider=RmidViaInheritedChannel$RmidSelectorProvider"});
if (System.getProperty("os.name").startsWith("Windows") &&
System.getProperty("os.version").startsWith("5."))
{
/* Windows XP/2003 or older
* Need to expand ephemeral range to include RMI test ports
*/
rmid.addOptions(new String[]{
"-Djdk.net.ephemeralPortRange.low=1024",
"-Djdk.net.ephemeralPortRange.high=64000"
});
}
rmid.start(); rmid.start();
/* /*
......
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
# @run shell readTest.sh # @run shell readTest.sh
OS=`uname -s` OS=`uname -s`
VER=`uname -r`
ARGS=""
REGARGS=""
case "$OS" in case "$OS" in
SunOS | Linux | Darwin ) SunOS | Linux | Darwin )
PS=":" PS=":"
...@@ -39,11 +43,19 @@ case "$OS" in ...@@ -39,11 +43,19 @@ case "$OS" in
PS=";" PS=";"
FS="\\" FS="\\"
FILEURL="file:/" FILEURL="file:/"
if [ "$VER" -eq "5" ]; then
ARGS="-Djdk.net.ephemeralPortRange.low=1024 -Djdk.net.ephemeralPortRange.high=65000"
REGARGS="-J-Djdk.net.ephemeralPortRange.low=1024 -J-Djdk.net.ephemeralPortRange.high=65000"
fi
;; ;;
CYGWIN* ) CYGWIN* )
PS=";" PS=";"
FS="/" FS="/"
FILEURL="file:/" FILEURL="file:/"
if [ "$VER" -eq "5" ]; then
ARGS="-Djdk.net.ephemeralPortRange.low=1024 -Djdk.net.ephemeralPortRange.high=65000"
REGARGS="-J-Djdk.net.ephemeralPortRange.low=1024 -J-Djdk.net.ephemeralPortRange.high=65000"
fi
;; ;;
* ) * )
echo "Unrecognized system!" echo "Unrecognized system!"
...@@ -61,8 +73,8 @@ RMIREG_OUT=rmi.out ...@@ -61,8 +73,8 @@ RMIREG_OUT=rmi.out
#start rmiregistry without any local classes on classpath #start rmiregistry without any local classes on classpath
cd rmi_tmp cd rmi_tmp
# NOTE: This RMI Registry port must match TestLibrary.READTEST_REGISTRY_PORT # NOTE: This RMI Registry port must match TestLibrary.READTEST_REGISTRY_PORT
${TESTJAVA}${FS}bin${FS}rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false \ ${TESTJAVA}${FS}bin${FS}rmiregistry ${REGARGS} -J-Djava.rmi.server.useCodebaseOnly=false \
${TESTTOOLVMOPTS} 64005 > ..${FS}${RMIREG_OUT} 2>&1 & ${TESTTOOLVMOPTS} 60005 > ..${FS}${RMIREG_OUT} 2>&1 &
RMIREG_PID=$! RMIREG_PID=$!
# allow some time to start # allow some time to start
sleep 3 sleep 3
...@@ -77,7 +89,7 @@ case "$OS" in ...@@ -77,7 +89,7 @@ case "$OS" in
;; ;;
esac esac
# trailing / after code base is important for rmi codebase property. # trailing / after code base is important for rmi codebase property.
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp $TEST_CLASSPATH -Djava.rmi.server.codebase=${FILEURL}$CODEBASE/ readTest > OUT.TXT 2>&1 & ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp $TEST_CLASSPATH ${ARGS} -Djava.rmi.server.codebase=${FILEURL}$CODEBASE/ readTest > OUT.TXT 2>&1 &
TEST_PID=$! TEST_PID=$!
#bulk of testcase - let it run for a while #bulk of testcase - let it run for a while
sleep 5 sleep 5
......
...@@ -86,13 +86,13 @@ public class TestLibrary { ...@@ -86,13 +86,13 @@ public class TestLibrary {
* FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust * FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust
* FIXED_PORT_MIN/MAX appropriately. * FIXED_PORT_MIN/MAX appropriately.
*/ */
public final static int FIXED_PORT_MIN = 64001; public final static int FIXED_PORT_MIN = 60001;
public final static int FIXED_PORT_MAX = 64010; public final static int FIXED_PORT_MAX = 60010;
public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 64001; public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 60001;
public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 64002; public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 60002;
public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 64003; public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 60003;
public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 64004; public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 60004;
public final static int READTEST_REGISTRY_PORT = 64005; public final static int READTEST_REGISTRY_PORT = 60005;
private final static int MAX_SERVER_SOCKET_TRIES = 2*(FIXED_PORT_MAX-FIXED_PORT_MIN+1); private final static int MAX_SERVER_SOCKET_TRIES = 2*(FIXED_PORT_MAX-FIXED_PORT_MIN+1);
static void mesg(Object mesg) { static void mesg(Object mesg) {
......
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @summary Tests counting of streams containing Integer.MAX_VALUE + 1 elements
* @bug 8031187
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.LongStream;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class CountLargeTest {
static final long EXPECTED_LARGE_COUNT = 1L + Integer.MAX_VALUE;
public void testRefLarge() {
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToObj(e -> null).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
public void testIntLarge() {
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToInt(e -> 0).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
public void testLongLarge() {
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
public void testDoubleLarge() {
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToDouble(e -> 0.0).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
}
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @summary Tests counting of streams
* @bug 8031187
*/
package org.openjdk.tests.java.util.stream;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestDataProvider;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import org.testng.annotations.Test;
public class CountTest extends OpTestCase {
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
AtomicLong expectedCount = new AtomicLong();
data.stream().forEach(e -> expectedCount.incrementAndGet());
withData(data).
terminal(Stream::count).
expectedResult(expectedCount.get()).
exercise();
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOps(String name, TestData.OfInt data) {
AtomicLong expectedCount = new AtomicLong();
data.stream().forEach(e -> expectedCount.incrementAndGet());
withData(data).
terminal(IntStream::count).
expectedResult(expectedCount.get()).
exercise();
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testOps(String name, TestData.OfLong data) {
AtomicLong expectedCount = new AtomicLong();
data.stream().forEach(e -> expectedCount.incrementAndGet());
withData(data).
terminal(LongStream::count).
expectedResult(expectedCount.get()).
exercise();
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testOps(String name, TestData.OfDouble data) {
AtomicLong expectedCount = new AtomicLong();
data.stream().forEach(e -> expectedCount.incrementAndGet());
withData(data).
terminal(DoubleStream::count).
expectedResult(expectedCount.get()).
exercise();
}
}
...@@ -239,13 +239,13 @@ public class TimestampCheck { ...@@ -239,13 +239,13 @@ public class TimestampCheck {
" -J-Djava.security.egd=file:/dev/./urandom" + " -J-Djava.security.egd=file:/dev/./urandom" +
" -debug -keystore " + TSKS + " -storepass changeit" + " -debug -keystore " + TSKS + " -storepass changeit" +
" -tsa http://localhost:" + port + "/%d" + " -tsa http://localhost:" + port + "/%d" +
" -signedjar new.jar " + JAR + " old"; " -signedjar new_%d.jar " + JAR + " old";
} else { } else {
cmd = System.getProperty("java.home") + "/bin/jarsigner" + cmd = System.getProperty("java.home") + "/bin/jarsigner" +
" -J-Djava.security.egd=file:/dev/./urandom" + " -J-Djava.security.egd=file:/dev/./urandom" +
" -debug -keystore " + TSKS + " -storepass changeit" + " -debug -keystore " + TSKS + " -storepass changeit" +
" -tsa http://localhost:" + port + "/%d" + " -tsa http://localhost:" + port + "/%d" +
" -signedjar new.jar " + JAR + " old"; " -signedjar new_%d.jar " + JAR + " old";
} }
try { try {
...@@ -280,7 +280,7 @@ public class TimestampCheck { ...@@ -280,7 +280,7 @@ public class TimestampCheck {
static void jarsigner(String cmd, int path, boolean expected) static void jarsigner(String cmd, int path, boolean expected)
throws Exception { throws Exception {
System.err.println("Test " + path); System.err.println("Test " + path);
Process p = Runtime.getRuntime().exec(String.format(cmd, path)); Process p = Runtime.getRuntime().exec(String.format(cmd, path, path));
BufferedReader reader = new BufferedReader( BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getErrorStream())); new InputStreamReader(p.getErrorStream()));
while (true) { while (true) {
...@@ -288,9 +288,25 @@ public class TimestampCheck { ...@@ -288,9 +288,25 @@ public class TimestampCheck {
if (s == null) break; if (s == null) break;
System.err.println(s); System.err.println(s);
} }
// Will not see noTimestamp warning
boolean seeWarning = false;
reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while (true) {
String s = reader.readLine();
if (s == null) break;
System.err.println(s);
if (s.indexOf("Warning:") >= 0) {
seeWarning = true;
}
}
int result = p.waitFor(); int result = p.waitFor();
if (expected && result != 0 || !expected && result == 0) { if (expected && result != 0 || !expected && result == 0) {
throw new Exception("Failed"); throw new Exception("Failed");
} }
if (seeWarning) {
throw new Exception("See warning");
}
} }
} }
...@@ -139,7 +139,6 @@ LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l` ...@@ -139,7 +139,6 @@ LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l`
# 16 and 32 already covered in the first part # 16 and 32 already covered in the first part
# ========================================================== # ==========================================================
$KT -genkeypair -alias expiring -dname CN=expiring -startdate -1m
$KT -genkeypair -alias expired -dname CN=expired -startdate -10m $KT -genkeypair -alias expired -dname CN=expired -startdate -10m
$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid -startdate +1m $KT -genkeypair -alias notyetvalid -dname CN=notyetvalid -startdate +1m
$KT -genkeypair -alias badku -dname CN=badku -ext KU=cRLSign -validity 365 $KT -genkeypair -alias badku -dname CN=badku -ext KU=cRLSign -validity 365
...@@ -154,9 +153,6 @@ $KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \ ...@@ -154,9 +153,6 @@ $KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \
$KT -importcert -alias badchain $KT -importcert -alias badchain
$KT -delete -alias ca $KT -delete -alias ca
$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar expiring
[ $? = 2 ] || exit $LINENO
$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar expired $JARSIGNER -strict -keystore js.jks -storepass changeit a.jar expired
[ $? = 4 ] || exit $LINENO [ $? = 4 ] || exit $LINENO
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
# #
# @test # @test
# @bug 6543842 6543440 6939248 8009636 # @bug 6543842 6543440 6939248 8009636 8024302
# @summary checking response of timestamp # @summary checking response of timestamp
# #
# @run shell/timeout=600 ts.sh # @run shell/timeout=600 ts.sh
...@@ -53,7 +53,7 @@ fi ...@@ -53,7 +53,7 @@ fi
JAR="${TESTJAVA}${FS}bin${FS}jar" JAR="${TESTJAVA}${FS}bin${FS}jar"
JAVA="${TESTJAVA}${FS}bin${FS}java" JAVA="${TESTJAVA}${FS}bin${FS}java"
JAVAC="${TESTJAVA}${FS}bin${FS}javac" JAVAC="${TESTJAVA}${FS}bin${FS}javac"
KT="${TESTJAVA}${FS}bin${FS}keytool -keystore tsks -storepass changeit -keypass changeit -keyalg rsa" KT="${TESTJAVA}${FS}bin${FS}keytool -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200"
rm tsks rm tsks
echo Nothing > A echo Nothing > A
......
#
# Copyright (c) 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test
# @bug 8024302
# @bug 8026037
# @summary Clarify jar verifications
#
if [ "${TESTJAVA}" = "" ] ; then
JAVAC_CMD=`which javac`
TESTJAVA=`dirname $JAVAC_CMD`/..
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Windows_* )
FS="\\"
;;
* )
FS="/"
;;
esac
KS=warnings.jks
JFILE=warnings.jar
KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \
-keystore $KS"
JAR=$TESTJAVA${FS}bin${FS}jar
JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit"
rm $KS 2> /dev/null
LANG=C
export LANG
echo 12345 > file
ERR=""
# Normal signer expiring on 2100-01-01
$KT -alias s1 -dname CN=s1 -genkey -startdate 2000/01/01 -validity 36525 || ERR="$ERR keytool s1,"
# Cert expiring soon, informational warning
$KT -alias s2 -dname CN=s2 -genkey -validity 100 || ERR="$ERR keytool s2,"
# Cert expired, severe warning
$KT -alias s3 -dname CN=s3 -genkey -startdate -200d -validity 100 || ERR="$ERR keytool s3,"
# noTimestamp is informatiional warning and includes a date
$JAR cvf $JFILE file
$JARSIGNER $JFILE s1 > output1 || ERR="$ERR jarsigner s1,"
$JARSIGNER -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict,"
$JARSIGNER -verify $JFILE s1 >> output1 || ERR="$ERR jarsigner s1,"
$JARSIGNER -verify -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict,"
cat output1 | grep Warning || ERR="$ERR s1 warning,"
cat output1 | grep Error && ERR="$ERR s1 error,"
cat output1 | grep timestamp | grep 2100-01-01 || ERR="$ERR s1 timestamp,"
cat output1 | grep "with signer errors" && ERR="$ERR s1 err,"
# hasExpiringCert is informatiional warning
$JAR cvf $JFILE file
$JARSIGNER $JFILE s2 > output2 || ERR="$ERR jarsigner s2,"
$JARSIGNER -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict,"
$JARSIGNER -verify $JFILE s2 >> output2 || ERR="$ERR jarsigner s2,"
$JARSIGNER -verify -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict,"
cat output2 | grep Warning || ERR="$ERR s2 warning,"
cat output2 | grep Error && ERR="$ERR s2 error,"
cat output2 | grep timestamp || ERR="$ERR s2 timestamp,"
cat output2 | grep "will expire" || ERR="$ERR s2 expiring,"
cat output2 | grep "with signer errors" && ERR="$ERR s2 err,"
# hasExpiredCert is severe warning
$JAR cvf $JFILE file
$JARSIGNER $JFILE s3 > output3 || ERR="$ERR jarsigner s3,"
$JARSIGNER -strict $JFILE s3 > output3s && ERR="$ERR jarsigner s3 strict,"
$JARSIGNER -verify $JFILE s3 >> output3 || ERR="$ERR jarsigner s3,"
$JARSIGNER -verify -strict $JFILE s3 >> output3s && ERR="$ERR jarsigner s3 strict,"
# warning without -strict
cat output3 | grep Warning || ERR="$ERR s3 warning,"
cat output3 | grep Error && ERR="$ERR s3 error,"
cat output3 | grep "with signer errors" && ERR="$ERR s3 err,"
# error with -strict
cat output3s | grep Warning || ERR="$ERR s3s warning,"
cat output3s | grep Error || ERR="$ERR s3s error,"
cat output3s | grep "with signer errors" || ERR="$ERR s3 err,"
if [ "$ERR" = "" ]; then
exit 0
else
echo "ERR is $ERR"
exit 1
fi
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册