提交 d2a73c79 编写于 作者: L lana

Merge

......@@ -274,11 +274,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java \
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
# JObjC.jar contains 1.5 byte-code...so skip it here :-(
# MACOSX_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/jobjc/src
# EXCLUDES += tests/java/com/apple/jobjc
EXCLUDES += com/apple/jobjc
endif
# The security classes should not end up in the classes directory as that will prevent them
......@@ -354,44 +349,6 @@ $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin:
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
#
# JObjC.jar is compiled with BOOT_JAVAC which (may) not support the "-h" flag.
# so we first compile classes with BOOT_JAVAC and then with JDK_JAVAC :-(
#
$(eval $(call SetupJavaCompiler,GENERATE_15BYTECODE, \
JAVAC := $(JAVAC), \
FLAGS := -source 1.5 -target 1.5 -g -bootclasspath $(BOOT_RTJAR) -cp $(JDK_OUTPUTDIR)/../langtools/dist/lib/classes.jar $(DISABLE_WARNINGS), \
SERVER_DIR := $(SJAVAC_SERVER_DIR), \
SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
$(eval $(call SetupJavaCompilation,BUILD_JOBJC, \
SETUP := GENERATE_15BYTECODE, \
DISABLE_SJAVAC := true, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc, \
EXCLUDES := tests/java/com/apple/jobjc, \
BIN := $(JDK_OUTPUTDIR)/jobjc_classes, \
JAR := $(JDK_OUTPUTDIR)/lib/JObjC.jar, \
JARINDEX := true))
$(BUILD_JOBJC): $(BUILD_JDK)
$(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS, \
SETUP := GENERATE_JDKBYTECODE, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc, \
EXCLUDES := tests/java/com/apple/jobjc, \
BIN := $(JDK_OUTPUTDIR)/jobjc_classes_headers, \
HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers_jobjc))
$(BUILD_JOBJC_HEADERS): $(BUILD_JDK)
endif
##########################################################################################
......
......@@ -693,13 +693,6 @@ $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar: $(JDK_OUTPUTDIR)/demo/nio/zipfs/zipfs.jar
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
$(eval $(call SetupArchive,BUILD_JOBJC_JAR, , \
SRCS := $(JDK_OUTPUTDIR)/jobjc_classes, \
JAR := $(IMAGES_OUTPUTDIR)/lib/JObjC.jar, \
JARINDEX := true))
endif
# This file is imported from hotspot in Import.gmk. Copying it into images/lib so that
# all jars can be found in one place when creating images in Images.gmk. It needs to be
# done here so that clean targets can be simple and accurate.
......
......@@ -85,11 +85,6 @@ GENSRC += $(GENSRC_CLDR)
include gensrc/GensrcSwing.gmk
GENSRC += $(GENSRC_SWING_BEANINFO) $(GENSRC_SWING_NIMBUS)
ifeq ($(OPENJDK_TARGET_OS), macosx)
include gensrc/GensrcJObjC.gmk
GENSRC += $(GENSRC_JOBJC)
endif
$(GENSRC): $(BUILD_TOOLS)
all: $(GENSRC)
......
......@@ -303,14 +303,13 @@ $(JDK_IMAGE_DIR)/jre/lib/applet:
$(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(MKDIR) -p $@
# In the old build, JObjC.jar is not part of the meta-index
$(JRE_IMAGE_DIR)/lib/meta-index: $(JRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index `$(LS) *.jar | $(SED) 's/JObjC\.jar//g'`
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index *.jar
$(JDK_IMAGE_DIR)/jre/lib/meta-index: $(JDKJRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index `$(LS) *.jar | $(SED) 's/JObjC\.jar//g'`
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index *.jar
$(JRE_IMAGE_DIR)/lib/ext/meta-index: $(JRE_LIB_TARGETS)
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
......@@ -326,6 +325,7 @@ $(JDK_IMAGE_DIR)/jre/lib/ext/meta-index: $(JDKJRE_LIB_TARGETS)
ifneq ($(OPENJDK_TARGET_OS), windows)
JRE_MAN_PAGES := \
java.1 \
jjs.1 \
keytool.1 \
orbd.1 \
pack200.1 \
......@@ -356,6 +356,7 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
jconsole.1 \
jcmd.1 \
jdb.1 \
jdeps.1 \
jhat.1 \
jinfo.1 \
jmap.1 \
......@@ -374,7 +375,10 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
xjc.1
ifndef OPENJDK
JDK_MAN_PAGES += jvisualvm.1
JDK_MAN_PAGES += \
jvisualvm.1 \
jmc.1 \
#
endif
# This variable is potentially overridden in the closed makefile.
......@@ -387,15 +391,13 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
ifeq ($(OPENJDK_TARGET_OS), solaris)
MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/solaris/doc
MAN1_SUBDIR := sun/man/man1
JDK_MAN_PAGES := $(filter-out jmc.1, $(JDK_MAN_PAGES))
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/bsd/doc
MAN1_SUBDIR := man
JDK_MAN_PAGES := $(filter-out jcmd.1, $(JDK_MAN_PAGES))
JDK_MAN_PAGES := $(filter-out jvisualvm.1, $(JDK_MAN_PAGES))
endif
$(JRE_IMAGE_DIR)/man/man1/%: $(MAN_SRC_DIR)/$(MAN1_SUBDIR)/%
$(ECHO) $(LOG_INFO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(install-file)
......@@ -474,7 +476,7 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
JDK_MAN_PAGE_LIST := $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \
$(addprefix $(JDK_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JDK_MAN_PAGES)) \
$(JDK_IMAGE_DIR)/man/ja
$(JDK_IMAGE_DIR)/man/ja
endif
ifeq ($(OPENJDK_TARGET_OS), solaris)
......
......@@ -105,10 +105,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
endif
ifeq ($(PROFILE), profile_1)
PROFILE_JARS := $(PROFILE_1_JARS)
else ifeq ($(PROFILE), profile_2)
......
......@@ -77,7 +77,7 @@ $(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) \
$(ECHO) Generating beaninfo
$(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing
$(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 \
-x $(SWINGBEAN_DEBUG_FLAG) -d $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing \
-t $(DOCLET_DATA_DIR)/SwingBeanInfo.template -docletpath $(JDK_OUTPUTDIR)/btclasses \
......
......@@ -25,6 +25,7 @@
LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/share/native/java/net \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/ \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/dns \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/spi
......
......@@ -136,64 +136,6 @@ endif
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
$(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC32, \
LIBRARY := JObjC, \
OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := -fpascal-strings \
-fobjc-gc \
-gdwarf-2 \
$(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-m32, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
-m32, \
LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-lffi, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
$(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC64, \
LIBRARY := JObjC, \
OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := -fpascal-strings \
-fobjc-gc \
-gdwarf-2 \
$(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
, \
LDFLAGS := -fpascal-strings \
-fobjc-gc \
-gdwarf-2 \
$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-lffi, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
$(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX): $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64)
$(LIPO) -create -output $@ $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64)
BUILD_LIBRARIES += $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX)
endif
##########################################################################################
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
......
......@@ -86,6 +86,8 @@ SUNWprivate_1.1 {
Java_java_net_PlainSocketImpl_socketConnect;
Java_java_net_PlainDatagramSocketImpl_getTimeToLive;
Java_java_net_PlainDatagramSocketImpl_setTimeToLive;
Java_sun_net_PortConfig_getUpper0;
Java_sun_net_PortConfig_getLower0;
Java_sun_net_dns_ResolverConfigurationImpl_localDomain0;
Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0;
Java_sun_net_sdp_SdpSupport_convert0;
......
." 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) {
SplashUnlock(splash);
rc = poll(pfd, 1, timeout);
SplashLock(splash);
if (splash->isVisible>0 && SplashTime() >= splash->time +
splash->frames[splash->currentFrame].delay) {
if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
SplashNextFrame(splash);
SplashRedrawWindow(splash);
}
......
......@@ -29,6 +29,7 @@ import com.sun.beans.finder.ClassFinder;
import java.beans.ExceptionListener;
import java.io.IOException;
import java.io.StringReader;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
......@@ -245,6 +246,14 @@ public final class DocumentHandler extends DefaultHandler {
this.objects.add(object);
}
/**
* Disables any external entities.
*/
@Override
public InputSource resolveEntity(String publicId, String systemId) {
return new InputSource(new StringReader(""));
}
/**
* Prepares this handler to read objects from XML document.
*/
......
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -72,13 +72,17 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
throw new IllegalStateException(
"TlsRsaPremasterSecretGenerator must be initialized");
}
if (random == null) {
random = new SecureRandom();
byte[] b = spec.getEncodedSecret();
if (b == null) {
if (random == null) {
random = new SecureRandom();
}
b = new byte[48];
random.nextBytes(b);
b[0] = (byte)spec.getMajorVersion();
b[1] = (byte)spec.getMinorVersion();
}
byte[] b = new byte[48];
random.nextBytes(b);
b[0] = (byte)spec.getMajorVersion();
b[1] = (byte)spec.getMinorVersion();
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
}
......
......@@ -27,17 +27,9 @@ package com.sun.jmx.snmp.agent;
// java imports
//
import com.sun.jmx.snmp.SnmpDefinitions;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Enumeration;
// jmx imports
//
import com.sun.jmx.snmp.SnmpValue;
import com.sun.jmx.snmp.SnmpVarBind;
import com.sun.jmx.snmp.SnmpStatusException;
import com.sun.jmx.snmp.agent.SnmpMibOid;
import com.sun.jmx.snmp.agent.SnmpMibNode;
/**
* Represents a node in an SNMP MIB which corresponds to a table entry
......@@ -99,7 +91,9 @@ public abstract class SnmpMibEntry extends SnmpMibNode
*/
public void validateVarId(long arc, Object userData)
throws SnmpStatusException {
if (isVariable(arc) == false) throw noSuchNameException;
if (isVariable(arc) == false) {
throw new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
}
}
/**
......
......@@ -108,8 +108,9 @@ public abstract class SnmpMibGroup extends SnmpMibOid
*/
public void validateVarId(long arc, Object userData)
throws SnmpStatusException {
if (isVariable(arc) == false)
throw noSuchObjectException;
if (isVariable(arc) == false) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
}
......@@ -360,17 +361,20 @@ public abstract class SnmpMibGroup extends SnmpMibOid
validateVarId(arc, data);
// The trailing .0 is missing in the OID
if (depth+2 > length)
throw noSuchInstanceException;
if (depth+2 > length) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// There are too many arcs left in the OID (there should remain
// a single trailing .0)
if (depth+2 < length)
throw noSuchInstanceException;
if (depth+2 < length) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// The last trailing arc is not .0
if (oid[depth+1] != 0L)
throw noSuchInstanceException;
if (oid[depth+1] != 0L) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// It's one of our variable, register this node.
handlers.add(this,depth,varbind);
......@@ -389,12 +393,13 @@ public abstract class SnmpMibGroup extends SnmpMibOid
int length = oid.length;
SnmpMibNode node = null;
if (handlers == null)
if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
......@@ -430,7 +435,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
depth+1,handlers,
checker);
}catch(SnmpStatusException ex) {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} finally {
checker.remove(depth);
}
......@@ -455,7 +460,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
try {
checker.checkCurrentOid();
} catch(SnmpStatusException e) {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} finally {
checker.remove(depth,2);
}
......@@ -500,7 +505,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
// The oid is not valid, we will throw an exception in order
// to try with the next valid identifier...
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} catch (SnmpStatusException e) {
// We didn't find anything at the given arc, so we're going
......
......@@ -155,7 +155,7 @@ public abstract class SnmpMibNode implements Serializable {
long[] oid, int depth,
SnmpRequestTree handlers)
throws SnmpStatusException {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
/**
......@@ -183,7 +183,7 @@ public abstract class SnmpMibNode implements Serializable {
long[] oid, int pos, int depth,
SnmpRequestTree handlers, AcmChecker checker)
throws SnmpStatusException {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
/**
......@@ -346,8 +346,9 @@ public abstract class SnmpMibNode implements Serializable {
final int[] a = table;
final int val= (int) value;
if (a == null)
throw noSuchObjectException;
if (a == null) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
int low= 0;
int max= a.length;
......@@ -356,11 +357,13 @@ public abstract class SnmpMibNode implements Serializable {
// Basic check
//
if (max < 1)
throw noSuchObjectException;
if (max < 1) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (a[max-1] <= val)
throw noSuchObjectException;
if (a[max-1] <= val) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
while (low <= max) {
elmt= a[curr];
......@@ -400,15 +403,4 @@ public abstract class SnmpMibNode implements Serializable {
* Contains the list of variable identifiers.
*/
protected int[] varList;
/**
* Contains a predefined exception that is often fired when an
* object is not found in the MIB.
*/
static final protected SnmpStatusException noSuchInstanceException =
new SnmpStatusException(SnmpStatusException.noSuchInstance);
static final protected SnmpStatusException noSuchObjectException =
new SnmpStatusException(SnmpStatusException.noSuchObject);
static final protected SnmpStatusException noSuchNameException =
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
}
......@@ -160,12 +160,10 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
if (depth > length) {
// Nothing is left... the oid is not valid
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (depth == length) {
// The oid is not complete...
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} else {
// Some children variable or subobject is being querried
// getChild() will raise an exception if no child is found.
......@@ -205,12 +203,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
final int length = oid.length;
SnmpMibNode node = null;
long[] result = null;
if (handlers == null)
if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
......@@ -235,7 +234,7 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
// SnmpOid result = null;
if (child == null) {
// shouldn't happen
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
// validateVarId(index);
// handlers.add(this,varbind,depth);
// result = new SnmpOid(0);
......@@ -444,11 +443,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
// first we need to retrieve the identifier in the list of children
//
final int pos= getInsertAt(id);
if (pos >= nbChildren)
throw noSuchObjectException;
if (pos >= nbChildren) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (varList[pos] != (int) id)
throw noSuchObjectException;
if (varList[pos] != (int) id) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// Access the node
//
......@@ -456,10 +457,11 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
try {
child = children.elementAtNonSync(pos);
} catch(ArrayIndexOutOfBoundsException e) {
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
if (child == null) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
if (child == null)
throw noSuchInstanceException;
return child;
}
......
......@@ -280,7 +280,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
SnmpVarBind var;
for (Enumeration<SnmpVarBind> e= r.getElements(); e.hasMoreElements();) {
var = e.nextElement();
r.registerGetException(var,noSuchInstanceException);
r.registerGetException(var,new SnmpStatusException(SnmpStatusException.noSuchInstance));
}
}
......@@ -1607,8 +1607,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
protected SnmpOid getNextOid(SnmpOid oid, Object userData)
throws SnmpStatusException {
if (size == 0)
throw noSuchInstanceException;
if (size == 0) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
final SnmpOid resOid = oid;
......@@ -1619,7 +1620,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
if (last.equals(resOid)) {
// Last element of the table ...
//
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// First find the oid. This will allow to speed up retrieval process
......@@ -1641,12 +1642,12 @@ public abstract class SnmpMibTable extends SnmpMibNode
// XX last = (SnmpOid) oids.elementAt(newPos);
last = tableoids[newPos];
} catch(ArrayIndexOutOfBoundsException e) {
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
} else {
// We are dealing with the last element of the table ..
//
throw noSuchInstanceException;
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
......@@ -1668,8 +1669,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
*/
protected SnmpOid getNextOid(Object userData)
throws SnmpStatusException {
if (size == 0)
throw noSuchInstanceException;
if (size == 0) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// XX return (SnmpOid) oids.firstElement();
return tableoids[0];
}
......@@ -1875,10 +1877,10 @@ public abstract class SnmpMibTable extends SnmpMibNode
// not support creation.
// We know that the entry does not exists if (isentry == false).
if (!hasEntry) {
if (!handlers.isCreationAllowed())
if (!handlers.isCreationAllowed()) {
// we're not doing a set
throw noSuchInstanceException;
else if (!isCreationEnabled())
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
} else if (!isCreationEnabled())
// we're doing a set but creation is disabled.
throw new
SnmpStatusException(SnmpStatusException.snmpRspNoAccess);
......@@ -1922,12 +1924,13 @@ public abstract class SnmpMibTable extends SnmpMibNode
int length = oid.length;
if (handlers == null)
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw noSuchObjectException;
if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
......@@ -1961,7 +1964,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
// so we won't find the next element in this table... (any
// element in this table will have a smaller OID)
//
throw noSuchObjectException;
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (oid[pos] < nodeId) {
// we must return the first leaf under the first columnar
// object, so we are back to our first case where pos was
......@@ -2051,8 +2054,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// in tables can't be properly supported (all rows
// must have the same holes)
//
if (skipEntryVariable(entryoid,var,data,pduVersion))
throw noSuchObjectException;
if (skipEntryVariable(entryoid,var,data,pduVersion)) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} catch(SnmpStatusException se) {
entryoid = getNextOid(data);
var = getNextVarEntryId(entryoid,var,data,pduVersion);
......@@ -2085,8 +2089,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// So we throw the exception.
// => will skip to next node in the MIB tree.
//
if (entryoid == null || var == -1 ) throw noSuchObjectException;
if (entryoid == null || var == -1 ) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// So here we know both the row (entryoid) and the column (var)
//
......@@ -2097,8 +2102,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// for this specific entry, it is not readable for any
// other entry => skip to next column.
//
if (!isReadableEntryId(entryoid,var,data))
throw noSuchObjectException;
if (!isReadableEntryId(entryoid,var,data)) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
// Prepare the result and the ACM checker.
//
......@@ -2161,8 +2167,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
// No need to continue, we throw an exception.
// => will skip to next node in the MIB tree.
//
if (entryoid == null || var == -1 )
throw noSuchObjectException;
if (entryoid == null || var == -1 ) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
}
}
......@@ -2182,14 +2189,15 @@ public abstract class SnmpMibTable extends SnmpMibNode
// Control the length of the oid
//
if (pos +2 >= length)
throw noSuchInstanceException;
if (pos +2 >= length) {
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
}
// Check that the entry identifier is specified
//
if (oid[pos] != nodeId)
throw noSuchObjectException;
if (oid[pos] != nodeId) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
}
// ----------------------------------------------------------------------
......
......@@ -1146,7 +1146,4 @@ class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions {
static final private String InterruptSysCallMsg =
"Interrupted system call";
static final private SnmpStatusException noSuchNameException =
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName) ;
}
......@@ -56,9 +56,12 @@ public final class FactoryEnumeration {
* references so as not to prevent GC of the class loader. Each
* weak reference is tagged with the factory's class name so the
* class can be reloaded if the reference is cleared.
*
* @param factories A non-null list
* @param loader The class loader of the list's contents
*
* This internal method is used with Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*/
FactoryEnumeration(List<NamedWeakReference<Object>> factories,
ClassLoader loader) {
......@@ -79,7 +82,8 @@ public final class FactoryEnumeration {
try {
if (answer == null) { // reload class if weak ref cleared
answer = Class.forName(className, true, loader);
Class<?> cls = Class.forName(className, true, loader);
answer = cls;
}
// Instantiate Class to get factory
answer = ((Class) answer).newInstance();
......
......@@ -53,21 +53,24 @@ import javax.naming.*;
final class VersionHelper12 extends VersionHelper {
private boolean getSystemPropsFailed = false;
VersionHelper12() {} // Disallow external from creating one of these.
// Disallow external from creating one of these.
VersionHelper12() {
}
public Class<?> loadClass(String className) throws ClassNotFoundException {
ClassLoader cl = getContextClassLoader();
return Class.forName(className, true, cl);
return loadClass(className, getContextClassLoader());
}
/**
* Package private.
*/
* Package private.
*
* This internal method is used with Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*/
Class<?> loadClass(String className, ClassLoader cl)
throws ClassNotFoundException {
return Class.forName(className, true, cl);
Class<?> cls = Class.forName(className, true, cl);
return cls;
}
/**
......@@ -75,13 +78,13 @@ final class VersionHelper12 extends VersionHelper {
* @param codebase A non-null, space-separated list of URL strings.
*/
public Class<?> loadClass(String className, String codebase)
throws ClassNotFoundException, MalformedURLException {
ClassLoader cl;
throws ClassNotFoundException, MalformedURLException {
ClassLoader parent = getContextClassLoader();
cl = URLClassLoader.newInstance(getUrlArray(codebase), parent);
ClassLoader cl =
URLClassLoader.newInstance(getUrlArray(codebase), parent);
return Class.forName(className, true, cl);
return loadClass(className, cl);
}
String getJndiProperty(final int i) {
......@@ -99,16 +102,12 @@ final class VersionHelper12 extends VersionHelper {
}
String[] getJndiProperties() {
if (getSystemPropsFailed) {
return null; // after one failure, don't bother trying again
}
Properties sysProps = AccessController.doPrivileged(
new PrivilegedAction<Properties>() {
public Properties run() {
try {
return System.getProperties();
} catch (SecurityException e) {
getSystemPropsFailed = true;
return null;
}
}
......@@ -173,17 +172,32 @@ final class VersionHelper12 extends VersionHelper {
return new InputStreamEnumeration(urls);
}
/**
* Package private.
*
* This internal method returns Thread Context Class Loader (TCCL),
* if null, returns the system Class Loader.
*
* Please don't expose this method as public.
*/
ClassLoader getContextClassLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
if (loader == null) {
// Don't use bootstrap class loader directly!
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}
}
);
}
/**
* Given an enumeration of URLs, an instance of this class represents
* an enumeration of their InputStreams. Each operation on the URL
......
......@@ -276,6 +276,11 @@ public abstract class SctpChannel
*
* @throws IOException
* If some other I/O error occurs
*
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/
public abstract SctpChannel bind(SocketAddress local)
throws IOException;
......
......@@ -382,7 +382,8 @@ public abstract class Canonicalizer11 extends CanonicalizerBase {
} else if (!isVisible(xmlns)) {
//There is a definition but the xmlns is not selected by the xpath.
//then xmlns=""
n = ns.addMappingAndRender(XMLNS, "", nullNode);
n = ns.addMappingAndRender(
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
}
//output the xmlns def if needed.
if (n != null) {
......
......@@ -327,7 +327,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase {
} else if (!isVisible(xmlns)) {
//There is a definition but the xmlns is not selected by the xpath.
//then xmlns=""
n = ns.addMappingAndRender(XMLNS, "", nullNode);
n = ns.addMappingAndRender(
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
}
//output the xmlns def if needed.
if (n != null) {
......
......@@ -292,7 +292,7 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
if (xmlns != null && !isVisible(xmlns)) {
// There is a definition but the xmlns is not selected by the
// xpath. then xmlns=""
ns.addMapping(XMLNS, "", nullNode);
ns.addMapping(XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
}
String prefix = null;
......
......@@ -34,8 +34,6 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
......@@ -49,6 +47,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
......@@ -64,8 +63,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
public static final String XMLNS = "xmlns";
protected static final AttrCompare COMPARE = new AttrCompare();
protected static final Attr nullNode;
// Make sure you clone the following mutable arrays before passing to
// potentially untrusted objects such as OutputStreams.
private static final byte[] END_PI = {'?','>'};
private static final byte[] BEGIN_PI = {'<','?'};
private static final byte[] END_COMM = {'-','-','>'};
......@@ -78,27 +78,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private static final byte[] LT = {'&','l','t',';'};
private static final byte[] END_TAG = {'<','/'};
private static final byte[] AMP = {'&','a','m','p',';'};
private static final byte[] equalsStr = {'=','\"'};
private static final byte[] EQUALS_STR = {'=','\"'};
protected static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
protected static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
static {
// The null xmlns definition.
try {
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
nullNode = documentBuilder.newDocument().createAttributeNS(Constants.NamespaceSpecNS, XMLNS);
nullNode.setValue("");
} catch (Exception e) {
throw new RuntimeException("Unable to create nullNode: " + e);
}
}
private List<NodeFilter> nodeFilter;
private boolean includeComments;
private Set<Node> xpathNodeSet;
/**
* The node to be skipped/excluded from the DOM tree
* in subtree canonicalizations.
......@@ -106,6 +96,11 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private Node excludeNode;
private OutputStream writer = new ByteArrayOutputStream();
/**
* The null xmlns definition.
*/
private Attr nullNode;
/**
* Constructor CanonicalizerBase
*
......@@ -310,7 +305,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
writer.write('>');
sibling = currentNode.getFirstChild();
if (sibling == null) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeStringToUtf8(name, writer);
writer.write('>');
//We finished with this level, pop to the previous definitions.
......@@ -328,7 +323,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
break;
}
while (sibling == null && parentNode != null) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>');
//We finished with this level, pop to the previous definitions.
......@@ -488,7 +483,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (sibling == null) {
if (currentNodeIsVisible) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeByte(name, writer, cache);
writer.write('>');
//We finished with this level, pop to the previous definitions.
......@@ -510,7 +505,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
}
while (sibling == null && parentNode != null) {
if (isVisible(parentNode)) {
writer.write(END_TAG);
writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>');
//We finished with this level, pop to the previous definitions.
......@@ -641,8 +636,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
parents.clear();
Attr nsprefix;
if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null)
&& "".equals(nsprefix.getValue())) {
ns.addMappingAndRender(XMLNS, "", nullNode);
&& "".equals(nsprefix.getValue())) {
ns.addMappingAndRender(
XMLNS, "", getNullNode(nsprefix.getOwnerDocument()));
}
}
......@@ -696,7 +692,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
) throws IOException {
writer.write(' ');
UtfHelpper.writeByte(name, writer, cache);
writer.write(equalsStr);
writer.write(EQUALS_STR.clone());
byte[] toWrite;
final int length = value.length();
int i = 0;
......@@ -706,27 +702,27 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) {
case '&' :
toWrite = AMP;
toWrite = AMP.clone();
break;
case '<' :
toWrite = LT;
toWrite = LT.clone();
break;
case '"' :
toWrite = QUOT;
toWrite = QUOT.clone();
break;
case 0x09 : // '\t'
toWrite = X9;
toWrite = X9.clone();
break;
case 0x0A : // '\n'
toWrite = XA;
toWrite = XA.clone();
break;
case 0x0D : // '\r'
toWrite = XD;
toWrite = XD.clone();
break;
default :
......@@ -756,7 +752,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n');
}
writer.write(BEGIN_PI);
writer.write(BEGIN_PI.clone());
final String target = currentPI.getTarget();
int length = target.length();
......@@ -764,7 +760,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) {
char c = target.charAt(i);
if (c == 0x0D) {
writer.write(XD);
writer.write(XD.clone());
} else {
if (c < 0x80) {
writer.write(c);
......@@ -784,14 +780,14 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) {
char c = data.charAt(i);
if (c == 0x0D) {
writer.write(XD);
writer.write(XD.clone());
} else {
UtfHelpper.writeCharToUtf8(c, writer);
}
}
}
writer.write(END_PI);
writer.write(END_PI.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n');
}
......@@ -810,7 +806,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n');
}
writer.write(BEGIN_COMM);
writer.write(BEGIN_COMM.clone());
final String data = currentComment.getData();
final int length = data.length();
......@@ -818,7 +814,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) {
char c = data.charAt(i);
if (c == 0x0D) {
writer.write(XD);
writer.write(XD.clone());
} else {
if (c < 0x80) {
writer.write(c);
......@@ -828,7 +824,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
}
}
writer.write(END_COMM);
writer.write(END_COMM.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n');
}
......@@ -852,19 +848,19 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) {
case '&' :
toWrite = AMP;
toWrite = AMP.clone();
break;
case '<' :
toWrite = LT;
toWrite = LT.clone();
break;
case '>' :
toWrite = GT;
toWrite = GT.clone();
break;
case 0xD :
toWrite = XD;
toWrite = XD.clone();
break;
default :
......@@ -879,4 +875,18 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
}
}
// The null xmlns definition.
protected Attr getNullNode(Document ownerDocument) {
if (nullNode == null) {
try {
nullNode = ownerDocument.createAttributeNS(
Constants.NamespaceSpecNS, XMLNS);
nullNode.setValue("");
} catch (Exception e) {
throw new RuntimeException("Unable to create nullNode: " + e);
}
}
return nullNode;
}
}
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -660,7 +660,7 @@ public class XmlReaderContentHandler extends DefaultHandler {
//Added the handling for Class tags to take care of maps
//Makes an entry into the map upon end of class tag
try{
typeMap.put(Key_map,Class.forName(Value_map));
typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map));
}catch(ClassNotFoundException ex) {
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));
......
......@@ -1114,11 +1114,8 @@ class SecurityManager {
* calling thread is not allowed to wait for a connection request on
* the specified local port number.
* <p>
* If port is not 0, this method calls
* <code>checkPermission</code> with the
* This method calls <code>checkPermission</code> with the
* <code>SocketPermission("localhost:"+port,"listen")</code>.
* If port is zero, this method calls <code>checkPermission</code>
* with <code>SocketPermission("localhost:1024-","listen").</code>
* <p>
* If you override this method, then you should make a call to
* <code>super.checkListen</code>
......@@ -1131,12 +1128,8 @@ class SecurityManager {
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkListen(int port) {
if (port == 0) {
checkPermission(SecurityConstants.LOCAL_LISTEN_PERMISSION);
} else {
checkPermission(new SocketPermission("localhost:"+port,
SecurityConstants.SOCKET_LISTEN_ACTION));
}
checkPermission(new SocketPermission("localhost:"+port,
SecurityConstants.SOCKET_LISTEN_ACTION));
}
/**
......
......@@ -638,6 +638,12 @@ class InvokerBytecodeGenerator {
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
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
......
......@@ -272,7 +272,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its
* {@code checkConnect} method doesn't allow the operation.
* {@code checkConnect} method doesn't allow the connection
* to the destination, or if its {@code checkListen} method
* doesn't allow the bind to the local port.
* @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
......@@ -311,7 +313,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its
* {@code checkConnect} method doesn't allow the operation.
* {@code checkConnect} method doesn't allow the connection
* to the destination, or if its {@code checkListen} method
* doesn't allow the bind to the local port.
* @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
......@@ -609,6 +613,9 @@ class Socket implements java.io.Closeable {
* is already bound.
* @throws IllegalArgumentException if bindpoint is a
* SocketAddress subclass not supported by this socket
* @throws SecurityException if a security manager exists and its
* {@code checkListen} method doesn't allow the bind
* to the local port.
*
* @since 1.4
* @see #isBound
......@@ -630,6 +637,10 @@ class Socket implements java.io.Closeable {
InetAddress addr = epoint.getAddress();
int port = epoint.getPort();
checkAddress (addr, "bind");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkListen(port);
}
getImpl().bind (addr, port);
bound = true;
}
......
......@@ -34,6 +34,9 @@ import java.util.StringTokenizer;
import java.net.InetAddress;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.Security;
import java.io.Serializable;
import java.io.ObjectStreamField;
import java.io.ObjectOutputStream;
......@@ -41,6 +44,7 @@ import java.io.ObjectInputStream;
import java.io.IOException;
import sun.net.util.IPAddressUtil;
import sun.net.RegisteredDomain;
import sun.net.PortConfig;
import sun.security.util.SecurityConstants;
import sun.security.util.Debug;
......@@ -89,6 +93,9 @@ import sun.security.util.Debug;
* form "N-", where <i>N</i> is a port number, signifies all ports
* numbered <i>N</i> and above, while a specification of the
* form "-N" indicates all ports numbered <i>N</i> and below.
* The special port value {@code 0} refers to the entire <i>ephemeral</i>
* port range. This is a fixed range of ports a system may use to
* allocate dynamic ports from. The actual range may be system dependent.
* <p>
* The possible ways to connect to the host are
* <pre>
......@@ -97,7 +104,8 @@ import sun.security.util.Debug;
* listen
* resolve
* </pre>
* The "listen" action is only meaningful when used with "localhost".
* The "listen" action is only meaningful when used with "localhost" and
* means the ability to bind to a specified port.
* The "resolve" action is implied when any of the other actions are present.
* The action "resolve" refers to host/ip name service lookups.
* <P>
......@@ -176,6 +184,7 @@ public final class SocketPermission extends Permission
private static final int PORT_MIN = 0;
private static final int PORT_MAX = 65535;
private static final int PRIV_PORT_MAX = 1023;
private static final int DEF_EPH_LOW = 49152;
// the actions mask
private transient int mask;
......@@ -226,6 +235,14 @@ public final class SocketPermission extends Permission
private static Debug debug = null;
private static boolean debugInit = false;
// ephemeral port range for this system
private static final int ephemeralLow = initEphemeralPorts(
"low", DEF_EPH_LOW
);
private static final int ephemeralHigh = initEphemeralPorts(
"high", PORT_MAX
);
static {
Boolean tmp = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
......@@ -359,6 +376,14 @@ public final class SocketPermission extends Permission
}
}
/**
* Returns true if the permission has specified zero
* as its value (or lower bound) signifying the ephemeral range
*/
private boolean includesEphemerals() {
return portrange[0] == 0;
}
/**
* Initialize the SocketPermission object. We don't do any DNS lookups
* as this point, instead we hold off until the implies method is
......@@ -850,10 +875,21 @@ public final class SocketPermission extends Permission
int i,j;
if ((that.mask & RESOLVE) != that.mask) {
// check port range
// check simple port range
if ((that.portrange[0] < this.portrange[0]) ||
(that.portrange[1] > this.portrange[1])) {
// if either includes the ephemeral range, do full check
if (this.includesEphemerals() || that.includesEphemerals()) {
if (!inRange(this.portrange[0], this.portrange[1],
that.portrange[0], that.portrange[1]))
{
return false;
}
} else {
return false;
}
}
}
......@@ -1168,6 +1204,75 @@ public final class SocketPermission extends Permission
init(getName(),getMask(actions));
}
/**
* Check the system/security property for the ephemeral port range
* for this system. The suffix is either "high" or "low"
*/
private static int initEphemeralPorts(String suffix, int defval) {
return AccessController.doPrivileged(
new PrivilegedAction<Integer>(){
public Integer run() {
int val = Integer.getInteger(
"jdk.net.ephemeralPortRange."+suffix, -1
);
if (val != -1) {
return val;
} else {
return suffix.equals("low") ?
PortConfig.getLower() : PortConfig.getUpper();
}
}
}
);
}
/**
* Check if the target range is within the policy range
* together with the ephemeral range for this platform
* (if policy includes ephemeral range)
*/
private static boolean inRange(
int policyLow, int policyHigh, int targetLow, int targetHigh
)
{
if (targetLow == 0) {
// check policy includes ephemeral range
if (!inRange(policyLow, policyHigh, ephemeralLow, ephemeralHigh)) {
return false;
}
if (targetHigh == 0) {
// nothing left to do
return true;
}
// continue check with first real port number
targetLow = 1;
}
if (policyLow == 0 && policyHigh == 0) {
// ephemeral range only
return targetLow >= ephemeralLow && targetHigh <= ephemeralHigh;
}
if (policyLow != 0) {
// simple check of policy only
return targetLow >= policyLow && targetHigh <= policyHigh;
}
// policyLow == 0 which means possibly two ranges to check
// first check if policy and ephem range overlap/contiguous
if (policyHigh >= ephemeralLow - 1) {
return targetHigh <= ephemeralHigh;
}
// policy and ephem range do not overlap
// target range must lie entirely inside policy range or eph range
return (targetLow <= policyHigh && targetHigh <= policyHigh) ||
(targetLow >= ephemeralLow && targetHigh <= ephemeralHigh);
}
/*
public String toString()
{
......
......@@ -200,6 +200,10 @@ public abstract class AsynchronousSocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/
@Override
public abstract AsynchronousSocketChannel bind(SocketAddress local)
......
......@@ -227,6 +227,10 @@ public abstract class SocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*
* @since 1.7
*/
......
......@@ -53,6 +53,13 @@ import sun.misc.SharedSecrets;
* or method in this class will cause a {@link NullPointerException} to be
* thrown.
*
* If the verify flag is on when opening a signed jar file, the content of the
* file is verified against its signature embedded inside the file. Please note
* that the verification process does not include validating the signer's
* certificate. A caller should inspect the return value of
* {@link JarEntry#getCodeSigners()} to further determine if the signature
* can be trusted.
*
* @author David Connelly
* @see Manifest
* @see java.util.zip.ZipFile
......
......@@ -179,7 +179,9 @@ class JarVerifier {
name = name.substring(1);
// only set the jev object for entries that have a signature
if (sigFileSigners.get(name) != null) {
// (either verified or not)
if (sigFileSigners.get(name) != null ||
verifiedSigners.get(name) != null) {
mev.setEntry(name, je);
return;
}
......
......@@ -248,6 +248,11 @@ public class LogManager {
* retrieved by calling LogManager.getLogManager.
*/
protected LogManager() {
this(checkSubclassPermissions());
}
private LogManager(Void checked) {
// Add a shutdown hook to close the global handlers.
try {
Runtime.getRuntime().addShutdownHook(new Cleaner());
......@@ -257,6 +262,19 @@ public class LogManager {
}
}
private static Void checkSubclassPermissions() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// These permission will be checked in the LogManager constructor,
// in order to register the Cleaner() thread as a shutdown hook.
// Check them here to avoid the penalty of constructing the object
// etc...
sm.checkPermission(new RuntimePermission("shutdownHooks"));
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
return null;
}
/**
* Lazy initialization: if this instance of manager is the global
* manager then this method will read the initial configuration and
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -446,7 +446,7 @@ abstract class DoublePipeline<E_IN>
@Override
public final long count() {
return mapToObj(e -> null).mapToInt(e -> 1).sum();
return mapToLong(e -> 1L).sum();
}
@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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -426,7 +426,7 @@ abstract class IntPipeline<E_IN>
@Override
public final long count() {
return asLongStream().map(e -> 1L).sum();
return mapToLong(e -> 1L).sum();
}
@Override
......
......@@ -91,7 +91,10 @@ public final class SimpleDoc implements Doc {
Class repClass = null;
try {
repClass = Class.forName(flavor.getRepresentationClassName());
String className = flavor.getRepresentationClassName();
sun.reflect.misc.ReflectUtil.checkPackageAccess(className);
repClass = Class.forName(className, false,
Thread.currentThread().getContextClassLoader());
} catch (Throwable e) {
throw new IllegalArgumentException("unknown representation class");
}
......
......@@ -26,6 +26,10 @@
package javax.security.auth;
import java.security.Security;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import sun.security.util.Debug;
/**
......@@ -155,22 +159,15 @@ import sun.security.util.Debug;
public abstract class Policy {
private static Policy policy;
private static ClassLoader contextClassLoader;
private final static String AUTH_POLICY =
"sun.security.provider.AuthPolicyFile";
private final java.security.AccessControlContext acc =
java.security.AccessController.getContext();
// true if a custom (not AUTH_POLICY) system-wide policy object is set
private static boolean isCustomPolicy;
static {
contextClassLoader = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
};
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
......@@ -213,8 +210,8 @@ public abstract class Policy {
if (policy == null) {
String policy_class = null;
policy_class = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<String>() {
policy_class = AccessController.doPrivileged
(new PrivilegedAction<String>() {
public String run() {
return java.security.Security.getProperty
("auth.policy.provider");
......@@ -226,18 +223,28 @@ public abstract class Policy {
try {
final String finalClass = policy_class;
policy = java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Policy>() {
public Policy run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
return (Policy) Class.forName
(finalClass,
true,
contextClassLoader).newInstance();
}
});
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
Policy untrustedImpl = AccessController.doPrivileged(
new PrivilegedExceptionAction<Policy>() {
public Policy run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class<? extends Policy> implClass = Class.forName(
finalClass, false,
Thread.currentThread().getContextClassLoader()
).asSubclass(Policy.class);
return implClass.newInstance();
}
});
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() {
setPolicy(untrustedImpl);
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
return null;
}
}, Objects.requireNonNull(untrustedImpl.acc)
);
} catch (Exception e) {
throw new SecurityException
(sun.security.util.ResourcesMgr.getString
......
......@@ -964,6 +964,10 @@ public final class Subject implements java.io.Serializable {
s.defaultReadObject();
// Rewrap the principals into a SecureSet
principals = Collections.synchronizedSet(new SecureSet<Principal>
(this, PRINCIPAL_SET, principals));
// The Credential {@code Set} is not serialized, but we do not
// want the default deserialization routine to set it to null.
this.pubCredentials = Collections.synchronizedSet
......
......@@ -27,9 +27,6 @@ package javax.security.auth.login;
import javax.security.auth.AuthPermission;
import java.io.*;
import java.util.*;
import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
......@@ -38,7 +35,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;
import java.security.SecurityPermission;
import java.util.Objects;
import sun.security.jca.GetInstance;
......@@ -191,16 +188,9 @@ import sun.security.jca.GetInstance;
public abstract class Configuration {
private static Configuration configuration;
private static ClassLoader contextClassLoader;
static {
contextClassLoader = AccessController.doPrivileged
(new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
};
private final java.security.AccessControlContext acc =
java.security.AccessController.getContext();
private static void checkPermission(String type) {
SecurityManager sm = System.getSecurityManager();
......@@ -253,17 +243,26 @@ public abstract class Configuration {
try {
final String finalClass = config_class;
configuration = AccessController.doPrivileged
(new PrivilegedExceptionAction<Configuration>() {
public Configuration run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
return (Configuration)Class.forName
(finalClass,
true,
contextClassLoader).newInstance();
}
});
Configuration untrustedImpl = AccessController.doPrivileged(
new PrivilegedExceptionAction<Configuration>() {
public Configuration run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class<? extends Configuration> implClass = Class.forName(
finalClass, false,
Thread.currentThread().getContextClassLoader()
).asSubclass(Configuration.class);
return implClass.newInstance();
}
});
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() {
setConfiguration(untrustedImpl);
return null;
}
}, Objects.requireNonNull(untrustedImpl.acc)
);
} catch (PrivilegedActionException e) {
Exception ee = e.getException();
if (ee instanceof InstantiationException) {
......
......@@ -209,8 +209,7 @@ public class LoginContext {
private Map<String,?> state = new HashMap<String,Object>();
private Configuration config;
private boolean configProvided = false;
private AccessControlContext creatorAcc = null;
private AccessControlContext creatorAcc = null; // customized config only
private ModuleInfo[] moduleStack;
private ClassLoader contextClassLoader = null;
private static final Class<?>[] PARAMS = { };
......@@ -229,7 +228,7 @@ public class LoginContext {
private void init(String name) throws LoginException {
SecurityManager sm = System.getSecurityManager();
if (sm != null && !configProvided) {
if (sm != null && creatorAcc == null) {
sm.checkPermission(new AuthPermission
("createLoginContext." + name));
}
......@@ -252,7 +251,7 @@ public class LoginContext {
AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
if (entries == null) {
if (sm != null && !configProvided) {
if (sm != null && creatorAcc == null) {
sm.checkPermission(new AuthPermission
("createLoginContext." + OTHER));
}
......@@ -279,7 +278,15 @@ public class LoginContext {
contextClassLoader = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
if (loader == null) {
// Don't use bootstrap class loader directly to ensure
// proper package access control!
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}
});
}
......@@ -298,10 +305,10 @@ public class LoginContext {
(DEFAULT_HANDLER);
if (defaultHandler == null || defaultHandler.length() == 0)
return null;
Class<?> c = Class.forName(defaultHandler,
true,
finalLoader);
return (CallbackHandler)c.newInstance();
Class<? extends CallbackHandler> c = Class.forName(
defaultHandler, true,
finalLoader).asSubclass(CallbackHandler.class);
return c.newInstance();
}
});
} catch (java.security.PrivilegedActionException pae) {
......@@ -309,7 +316,7 @@ public class LoginContext {
}
// secure it with the caller's ACC
if (this.callbackHandler != null && !configProvided) {
if (this.callbackHandler != null && creatorAcc == null) {
this.callbackHandler = new SecureCallbackHandler
(java.security.AccessController.getContext(),
this.callbackHandler);
......@@ -498,8 +505,7 @@ public class LoginContext {
CallbackHandler callbackHandler,
Configuration config) throws LoginException {
this.config = config;
configProvided = (config != null) ? true : false;
if (configProvided) {
if (config != null) {
creatorAcc = java.security.AccessController.getContext();
}
......@@ -510,7 +516,7 @@ public class LoginContext {
}
if (callbackHandler == null) {
loadDefaultCallbackHandler();
} else if (!configProvided) {
} else if (creatorAcc == null) {
this.callbackHandler = new SecureCallbackHandler
(java.security.AccessController.getContext(),
callbackHandler);
......@@ -577,23 +583,13 @@ public class LoginContext {
}
try {
if (configProvided) {
// module invoked in doPrivileged with creatorAcc
invokeCreatorPriv(LOGIN_METHOD);
invokeCreatorPriv(COMMIT_METHOD);
} else {
// module invoked in doPrivileged
invokePriv(LOGIN_METHOD);
invokePriv(COMMIT_METHOD);
}
// module invoked in doPrivileged
invokePriv(LOGIN_METHOD);
invokePriv(COMMIT_METHOD);
loginSucceeded = true;
} catch (LoginException le) {
try {
if (configProvided) {
invokeCreatorPriv(ABORT_METHOD);
} else {
invokePriv(ABORT_METHOD);
}
invokePriv(ABORT_METHOD);
} catch (LoginException le2) {
throw le;
}
......@@ -628,13 +624,8 @@ public class LoginContext {
("null.subject.logout.called.before.login"));
}
if (configProvided) {
// module invoked in doPrivileged with creatorAcc
invokeCreatorPriv(LOGOUT_METHOD);
} else {
// module invoked in doPrivileged
invokePriv(LOGOUT_METHOD);
}
// module invoked in doPrivileged
invokePriv(LOGOUT_METHOD);
}
/**
......@@ -677,35 +668,13 @@ public class LoginContext {
/**
* Invokes the login, commit, and logout methods
* from a LoginModule inside a doPrivileged block.
* from a LoginModule inside a doPrivileged block restricted
* by creatorAcc (may be null).
*
* This version is called if the caller did not instantiate
* the LoginContext with a Configuration object.
*/
private void invokePriv(final String methodName) throws LoginException {
try {
java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Void>() {
public Void run() throws LoginException {
invoke(methodName);
return null;
}
});
} catch (java.security.PrivilegedActionException pae) {
throw (LoginException)pae.getException();
}
}
/**
* Invokes the login, commit, and logout methods
* from a LoginModule inside a doPrivileged block restricted
* by creatorAcc
*
* This version is called if the caller instantiated
* the LoginContext with a Configuration object.
*/
private void invokeCreatorPriv(final String methodName)
throws LoginException {
try {
java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction<Void>() {
......@@ -735,24 +704,24 @@ public class LoginContext {
} else {
// instantiate the LoginModule
Class<?> c = Class.forName
(moduleStack[i].entry.getLoginModuleName(),
//
// Allow any object to be a LoginModule as long as it
// conforms to the interface.
Class<?> c = Class.forName(
moduleStack[i].entry.getLoginModuleName(),
true,
contextClassLoader);
Constructor<?> constructor = c.getConstructor(PARAMS);
Object[] args = { };
// allow any object to be a LoginModule
// as long as it conforms to the interface
moduleStack[i].module = constructor.newInstance(args);
methods = moduleStack[i].module.getClass().getMethods();
// call the LoginModule's initialize method
methods = moduleStack[i].module.getClass().getMethods();
for (mIndex = 0; mIndex < methods.length; mIndex++) {
if (methods[mIndex].getName().equals(INIT_METHOD))
if (methods[mIndex].getName().equals(INIT_METHOD)) {
break;
}
}
Object[] initArgs = {subject,
......@@ -760,19 +729,28 @@ public class LoginContext {
state,
moduleStack[i].entry.getOptions() };
// invoke the LoginModule initialize method
//
// Throws ArrayIndexOutOfBoundsException if no such
// method defined. May improve to use LoginException in
// the future.
methods[mIndex].invoke(moduleStack[i].module, initArgs);
}
// find the requested method in the LoginModule
for (mIndex = 0; mIndex < methods.length; mIndex++) {
if (methods[mIndex].getName().equals(methodName))
if (methods[mIndex].getName().equals(methodName)) {
break;
}
}
// set up the arguments to be passed to the LoginModule method
Object[] args = { };
// invoke the LoginModule method
//
// Throws ArrayIndexOutOfBoundsException if no such
// method defined. May improve to use LoginException in
// the future.
boolean status = ((Boolean)methods[mIndex].invoke
(moduleStack[i].module, args)).booleanValue();
......
......@@ -35,6 +35,8 @@ import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.naming.*;
......@@ -348,7 +350,17 @@ public class SyncFactory {
/*
* Dependent on application
*/
String strRowsetProperties = System.getProperty("rowset.properties");
String strRowsetProperties;
try {
strRowsetProperties = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("rowset.properties");
}
}, null, new PropertyPermission("rowset.properties","read"));
} catch (Exception ex) {
strRowsetProperties = null;
}
if (strRowsetProperties != null) {
// Load user's implementation of SyncProvider
// here. -Drowset.properties=/abc/def/pqr.txt
......@@ -393,7 +405,16 @@ public class SyncFactory {
* load additional properties from -D command line
*/
properties.clear();
String providerImpls = System.getProperty(ROWSET_SYNC_PROVIDER);
String providerImpls;
try {
providerImpls = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(ROWSET_SYNC_PROVIDER);
}
}, null, new PropertyPermission(ROWSET_SYNC_PROVIDER,"read"));
} catch (Exception ex) {
providerImpls = null;
}
if (providerImpls != null) {
int i = 0;
......
......@@ -24,6 +24,7 @@
*/
package javax.swing;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2;
import sun.swing.UIAction;
......@@ -33,9 +34,6 @@ import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.DropTarget;
import java.util.Vector;
import java.util.Hashtable;
import java.lang.reflect.*;
import javax.accessibility.*;
......@@ -1872,6 +1870,7 @@ public class SwingUtilities implements SwingConstants
static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
ReflectUtil.checkPackageAccess(className);
return Class.forName(className, true, Thread.currentThread().
getContextClassLoader());
}
......
......@@ -27,6 +27,7 @@ package javax.swing.event;
import java.io.*;
import java.util.*;
import java.lang.reflect.Array;
import sun.reflect.misc.ReflectUtil;
/**
* A class that holds a list of EventListeners. A single instance
......@@ -271,7 +272,9 @@ public class EventListenerList implements Serializable {
while (null != (listenerTypeOrNull = s.readObject())) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
EventListener l = (EventListener)s.readObject();
add((Class<EventListener>)Class.forName((String)listenerTypeOrNull, true, cl), l);
String name = (String) listenerTypeOrNull;
ReflectUtil.checkPackageAccess(name);
add((Class<EventListener>)Class.forName(name, true, cl), l);
}
}
......
......@@ -428,6 +428,10 @@ abstract class AsynchronousSocketChannelImpl
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
......
......@@ -572,6 +572,10 @@ class SocketChannelImpl
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
......
......@@ -28,7 +28,10 @@ package sun.reflect.generics.reflectiveObjects;
import java.lang.annotation.*;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.LinkedHashMap;
......@@ -40,6 +43,7 @@ import sun.reflect.annotation.AnnotationType;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.misc.ReflectUtil;
/**
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
......@@ -95,6 +99,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
TypeVariableImpl<T> make(T decl, String name,
FieldTypeSignature[] bs,
GenericsFactory f) {
if (!((decl instanceof Class) ||
(decl instanceof Method) ||
(decl instanceof Constructor))) {
throw new AssertionError("Unexpected kind of GenericDeclaration" +
decl.getClass().toString());
}
return new TypeVariableImpl<T>(decl, name, bs, f);
}
......@@ -149,6 +160,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
* @since 1.5
*/
public D getGenericDeclaration(){
if (genericDeclaration instanceof Class)
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
else if ((genericDeclaration instanceof Method) ||
(genericDeclaration instanceof Constructor))
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration);
else
throw new AssertionError("Unexpected kind of GenericDeclaration");
return genericDeclaration;
}
......@@ -164,7 +182,8 @@ public class TypeVariableImpl<D extends GenericDeclaration>
@Override
public boolean equals(Object o) {
if (o instanceof TypeVariable) {
if (o instanceof TypeVariable &&
o.getClass() == TypeVariableImpl.class) {
TypeVariable<?> that = (TypeVariable<?>) o;
GenericDeclaration thatDecl = that.getGenericDeclaration();
......
......@@ -26,11 +26,13 @@
package sun.reflect.misc;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
public final class ReflectUtil {
......@@ -117,6 +119,40 @@ public final class ReflectUtil {
return false;
}
/**
* Does a conservative approximation of member access check. Use this if
* you don't have an actual 'userland' caller Class/ClassLoader available.
* This might be more restrictive than a precise member access check where
* you have a caller, but should never allow a member access that is
* forbidden.
*
* @param m the {@code Member} about to be accessed
*/
public static void conservativeCheckMemberAccess(Member m) throws SecurityException{
final SecurityManager sm = System.getSecurityManager();
if (sm == null)
return;
// Check for package access on the declaring class.
//
// In addition, unless the member and the declaring class are both
// public check for access declared member permissions.
//
// This is done regardless of ClassLoader relations between the {@code
// Member m} and any potential caller.
final Class<?> declaringClass = m.getDeclaringClass();
checkPackageAccess(declaringClass);
if (Modifier.isPublic(m.getModifiers()) &&
Modifier.isPublic(declaringClass.getModifiers()))
return;
// Check for declared member access.
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
/**
* Checks package access on the given class.
*
......
......@@ -94,8 +94,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
RMIServerSocketFactory ssf)
throws RemoteException
{
LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref));
if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) {
// grant permission for default port only.
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws RemoteException {
LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref));
return null;
}
}, null, new SocketPermission("localhost:"+port, "listen,accept"));
} catch (PrivilegedActionException pae) {
throw (RemoteException)pae.getException();
}
} else {
LiveRef lref = new LiveRef(id, port, csf, ssf);
setup(new UnicastServerRef2(lref));
}
}
/**
......@@ -104,8 +119,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl(int port)
throws RemoteException
{
LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref));
if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) {
// grant permission for default port only.
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws RemoteException {
LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref));
return null;
}
}, null, new SocketPermission("localhost:"+port, "listen,accept"));
} catch (PrivilegedActionException pae) {
throw (RemoteException)pae.getException();
}
} else {
LiveRef lref = new LiveRef(id, port);
setup(new UnicastServerRef(lref));
}
}
/*
......@@ -352,7 +382,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl run() throws RemoteException {
return new RegistryImpl(regPort);
}
}, getAccessControlContext());
}, getAccessControlContext(regPort));
} catch (PrivilegedActionException ex) {
throw (RemoteException) ex.getException();
}
......@@ -382,7 +412,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* The approach used here is taken from the similar method
* getAccessControlContext() in the sun.applet.AppletPanel class.
*/
private static AccessControlContext getAccessControlContext() {
private static AccessControlContext getAccessControlContext(int port) {
// begin with permissions granted to all code in current policy
PermissionCollection perms = AccessController.doPrivileged(
new java.security.PrivilegedAction<PermissionCollection>() {
......@@ -404,6 +434,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* related classes themselves are more tightly limited by RMI.
*/
perms.add(new SocketPermission("*", "connect,accept"));
perms.add(new SocketPermission("localhost:"+port, "listen,accept"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*"));
......
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -45,11 +45,12 @@ public class TlsRsaPremasterSecretParameterSpec
private final int majorVersion;
private final int minorVersion;
private final byte[] encodedSecret;
/**
* Constructs a new TlsRsaPremasterSecretParameterSpec.
*
* <p>The version numbers will be placed inside the premaster secret to
* <P>
* The version numbers will be placed inside the premaster secret to
* detect version rollbacks attacks as described in the TLS specification.
* Note that they do not indicate the protocol version negotiated for
* the handshake.
......@@ -65,7 +66,42 @@ public class TlsRsaPremasterSecretParameterSpec
this.majorVersion =
TlsMasterSecretParameterSpec.checkVersion(majorVersion);
this.minorVersion =
TlsMasterSecretParameterSpec.checkVersion(minorVersion); }
TlsMasterSecretParameterSpec.checkVersion(minorVersion);
this.encodedSecret = null;
}
/**
* Constructs a new TlsRsaPremasterSecretParameterSpec.
* <P>
* The version numbers will be placed inside the premaster secret to
* detect version rollbacks attacks as described in the TLS specification.
* Note that they do not indicate the protocol version negotiated for
* the handshake.
* <P>
* Usually, the encoded secret key is a random number that acts as
* dummy pre_master_secret to avoid vulnerabilities described by
* section 7.4.7.1, RFC 5246.
*
* @param majorVersion the major number of the protocol version
* @param minorVersion the minor number of the protocol version
* @param encodedSecret the encoded secret key
*
* @throws IllegalArgumentException if minorVersion or majorVersion are
* negative or larger than 255, or encodedSecret is not exactly 48 bytes.
*/
public TlsRsaPremasterSecretParameterSpec(int majorVersion,
int minorVersion, byte[] encodedSecret) {
this.majorVersion =
TlsMasterSecretParameterSpec.checkVersion(majorVersion);
this.minorVersion =
TlsMasterSecretParameterSpec.checkVersion(minorVersion);
if (encodedSecret == null || encodedSecret.length != 48) {
throw new IllegalArgumentException(
"Encoded secret is not exactly 48 bytes");
}
this.encodedSecret = encodedSecret.clone();
}
/**
* Returns the major version.
......@@ -84,4 +120,13 @@ public class TlsRsaPremasterSecretParameterSpec
public int getMinorVersion() {
return minorVersion;
}
/**
* Returns the encoded secret.
*
* @return the encoded secret, may be null if no encoded secret.
*/
public byte[] getEncodedSecret() {
return encodedSecret == null ? null : encodedSecret.clone();
}
}
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -451,30 +451,7 @@ final class P11RSACipher extends CipherSpi {
// see JCE spec
protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
int type) throws InvalidKeyException, NoSuchAlgorithmException {
if (algorithm.equals("TlsRsaPremasterSecret")) {
// the instance variable "session" has been initialized for
// decrypt mode, so use a local variable instead.
Session s = null;
try {
s = token.getObjSession();
long keyType = CKK_GENERIC_SECRET;
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
};
attributes = token.getAttributes
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_UnwrapKey(s.id(),
new CK_MECHANISM(mechanism), p11Key.keyID, wrappedKey,
attributes);
return P11Key.secretKey(s, keyID, algorithm, 48 << 3,
attributes);
} catch (PKCS11Exception e) {
throw new InvalidKeyException("unwrap() failed", e);
} finally {
token.releaseSession(s);
}
}
// XXX implement unwrap using C_Unwrap() for all keys
implInit(Cipher.DECRYPT_MODE, p11Key);
if (wrappedKey.length > maxInputSize) {
......
/*
* Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -88,23 +88,33 @@ final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
throw new IllegalStateException
("TlsRsaPremasterSecretGenerator must be initialized");
}
CK_VERSION version =
new CK_VERSION(spec.getMajorVersion(), spec.getMinorVersion());
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_GenerateKey
(session.id(), new CK_MECHANISM(mechanism, version), attributes);
SecretKey key = P11Key.secretKey
(session, keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
return key;
} catch (PKCS11Exception e) {
throw new ProviderException("Could not generate premaster secret", e);
} finally {
token.releaseSession(session);
byte[] b = spec.getEncodedSecret();
if (b == null) {
CK_VERSION version = new CK_VERSION(
spec.getMajorVersion(), spec.getMinorVersion());
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes(
O_GENERATE, CKO_SECRET_KEY,
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_GenerateKey(session.id(),
new CK_MECHANISM(mechanism, version), attributes);
SecretKey key = P11Key.secretKey(session,
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
return key;
} catch (PKCS11Exception e) {
throw new ProviderException(
"Could not generate premaster secret", e);
} finally {
token.releaseSession(session);
}
}
// Won't worry, the TlsRsaPremasterSecret will be soon converted to
// TlsMasterSecret.
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
}
}
/*
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -43,10 +43,8 @@ import sun.misc.Unsafe;
* These are the only platforms we currently support, but other optimized
* variants could be added as needed.
*
* NOTE that because this code performs unchecked direct memory access, it
* MUST be restricted to trusted code. It is imperative that the caller protects
* against out of bounds memory access by performing the necessary bounds
* checks before calling methods in this class.
* NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks
* failed.
*
* This class may also be helpful in improving the performance of the
* crypto code in the SunJCE provider. However, for now it is only accessible by
......@@ -103,6 +101,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, little endian byte order.
*/
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
......@@ -131,6 +133,10 @@ final class ByteArrayAccess {
// Special optimization of b2iLittle(in, inOfs, out, 0, 64)
static void b2iLittle64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = unsafe.getInt(in, (long)(inOfs ));
......@@ -176,6 +182,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, little endian byte order.
*/
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
......@@ -204,6 +214,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.
static void i2bLittle4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
} else if (bigEndian && ((outOfs & 3) == 0)) {
......@@ -220,6 +233,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, big endian byte order.
*/
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
......@@ -248,6 +265,10 @@ final class ByteArrayAccess {
// Special optimization of b2iBig(in, inOfs, out, 0, 64)
static void b2iBig64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
......@@ -293,6 +314,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, big endian byte order.
*/
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
......@@ -321,6 +346,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
static void i2bBig4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
} else if (bigEndian && ((outOfs & 3) == 0)) {
......@@ -337,6 +365,10 @@ final class ByteArrayAccess {
* byte[] to long[] conversion, big endian byte order.
*/
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/8)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
......@@ -378,6 +410,10 @@ final class ByteArrayAccess {
// Special optimization of b2lBig(in, inOfs, out, 0, 128)
static void b2lBig128(byte[] in, int inOfs, long[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 128) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs )));
......@@ -406,6 +442,10 @@ final class ByteArrayAccess {
* long[] to byte[] conversion, big endian byte order.
*/
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
len += outOfs;
while (outOfs < len) {
long i = in[inOfs++];
......@@ -419,5 +459,4 @@ final class ByteArrayAccess {
out[outOfs++] = (byte)(i );
}
}
}
/*
* Copyright (c) 2003, 2013 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -318,33 +318,53 @@ public final class RSAPadding {
/**
* PKCS#1 v1.5 unpadding (blocktype 1 and 2).
*
* Note that we want to make it a constant-time operation
*/
private byte[] unpadV15(byte[] padded) throws BadPaddingException {
int k = 0;
BadPaddingException bpe = null;
if (padded[k++] != 0) {
throw new BadPaddingException("Data must start with zero");
bpe = new BadPaddingException("Data must start with zero");
}
if (padded[k++] != type) {
throw new BadPaddingException("Blocktype mismatch: " + padded[1]);
if (padded[k++] != type && bpe == null) {
bpe = new BadPaddingException("Blocktype mismatch: " + padded[1]);
}
while (true) {
int p = 0;
while (k < padded.length) {
int b = padded[k++] & 0xff;
if (b == 0) {
break;
if (b == 0 && p == 0) {
p = k;
}
if (k == padded.length) {
throw new BadPaddingException("Padding string not terminated");
if (k == padded.length && p == 0 && bpe == null) {
bpe = new BadPaddingException("Padding string not terminated");
}
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff)) {
throw new BadPaddingException("Padding byte not 0xff: " + b);
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
p == 0 && bpe == null) {
bpe = new BadPaddingException("Padding byte not 0xff: " + b);
}
}
int n = padded.length - k;
if (n > maxDataSize) {
throw new BadPaddingException("Padding string too short");
int n = padded.length - p;
if (n > maxDataSize && bpe == null) {
bpe = new BadPaddingException("Padding string too short");
}
// copy useless padding array for a constant-time method
//
// Is it necessary?
byte[] padding = new byte[p];
System.arraycopy(padded, 0, padding, 0, p);
byte[] data = new byte[n];
System.arraycopy(padded, padded.length - n, data, 0, n);
System.arraycopy(padded, p, data, 0, n);
if (bpe == null) {
bpe = new BadPaddingException("Unused exception");
} else {
throw bpe;
}
return data;
}
......
......@@ -1104,94 +1104,23 @@ abstract class Handshaker {
clnt_random.random_bytes, svr_random.random_bytes,
prfHashAlg, prfHashLength, prfBlockSize);
SecretKey masterSecret;
try {
KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
kg.init(spec);
masterSecret = kg.generateKey();
} catch (GeneralSecurityException e) {
return kg.generateKey();
} catch (InvalidAlgorithmParameterException |
NoSuchAlgorithmException iae) {
// unlikely to happen, otherwise, must be a provider exception
//
// For RSA premaster secrets, do not signal a protocol error
// due to the Bleichenbacher attack. See comments further down.
if (!preMasterSecret.getAlgorithm().equals(
"TlsRsaPremasterSecret")) {
throw new ProviderException(e);
}
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA master secret generation error:");
e.printStackTrace(System.out);
}
if (requestedVersion != null) {
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(requestedVersion);
} else {
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(protocolVersion);
iae.printStackTrace(System.out);
}
throw new ProviderException(iae);
// recursive call with new premaster secret
return calculateMasterSecret(preMasterSecret, null);
}
// if no version check requested (client side handshake), or version
// information is not available (not an RSA premaster secret),
// return master secret immediately.
if ((requestedVersion == null) ||
!(masterSecret instanceof TlsMasterSecret)) {
return masterSecret;
}
// we have checked the ClientKeyExchange message when reading TLS
// record, the following check is necessary to ensure that
// JCE provider does not ignore the checking, or the previous
// checking process bypassed the premaster secret version checking.
TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
int major = tlsKey.getMajorVersion();
int minor = tlsKey.getMinorVersion();
if ((major < 0) || (minor < 0)) {
return masterSecret;
}
// check if the premaster secret version is ok
// the specification says that it must be the maximum version supported
// by the client from its ClientHello message. However, many
// implementations send the negotiated version, so accept both
// for SSL v3.0 and TLS v1.0.
// NOTE that we may be comparing two unsupported version numbers, which
// is why we cannot use object reference equality in this special case.
ProtocolVersion premasterVersion =
ProtocolVersion.valueOf(major, minor);
boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
/*
* we never checked the client_version in server side
* for TLS v1.0 and SSL v3.0. For compatibility, we
* maintain this behavior.
*/
if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
versionMismatch = (premasterVersion.v != protocolVersion.v);
}
if (versionMismatch == false) {
// check passed, return key
return masterSecret;
}
// Due to the Bleichenbacher attack, do not signal a protocol error.
// Generate a random premaster secret and continue with the handshake,
// which will fail when verifying the finished messages.
// For more information, see comments in PreMasterSecret.
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA PreMasterSecret version error: expected"
+ protocolVersion + " or " + requestedVersion + ", decrypted: "
+ premasterVersion);
}
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(requestedVersion);
// recursive call with new premaster secret
return calculateMasterSecret(preMasterSecret, null);
}
/*
......
/*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -133,26 +133,37 @@ final class RSAClientKeyExchange extends HandshakeMessage {
} else {
encrypted = new byte [messageSize];
if (input.read(encrypted) != messageSize) {
throw new SSLProtocolException
("SSL: read PreMasterSecret: short read");
throw new SSLProtocolException(
"SSL: read PreMasterSecret: short read");
}
}
Exception failover = null;
byte[] encoded = null;
try {
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
cipher.init(Cipher.UNWRAP_MODE, privateKey);
preMaster = (SecretKey)cipher.unwrap(encrypted,
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
// polish the premaster secret
preMaster = polishPreMasterSecretKey(currentVersion, maxVersion,
generator, preMaster, null);
// Cannot generate key here, please don't use Cipher.UNWRAP_MODE!
cipher.init(Cipher.DECRYPT_MODE, privateKey);
encoded = cipher.doFinal(encrypted);
} catch (BadPaddingException bpe) {
failover = bpe;
encoded = null;
} catch (IllegalBlockSizeException ibse) {
// the message it too big to process with RSA
throw new SSLProtocolException(
"Unable to process PreMasterSecret, may be too big");
} catch (Exception e) {
// polish the premaster secret
preMaster =
polishPreMasterSecretKey(currentVersion, maxVersion,
generator, null, e);
// unlikely to happen, otherwise, must be a provider exception
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA premaster secret decryption error:");
e.printStackTrace(System.out);
}
throw new RuntimeException("Could not generate dummy secret", e);
}
// polish the premaster secret
preMaster = polishPreMasterSecretKey(
currentVersion, maxVersion, generator, encoded, failover);
}
/**
......@@ -163,85 +174,74 @@ final class RSAClientKeyExchange extends HandshakeMessage {
*
* RFC 5246 describes the approach as :
*
* 1. Generate a string R of 46 random bytes
* 1. Generate a string R of 48 random bytes
*
* 2. Decrypt the message to recover the plaintext M
*
* 3. If the PKCS#1 padding is not correct, or the length of message
* M is not exactly 48 bytes:
* pre_master_secret = ClientHello.client_version || R
* pre_master_secret = R
* else If ClientHello.client_version <= TLS 1.0, and version
* number check is explicitly disabled:
* pre_master_secret = M
* premaster secret = M
* else If M[0..1] != ClientHello.client_version:
* premaster secret = R
* else:
* pre_master_secret = ClientHello.client_version || M[2..47]
* premaster secret = M
*
* Note that #2 has completed before the call of this method.
*/
private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion,
ProtocolVersion clientHelloVersion, SecureRandom generator,
SecretKey secretKey, Exception failoverException) {
byte[] encoded, Exception failoverException) {
this.protocolVersion = clientHelloVersion;
if (generator == null) {
generator = new SecureRandom();
}
byte[] random = new byte[48];
generator.nextBytes(random);
if (failoverException == null && secretKey != null) {
if (failoverException == null && encoded != null) {
// check the length
byte[] encoded = secretKey.getEncoded();
if (encoded == null) { // unable to get the encoded key
if (encoded.length != 48) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"unable to get the plaintext of the premaster secret");
"incorrect length of premaster secret: " +
encoded.length);
}
int keySize = KeyUtil.getKeySize(secretKey);
if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"incorrect length of premaster secret: " +
(keySize/8));
}
return generatePreMasterSecret(
clientHelloVersion, random, generator);
}
return generateDummySecret(clientHelloVersion);
}
if (clientHelloVersion.major != encoded[0] ||
clientHelloVersion.minor != encoded[1]) {
// The key size is exactly 48 bytes or not accessible.
//
// Conservatively, pass the checking to master secret
// calculation.
return secretKey;
} else if (encoded.length == 48) {
// check the version
if (clientHelloVersion.major == encoded[0] &&
clientHelloVersion.minor == encoded[1]) {
return secretKey;
} else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
currentVersion.major == encoded[0] &&
currentVersion.minor == encoded[1]) {
if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
currentVersion.major == encoded[0] &&
currentVersion.minor == encoded[1]) {
/*
* For compatibility, we maintain the behavior that the
* version in pre_master_secret can be the negotiated
* version for TLS v1.0 and SSL v3.0.
*/
this.protocolVersion = currentVersion;
return secretKey;
}
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Mismatching Protocol Versions, " +
"ClientHello.client_version is " + clientHelloVersion +
", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1]));
}
} else {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Mismatching Protocol Versions, " +
"ClientHello.client_version is " +
clientHelloVersion +
", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1]));
}
return generateDummySecret(clientHelloVersion);
} else {
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"incorrect length of premaster secret: " +
encoded.length);
encoded = random;
}
return generateDummySecret(clientHelloVersion);
}
return generatePreMasterSecret(
clientHelloVersion, encoded, generator);
}
if (debug != null && Debug.isOn("handshake") &&
......@@ -250,11 +250,14 @@ final class RSAClientKeyExchange extends HandshakeMessage {
failoverException.printStackTrace(System.out);
}
return generateDummySecret(clientHelloVersion);
return generatePreMasterSecret(clientHelloVersion, random, generator);
}
// generate a premaster secret with the specified version number
static SecretKey generateDummySecret(ProtocolVersion version) {
private static SecretKey generatePreMasterSecret(
ProtocolVersion version, byte[] encodedSecret,
SecureRandom generator) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Generating a random fake premaster secret");
}
......@@ -263,11 +266,17 @@ final class RSAClientKeyExchange extends HandshakeMessage {
String s = ((version.v >= ProtocolVersion.TLS12.v) ?
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
KeyGenerator kg = JsseJce.getKeyGenerator(s);
kg.init(new TlsRsaPremasterSecretParameterSpec
(version.major, version.minor));
kg.init(new TlsRsaPremasterSecretParameterSpec(
version.major, version.minor, encodedSecret), generator);
return kg.generateKey();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate dummy secret", e);
} catch (InvalidAlgorithmParameterException |
NoSuchAlgorithmException iae) {
// unlikely to happen, otherwise, must be a provider exception
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA premaster secret generation error:");
iae.printStackTrace(System.out);
}
throw new RuntimeException("Could not generate dummy secret", iae);
}
}
......
......@@ -158,8 +158,13 @@ public class Main {
private String altSignerClasspath = null;
private ZipFile zipFile = null;
private boolean hasExpiredCert = false;
// Informational warnings
private boolean hasExpiringCert = false;
private boolean noTimestamp = false;
private Date expireDate = new Date(0L); // used in noTimestamp warning
// Severe warnings
private boolean hasExpiredCert = false;
private boolean notYetValidCert = false;
private boolean chainNotValidated = false;
private boolean notSignedByAlias = false;
......@@ -258,9 +263,6 @@ public class Main {
if (strict) {
int exitCode = 0;
if (hasExpiringCert) {
exitCode |= 2;
}
if (chainNotValidated || hasExpiredCert || notYetValidCert) {
exitCode |= 4;
}
......@@ -754,14 +756,25 @@ public class Main {
System.out.println(rb.getString(
"jar.is.unsigned.signatures.missing.or.not.parsable."));
} else {
System.out.println(rb.getString("jar.verified."));
if (hasUnsignedEntry || hasExpiredCert || hasExpiringCert ||
badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated ||
aliasNotInStore || notSignedByAlias) {
boolean warningAppeared = false;
boolean errorAppeared = false;
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated || hasExpiredCert ||
hasUnsignedEntry ||
aliasNotInStore || notSignedByAlias) {
if (strict) {
System.out.println(rb.getString("jar.verified.with.signer.errors."));
System.out.println();
System.out.println(rb.getString("Error."));
errorAppeared = true;
} else {
System.out.println(rb.getString("jar.verified."));
System.out.println();
System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
System.out.println();
System.out.println(rb.getString("Warning."));
if (badKeyUsage) {
System.out.println(
rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
......@@ -785,10 +798,6 @@ public class Main {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.has.expired."));
}
if (hasExpiringCert) {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
}
if (notYetValidCert) {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid."));
......@@ -807,10 +816,29 @@ public class Main {
if (aliasNotInStore) {
System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore."));
}
} else {
System.out.println(rb.getString("jar.verified."));
}
if (hasExpiringCert || noTimestamp) {
if (!warningAppeared) {
System.out.println();
System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
if (hasExpiringCert) {
System.out.println(rb.getString(
"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
}
if (noTimestamp) {
System.out.println(
String.format(rb.getString("no.timestamp.verifying"), expireDate));
}
}
if (warningAppeared || errorAppeared) {
if (! (verbose != null && showcerts)) {
System.out.println();
System.out.println(rb.getString(
"Re.run.with.the.verbose.and.certs.options.for.more.details."));
"Re.run.with.the.verbose.and.certs.options.for.more.details."));
}
}
}
......@@ -870,6 +898,9 @@ public class Main {
try {
boolean printValidity = true;
if (timestamp == null) {
if (expireDate.getTime() == 0 || expireDate.after(notAfter)) {
expireDate = notAfter;
}
x509Cert.checkValidity();
// test if cert will expire within six months
if (notAfter.getTime() < System.currentTimeMillis() + SIX_MONTHS) {
......@@ -1233,6 +1264,10 @@ public class Main {
tsaCert = getTsaCert(tsaAlias);
}
if (tsaUrl == null && tsaCert == null) {
noTimestamp = true;
}
SignatureFile.Block block = null;
try {
......@@ -1380,12 +1415,20 @@ public class Main {
}
}
if (hasExpiredCert || hasExpiringCert || notYetValidCert
|| badKeyUsage || badExtendedKeyUsage
|| badNetscapeCertType || chainNotValidated) {
System.out.println();
boolean warningAppeared = false;
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated || hasExpiredCert) {
if (strict) {
System.out.println(rb.getString("jar.signed.with.signer.errors."));
System.out.println();
System.out.println(rb.getString("Error."));
} else {
System.out.println(rb.getString("jar.signed."));
System.out.println();
System.out.println(rb.getString("Warning."));
warningAppeared = true;
}
System.out.println(rb.getString("Warning."));
if (badKeyUsage) {
System.out.println(
rb.getString("The.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
......@@ -1404,9 +1447,6 @@ public class Main {
if (hasExpiredCert) {
System.out.println(
rb.getString("The.signer.certificate.has.expired."));
} else if (hasExpiringCert) {
System.out.println(
rb.getString("The.signer.certificate.will.expire.within.six.months."));
} else if (notYetValidCert) {
System.out.println(
rb.getString("The.signer.certificate.is.not.yet.valid."));
......@@ -1416,6 +1456,24 @@ public class Main {
System.out.println(
rb.getString("The.signer.s.certificate.chain.is.not.validated."));
}
} else {
System.out.println(rb.getString("jar.signed."));
}
if (hasExpiringCert || noTimestamp) {
if (!warningAppeared) {
System.out.println();
System.out.println(rb.getString("Warning."));
}
if (hasExpiringCert) {
System.out.println(
rb.getString("The.signer.certificate.will.expire.within.six.months."));
}
if (noTimestamp) {
System.out.println(
String.format(rb.getString("no.timestamp.signing"), expireDate));
}
}
// no IOException thrown in the above try clause, so disable
......@@ -1502,6 +1560,7 @@ public class Main {
timestamp = ts.getTimestamp();
} else {
timestamp = null;
noTimestamp = true;
}
// display the certificate(s). The first one is end-entity cert and
// its KeyUsage should be checked.
......
......@@ -112,9 +112,9 @@ public class Resources extends java.util.ListResourceBundle {
{"Please.specify.alias.name", "Please specify alias name"},
{"Only.one.alias.can.be.specified", "Only one alias can be specified"},
{"This.jar.contains.signed.entries.which.is.not.signed.by.the.specified.alias.es.",
"This jar contains signed entries which is not signed by the specified alias(es)."},
"This jar contains signed entries which are not signed by the specified alias(es)."},
{"This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore.",
"This jar contains signed entries that's not signed by alias in this keystore."},
"This jar contains signed entries that are not signed by alias in this keystore."},
{"s", "s"},
{"m", "m"},
{"k", "k"},
......@@ -135,7 +135,10 @@ public class Resources extends java.util.ListResourceBundle {
{".Unsigned.entries.", "(Unsigned entries)"},
{"jar.is.unsigned.signatures.missing.or.not.parsable.",
"jar is unsigned. (signatures missing or not parsable)"},
{"jar.signed.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."},
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
{"jarsigner.", "jarsigner: "},
{"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
"signature filename must consist of the following characters: A-Z, 0-9, _ or -"},
......@@ -193,6 +196,7 @@ public class Resources extends java.util.ListResourceBundle {
"using an alternative signing mechanism"},
{"entry.was.signed.on", "entry was signed on {0}"},
{"Warning.", "Warning: "},
{"Error.", "Error: "},
{"This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked.",
"This jar contains unsigned entries which have not been integrity-checked. "},
{"This.jar.contains.entries.whose.signer.certificate.has.expired.",
......@@ -229,6 +233,10 @@ public class Resources extends java.util.ListResourceBundle {
"The signer's certificate chain is not validated."},
{"This.jar.contains.entries.whose.certificate.chain.is.not.validated.",
"This jar contains entries whose certificate chain is not validated."},
{"no.timestamp.signing",
"No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
{"no.timestamp.verifying",
"This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
{"Unknown.password.type.", "Unknown password type: "},
{"Cannot.find.environment.variable.",
"Cannot find environment variable: "},
......
......@@ -222,5 +222,5 @@ public final class SecurityConstants {
// java.lang.SecurityManager
public static final SocketPermission LOCAL_LISTEN_PERMISSION =
new SocketPermission("localhost:1024-", SOCKET_LISTEN_ACTION);
new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION);
}
......@@ -2,48 +2,48 @@
// Standard extensions get all permissions by default
grant codeBase "file:${{java.ext.dirs}}/*" {
permission java.security.AllPermission;
permission java.security.AllPermission;
};
// default permissions granted to all domains
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See the API specification of java.lang.Thread.stop() for more
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See the API specification of java.lang.Thread.stop() for more
// information.
permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on un-privileged ports
permission java.net.SocketPermission "localhost:1024-", "listen";
// "standard" properies that can be read by anyone
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on dynamic ports
permission java.net.SocketPermission "localhost:0", "listen";
// "standard" properies that can be read by anyone
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
};
......@@ -182,6 +182,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -205,7 +206,7 @@ package.access=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
......@@ -228,6 +229,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -251,7 +253,7 @@ package.definition=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
......@@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
......@@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
......@@ -184,6 +184,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -207,7 +208,7 @@ package.access=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
......@@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -252,7 +254,7 @@ package.definition=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
......@@ -494,4 +496,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
......@@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -206,7 +207,7 @@ package.access=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
......@@ -229,6 +230,7 @@ package.definition=sun.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.naming.internal.,\
com.sun.proxy.,\
com.sun.corba.se.,\
com.sun.org.apache.bcel.internal.,\
......@@ -252,7 +254,7 @@ package.definition=sun.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
oracle.jrockit.jfr.,\
oracle.jrockit.jfr.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
......@@ -495,4 +497,3 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
......@@ -111,8 +111,9 @@ SplashDone(Splash * splash)
int
SplashIsStillLooping(Splash * splash)
{
if (splash->currentFrame < 0)
if (splash->currentFrame < 0) {
return 0;
}
return splash->loopCount != 1 ||
splash->currentFrame + 1 < splash->frameCount;
}
......@@ -121,17 +122,22 @@ void
SplashUpdateScreenData(Splash * splash)
{
ImageRect srcRect, dstRect;
if (splash->currentFrame < 0) {
return;
}
initRect(&srcRect, 0, 0, splash->width, splash->height, 1,
splash->width * sizeof(rgbquad_t),
splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat);
if (splash->screenData)
if (splash->screenData) {
free(splash->screenData);
}
splash->screenStride = splash->width * splash->screenFormat.depthBytes;
if (splash->byteAlignment > 1)
if (splash->byteAlignment > 1) {
splash->screenStride =
(splash->screenStride + splash->byteAlignment - 1) &
~(splash->byteAlignment - 1);
}
splash->screenData = malloc(splash->height * splash->screenStride);
initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
splash->screenStride, splash->screenData, &splash->screenFormat);
......@@ -146,16 +152,19 @@ SplashUpdateScreenData(Splash * splash)
void
SplashNextFrame(Splash * splash)
{
if (splash->currentFrame < 0)
if (splash->currentFrame < 0) {
return;
}
do {
if (!SplashIsStillLooping(splash))
if (!SplashIsStillLooping(splash)) {
return;
}
splash->time += splash->frames[splash->currentFrame].delay;
if (++splash->currentFrame >= splash->frameCount) {
splash->currentFrame = 0;
if (splash->loopCount > 0)
if (splash->loopCount > 0) {
splash->loopCount--;
}
}
} while (splash->time + splash->frames[splash->currentFrame].delay -
SplashTime() <= 0);
......@@ -183,8 +192,9 @@ BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out)
pSrc += pSrcRect->depthBytes;
++i;
}
if (i >= pSrcRect->numSamples)
if (i >= pSrcRect->numSamples) {
break;
}
i0 = i;
while (i < pSrcRect->numSamples &&
getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) {
......
......@@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate), success)) {
glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
}
......
......@@ -37,55 +37,54 @@
U_NAMESPACE_BEGIN
void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const
void AnchorTable::getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{
switch(SWAPW(anchorFormat)) {
switch(SWAPW(anchorFormat)) {
case 1:
{
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
f1->getAnchor(fontInstance, anchor);
LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
break;
}
case 2:
{
const Format2AnchorTable *f2 = (const Format2AnchorTable *) this;
f2->getAnchor(glyphID, fontInstance, anchor);
LEReferenceTo<Format2AnchorTable> f2(base, success);
f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
break;
}
case 3:
{
const Format3AnchorTable *f3 = (const Format3AnchorTable *) this;
f3->getAnchor(fontInstance, anchor);
LEReferenceTo<Format3AnchorTable> f3(base, success);
f3->getAnchor(f3, fontInstance, anchor, success);
break;
}
default:
{
// unknown format: just use x, y coordinate, like format 1...
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
f1->getAnchor(fontInstance, anchor);
LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
break;
}
}
}
void Format1AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
void Format1AnchorTable::getAnchor(const LEReferenceTo<Format1AnchorTable>& base, const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const
{
le_int16 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate);
LEPoint pixels;
fontInstance->transformFunits(x, y, pixels);
fontInstance->pixelsToUnits(pixels, anchor);
}
void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const
void Format2AnchorTable::getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor
, LEErrorCode &success) const
{
LEPoint point;
......@@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font
fontInstance->pixelsToUnits(point, anchor);
}
void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
void Format3AnchorTable::getAnchor(const LEReferenceTo<Format3AnchorTable> &base, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{
le_int16 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate);
......@@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &
fontInstance->transformFunits(x, y, pixels);
if (dtxOffset != 0) {
const DeviceTable *dtx = (const DeviceTable *) ((char *) this + dtxOffset);
le_int16 adjx = dtx->getAdjustment((le_int16) fontInstance->getXPixelsPerEm());
LEReferenceTo<DeviceTable> dt(base, success, dtxOffset);
le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
pixels.fX += adjx;
}
if (dtyOffset != 0) {
const DeviceTable *dty = (const DeviceTable *) ((char *) this + dtyOffset);
le_int16 adjy = dty->getAdjustment((le_int16) fontInstance->getYPixelsPerEm());
LEReferenceTo<DeviceTable> dt(base, success, dtyOffset);
le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
pixels.fY += adjy;
}
......
......@@ -49,20 +49,23 @@ struct AnchorTable
le_int16 xCoordinate;
le_int16 yCoordinate;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const;
void getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
};
struct Format1AnchorTable : AnchorTable
{
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
void getAnchor(const LEReferenceTo<Format1AnchorTable>& base,
const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const;
};
struct Format2AnchorTable : AnchorTable
{
le_uint16 anchorPoint;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const;
void getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
};
struct Format3AnchorTable : AnchorTable
......@@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable
Offset xDeviceTableOffset;
Offset yDeviceTableOffset;
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
void getAnchor(const LEReferenceTo<Format3AnchorTable>& base,
const LEFontInstance *fontInstance, LEPoint &anchor,
LEErrorCode &success) const;
};
U_NAMESPACE_END
......
......@@ -51,7 +51,7 @@
U_NAMESPACE_BEGIN
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const
{
return fFontInstance->canDisplay((LEUnicode) glyph);
}
......@@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success);
} else {
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,
CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
......@@ -157,9 +159,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
/* OpenTypeLayoutEngine will allocate a substitution filter */
fGSUBTable.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);
fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
/* OpenTypeLayoutEngine will allocate a substitution filter */
}
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
......
......@@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{
LEErrorCode success = LE_NO_ERROR;
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
const LEReferenceTo<ClassDefinitionTable> joiningTypes(LETableReference::kStaticData,
(const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
ArabicShaping::shapingTypeTableLen);
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
......
......@@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{
LEErrorCode success = LE_NO_ERROR;
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
......
......@@ -43,6 +43,8 @@ class LEFontInstance;
* This filter is used by character-based GSUB processors. It
* accepts only those characters which the given font can display.
*
* Note: Implementation is in ArabicLayoutEngine.cpp
*
* @internal
*/
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
......@@ -97,7 +99,7 @@ public:
*
* @internal
*/
le_bool accept(LEGlyphID glyph) const;
le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
};
U_NAMESPACE_END
......
......@@ -49,6 +49,7 @@ struct ClassDefinitionTable
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
#if LE_ENABLE_RAW
le_int32 getGlyphClass(LEGlyphID glyphID) const {
LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR;
......@@ -60,6 +61,7 @@ struct ClassDefinitionTable
LEErrorCode ignored = LE_NO_ERROR;
return hasGlyphClass(base,glyphClass,ignored);
}
#endif
};
struct ClassDefFormat1Table : ClassDefinitionTable
......
......@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
*/
void ContextualSubstitutionBase::applySubstitutionLookups(
const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray,
const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
......@@ -60,10 +60,11 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
}
GlyphIterator tempIterator(*glyphIterator);
const SubstitutionLookupRecord *substLookupRecordArrayPtr = substLookupRecordArray.getAlias(); // OK to dereference, range checked against substCount below.
for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex);
le_uint16 sequenceIndex = SWAPW(substLookupRecordArrayPtr[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArrayPtr[subst].lookupListIndex);
tempIterator.setCurrStreamPosition(position);
tempIterator.next(sequenceIndex);
......@@ -72,7 +73,7 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
}
}
le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, le_uint16 glyphCount,
le_bool ContextualSubstitutionBase::matchGlyphIDs(const LEReferenceToArrayOf<TTGlyphID>& glyphArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, le_bool backtrack)
{
le_int32 direction = 1;
......@@ -101,10 +102,13 @@ le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, l
return TRUE;
}
le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable,
le_bool backtrack)
le_bool ContextualSubstitutionBase::matchGlyphClasses(
const LEReferenceToArrayOf<le_uint16> &classArray,
le_uint16 glyphCount,
GlyphIterator *glyphIterator,
const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable,
LEErrorCode &success,
le_bool backtrack)
{
le_int32 direction = 1;
le_int32 match = 0;
......@@ -120,7 +124,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 glyphClass = classDefinitionTable->getGlyphClass(glyph);
le_int32 glyphClass = classDefinitionTable->getGlyphClass(classDefinitionTable, glyph, success);
le_int32 matchClass = SWAPW(classArray[match]);
if (glyphClass != matchClass) {
......@@ -128,7 +132,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
// in the class array which aren't in the class definition
// table. If we're looking for such a class, pretend that
// we found it.
if (classDefinitionTable->hasGlyphClass(matchClass)) {
if (classDefinitionTable->hasGlyphClass(classDefinitionTable, matchClass, success)) {
return FALSE;
}
}
......@@ -140,8 +144,8 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
return TRUE;
}
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack)
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference &offsetBase, LEErrorCode &success, le_bool backtrack)
{
le_int32 direction = 1;
le_int32 glyph = 0;
......@@ -153,13 +157,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
while (glyphCount > 0) {
Offset coverageTableOffset = SWAPW(coverageTableOffsetArray[glyph]);
const CoverageTable *coverageTable = (const CoverageTable *) (offsetBase + coverageTableOffset);
LEReferenceTo<CoverageTable> coverageTable(offsetBase, success, coverageTableOffset);
if (! glyphIterator->next()) {
if (LE_FAILURE(success) || ! glyphIterator->next()) {
return FALSE;
}
if (coverageTable->getGlyphCoverage((LEGlyphID) glyphIterator->getCurrGlyphID()) < 0) {
if (coverageTable->getGlyphCoverage(coverageTable,
(LEGlyphID) glyphIterator->getCurrGlyphID(),
success) < 0) {
return FALSE;
}
......@@ -170,7 +176,7 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
return TRUE;
}
le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ContextualSubstitutionSubtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
......@@ -186,20 +192,29 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
case 1:
{
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ContextualSubstitutionFormat1Subtable> subtable(base, success, (const ContextualSubstitutionFormat1Subtable *) this);
if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 2:
{
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ContextualSubstitutionFormat2Subtable> subtable(base, success, (const ContextualSubstitutionFormat2Subtable *) this);
if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 3:
{
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ContextualSubstitutionFormat3Subtable> subtable(base, success, (const ContextualSubstitutionFormat3Subtable *) this);
if( LE_FAILURE(success) ) {
return 0;
}
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
default:
......@@ -207,7 +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,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
......@@ -227,22 +242,22 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
if (coverageIndex < srSetCount) {
Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]);
const SubRuleSetTable *subRuleSetTable =
(const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset);
LEReferenceTo<SubRuleSetTable>
subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset));
le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) {
Offset subRuleTableOffset =
SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]);
const SubRuleTable *subRuleTable =
(const SubRuleTable *) ((char *) subRuleSetTable + subRuleTableOffset);
LEReferenceTo<SubRuleTable>
subRuleTable(subRuleSetTable, success, subRuleTableOffset);
le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1;
le_uint16 substCount = SWAPW(subRuleTable->substCount);
if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount];
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2);
if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
......@@ -259,10 +274,11 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
return 0;
}
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
......@@ -275,29 +291,33 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
}
if (coverageIndex >= 0) {
const ClassDefinitionTable *classDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset));
LEReferenceTo<ClassDefinitionTable> classDefinitionTable(base, success,
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)));
le_uint16 scSetCount = SWAPW(subClassSetCount);
le_int32 setClass = classDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
le_int32 setClass = classDefinitionTable->getGlyphClass(classDefinitionTable,
glyphIterator->getCurrGlyphID(),
success);
if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) {
Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]);
const SubClassSetTable *subClassSetTable =
(const SubClassSetTable *) ((char *) this + subClassSetTableOffset);
LEReferenceTo<SubClassSetTable>
subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset));
le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) {
Offset subClassRuleTableOffset =
SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]);
const SubClassRuleTable *subClassRuleTable =
(const SubClassRuleTable *) ((char *) subClassSetTable + subClassRuleTableOffset);
LEReferenceTo<SubClassRuleTable>
subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset);
le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1;
le_uint16 substCount = SWAPW(subClassRuleTable->substCount);
if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount];
LEReferenceToArrayOf<le_uint16> classArray(base, success, subClassRuleTable->classArray, matchCount+1);
if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
......@@ -314,7 +334,8 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
return 0;
}
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LETableReference &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success)const
......@@ -333,9 +354,13 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
// that matched when we're done.
glyphIterator->prev();
if (ContextualSubstitutionBase::matchGlyphCoverages(coverageTableOffsetArray, gCount, glyphIterator, (const char *) this)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount];
LEReferenceToArrayOf<Offset> covTableOffsetArray(base, success, coverageTableOffsetArray, gCount);
if( LE_FAILURE(success) ) { return 0; }
if (ContextualSubstitutionBase::matchGlyphCoverages(covTableOffsetArray, gCount, glyphIterator, base, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount], subCount);
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
......@@ -347,7 +372,8 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
return 0;
}
le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionSubtable::process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base,
const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
......@@ -363,20 +389,23 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
case 1:
{
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ChainingContextualSubstitutionFormat1Subtable> subtable(base, success, (ChainingContextualSubstitutionFormat1Subtable *) this);
if(LE_FAILURE(success)) return 0;
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 2:
{
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ChainingContextualSubstitutionFormat2Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat2Subtable *) this);
if( LE_FAILURE(success) ) { return 0; }
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
case 3:
{
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
LEReferenceTo<ChainingContextualSubstitutionFormat3Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat3Subtable *) this);
if( LE_FAILURE(success) ) { return 0; }
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
}
default:
......@@ -390,7 +419,7 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
// emptyFeatureList matches an le_uint32 or an le_uint16...
static const FeatureMask emptyFeatureList = 0x00000000UL;
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
......@@ -410,8 +439,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
if (coverageIndex < srSetCount) {
Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]);
const ChainSubRuleSetTable *chainSubRuleSetTable =
(const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset);
LEReferenceTo<ChainSubRuleSetTable>
chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset));
le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
......@@ -419,13 +448,19 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) {
Offset chainSubRuleTableOffset =
SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]);
const ChainSubRuleTable *chainSubRuleTable =
(const ChainSubRuleTable *) ((char *) chainSubRuleSetTable + chainSubRuleTableOffset);
LEReferenceTo<ChainSubRuleTable>
chainSubRuleTable = LEReferenceTo<ChainSubRuleTable>(chainSubRuleSetTable, success, chainSubRuleTableOffset);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount);
LEReferenceToArrayOf<TTGlyphID> backtrackGlyphArray(base, success, chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 inputGlyphCount = (le_uint16) SWAPW(chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount]) - 1;
const TTGlyphID *inputGlyphArray = &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1];
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1], inputGlyphCount+2);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputGlyphArray[inputGlyphCount]);
const TTGlyphID *lookaheadGlyphArray = &inputGlyphArray[inputGlyphCount + 1];
LEReferenceToArrayOf<TTGlyphID> lookaheadGlyphArray(base, success, inputGlyphArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]);
tempIterator.setCurrStreamPosition(position);
......@@ -435,7 +470,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
}
tempIterator.prev();
if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
if (! matchGlyphIDs(backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
continue;
}
......@@ -446,8 +482,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
}
if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1];
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadGlyphArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
......@@ -464,7 +500,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
return 0;
}
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
......@@ -480,19 +516,21 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
}
if (coverageIndex >= 0) {
const ClassDefinitionTable *backtrackClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset));
const ClassDefinitionTable *inputClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset));
const ClassDefinitionTable *lookaheadClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset));
LEReferenceTo<ClassDefinitionTable>
backtrackClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset)));
LEReferenceTo<ClassDefinitionTable>
inputClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset)));
LEReferenceTo<ClassDefinitionTable>
lookaheadClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset)));
le_uint16 scSetCount = SWAPW(chainSubClassSetCount);
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable,
glyphIterator->getCurrGlyphID(),
success);
if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) {
Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]);
const ChainSubClassSetTable *chainSubClassSetTable =
(const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset);
LEReferenceTo<ChainSubClassSetTable>
chainSubClassSetTable(base, success, (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset));
le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
......@@ -500,13 +538,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) {
Offset chainSubClassRuleTableOffset =
SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]);
const ChainSubClassRuleTable *chainSubClassRuleTable =
(const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset);
LEReferenceTo<ChainSubClassRuleTable>
chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset);
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1];
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]);
const le_uint16 *lookaheadClassArray = &inputClassArray[inputGlyphCount + 1];
LEReferenceToArrayOf<le_uint16> inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success));
LEReferenceToArrayOf<le_uint16> lookaheadClassArray(base, success, inputClassArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2); // +2 for the substCount
if( LE_FAILURE(success) ) { return 0; }
le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]);
......@@ -517,20 +557,22 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
}
tempIterator.prev();
if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount,
&tempIterator, backtrackClassDefinitionTable, TRUE)) {
LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
if( LE_FAILURE(success) ) { return 0; }
if (! matchGlyphClasses(backtrackClassArray, backtrackGlyphCount,
&tempIterator, backtrackClassDefinitionTable, success, TRUE)) {
continue;
}
tempIterator.setCurrStreamPosition(position);
tempIterator.next(inputGlyphCount);
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable)) {
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable, success)) {
continue;
}
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1];
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount);
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
......@@ -547,7 +589,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
return 0;
}
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode & success) const
......@@ -558,9 +600,13 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1];
LEReferenceToArrayOf<Offset> inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset
const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]);
const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1];
if( LE_FAILURE(success) ) { return 0; }
LEReferenceToArrayOf<Offset> lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]);
le_int32 position = glyphIterator->getCurrStreamPosition();
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
......@@ -571,14 +617,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
tempIterator.prev();
if (! ContextualSubstitutionBase::matchGlyphCoverages(backtrackCoverageTableOffsetArray,
backtrkGlyphCount, &tempIterator, (const char *) this, TRUE)) {
backtrkGlyphCount, &tempIterator, base, success, TRUE)) {
return 0;
}
tempIterator.setCurrStreamPosition(position);
tempIterator.next(inputGlyphCount - 1);
if (! ContextualSubstitutionBase::matchGlyphCoverages(lookaheadCoverageTableOffsetArray,
lookaheadGlyphCount, &tempIterator, (const char *) this)) {
lookaheadGlyphCount, &tempIterator, base, success)) {
return 0;
}
......@@ -589,9 +635,10 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
glyphIterator->prev();
if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray,
inputGlyphCount, glyphIterator, (const char *) this)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1];
inputGlyphCount, glyphIterator, base, success)) {
LEReferenceToArrayOf<SubstitutionLookupRecord>
substLookupRecordArray(base, success,
(const SubstitutionLookupRecord *) lookaheadCoverageTableOffsetArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
......
......@@ -56,20 +56,32 @@ struct SubstitutionLookupRecord
struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
{
static le_bool matchGlyphIDs(
const TTGlyphID *glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const LEReferenceToArrayOf<TTGlyphID> &glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
le_bool backtrack = FALSE);
static le_bool matchGlyphClasses(
const le_uint16 *classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable, le_bool backtrack = FALSE);
const LEReferenceToArrayOf<le_uint16> &classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable, LEErrorCode &success, le_bool backtrack = FALSE);
static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack = FALSE);
const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE);
/**
* little shim to wrap the Offset array in range checking
* @private
*/
static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE) {
LEReferenceToArrayOf<Offset> ref(offsetBase, success, coverageTableOffsetArray, glyphCount);
if( LE_FAILURE(success) ) { return FALSE; }
return matchGlyphCoverages(ref, glyphCount, glyphIterator, offsetBase, success, backtrack);
}
static void applySubstitutionLookups(
const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray,
const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
......@@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
{
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
......@@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint16 subRuleSetCount;
Offset subRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
......@@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint16 subClassSetCount;
Offset subClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
......@@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable
Offset coverageTableOffsetArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
......@@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint16 chainSubRuleSetCount;
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
......@@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint16 chainSubClassSetCount;
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
......@@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
//le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
......
......@@ -37,8 +37,10 @@
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))
{
case 0:
......@@ -46,16 +48,16 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
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:
{
const CoverageFormat2Table *f2Table = (const CoverageFormat2Table *) this;
LEReferenceTo<CoverageFormat2Table> f2Table(base, success);
return f2Table->getGlyphCoverage(glyphID);
return f2Table->getGlyphCoverage(f2Table, glyphID, success);
}
default:
......@@ -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);
le_uint16 count = SWAPW(glyphCount);
le_uint8 bit = OpenTypeUtilities::highBit(count);
......@@ -73,37 +77,45 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
le_uint16 probe = power;
le_uint16 index = 0;
if (count == 0) {
return -1;
}
if (count == 0) {
return -1;
}
LEReferenceToArrayOf<TTGlyphID>(base, success, glyphArray, count);
if(LE_FAILURE(success)) return -1; // range checks array
if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
index = extra;
index = extra;
}
while (probe > (1 << 0)) {
probe >>= 1;
probe >>= 1;
if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) {
index += probe;
}
if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) {
index += probe;
}
}
if (SWAPW(glyphArray[index]) == ttGlyphID) {
return index;
return index;
}
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);
le_uint16 count = SWAPW(rangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> rangeRecordArrayRef(base, success, rangeRecordArray, count);
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;
}
......
......@@ -46,7 +46,7 @@ struct CoverageTable
{
le_uint16 coverageFormat;
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
le_int32 getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
};
struct CoverageFormat1Table : CoverageTable
......@@ -54,7 +54,7 @@ struct CoverageFormat1Table : CoverageTable
le_uint16 glyphCount;
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)
......@@ -64,7 +64,7 @@ struct CoverageFormat2Table : CoverageTable
le_uint16 rangeCount;
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)
......
......@@ -51,23 +51,27 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachme
}
LEPoint entryAnchor, exitAnchor;
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
if (entryOffset != 0) {
const AnchorTable *entryAnchorTable = (const AnchorTable *) ((char *) this + entryOffset);
LEReferenceTo<AnchorTable> entryAnchorTable(base, success, entryOffset);
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
glyphIterator->setCursiveEntryPoint(entryAnchor);
if( LE_SUCCESS(success) ) {
entryAnchorTable->getAnchor(entryAnchorTable, glyphID, fontInstance, entryAnchor, success);
glyphIterator->setCursiveEntryPoint(entryAnchor);
}
} else {
//glyphIterator->clearCursiveEntryPoint();
}
if (exitOffset != 0) {
const AnchorTable *exitAnchorTable = (const AnchorTable *) ((char *) this + exitOffset);
LEReferenceTo<AnchorTable> exitAnchorTable(base, success, exitOffset);
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
glyphIterator->setCursiveExitPoint(exitAnchor);
if( LE_SUCCESS(success) ) {
exitAnchorTable->getAnchor(exitAnchorTable, glyphID, fontInstance, exitAnchor, success);
glyphIterator->setCursiveExitPoint(exitAnchor);
}
} else {
//glyphIterator->clearCursiveExitPoint();
}
......
......@@ -43,7 +43,7 @@ const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
#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 format = SWAPW(deltaFormat) - 1;
......@@ -53,6 +53,13 @@ le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
le_uint16 sizeIndex = ppem - start;
le_uint16 bits = fieldBits[format];
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 fieldIndex = sizeIndex % count;
le_uint16 shift = 16 - (bits * (fieldIndex + 1));
......
......@@ -50,7 +50,7 @@ struct DeviceTable
le_uint16 deltaFormat;
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:
static const le_uint16 fieldMasks[];
......
......@@ -48,7 +48,6 @@ le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thi
const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
......
......@@ -52,8 +52,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable
le_uint16 extensionLookupType;
le_uint32 extensionOffset;
le_uint32 process(const LEReferenceTo<ExtensionSubtable> &extRef,
const LookupProcessor *lookupProcessor, le_uint16 lookupType,
le_uint32 process(const LEReferenceTo<ExtensionSubtable> &base, const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
......
......@@ -49,11 +49,11 @@ GDEFMarkFilter::~GDEFMarkFilter()
// 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;
}
U_NAMESPACE_END
......@@ -55,7 +55,7 @@ public:
GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~GDEFMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;
virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
};
U_NAMESPACE_END
......
......@@ -41,14 +41,13 @@
U_NAMESPACE_BEGIN
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),
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
glyphClassDefinitionTable(), markAttachClassDefinitionTable()
{
LEErrorCode success = LE_NO_ERROR; // TODO
le_int32 glyphCount = glyphStorage.getGlyphCount();
if (theGlyphDefinitionTableHeader.isValid()) {
......@@ -388,7 +387,7 @@ void GlyphIterator::setCursiveGlyph()
void GlyphIterator::filterResetCache(void) {
filterCacheValid = FALSE;
}
}
le_bool GlyphIterator::filterGlyph(le_uint32 index)
{
......@@ -399,53 +398,53 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index)
le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case
// we want more fancy cacheing in the future.
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
filterResult = TRUE;
} else {
LEErrorCode success = LE_NO_ERROR;
le_int32 glyphClass = gcdNoGlyphClass;
if (glyphClassDefinitionTable.isValid()) {
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
}
if (glyphClassDefinitionTable.isValid()) {
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
}
switch (glyphClass) {
case gcdNoGlyphClass:
case gcdNoGlyphClass:
filterResult = FALSE;
break;
case gcdSimpleGlyph:
case gcdSimpleGlyph:
filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0;
break;
case gcdLigatureGlyph:
case gcdLigatureGlyph:
filterResult = (lookupFlags & lfIgnoreLigatures) != 0;
break;
case gcdMarkGlyph:
if ((lookupFlags & lfIgnoreMarks) != 0) {
case gcdMarkGlyph:
if ((lookupFlags & lfIgnoreMarks) != 0) {
filterResult = TRUE;
} else {
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
filterResult = (markAttachClassDefinitionTable
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType);
} else {
filterResult = FALSE;
}
}
}
}
break;
case gcdComponentGlyph:
case gcdComponentGlyph:
filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0);
break;
default:
default:
filterResult = FALSE;
break;
}
}
}
filterCacheValid = TRUE;
}
}
return filterCache.result;
}
......
......@@ -49,7 +49,7 @@ class GlyphPositionAdjustments;
class GlyphIterator : public UMemory {
public:
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);
......
......@@ -95,6 +95,8 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
le_uint32 delta = 0;
//_LETRACE("attempting lookupType #%d", lookupType);
switch(lookupType)
{
case 0:
......@@ -152,21 +154,21 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
{
LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
delta = subtable->process(subtable, this , glyphIterator, fontInstance, success);
break;
}
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;
}
case gpstExtension:
{
LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success);
break;
......@@ -176,6 +178,12 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
break;
}
#if LE_TRACE
if(delta != 0) {
_LETRACE("GlyphPositioningLookupProcessor applied #%d -> delta %d @ %d", lookupType, delta, glyphIterator->getCurrStreamPosition());
}
#endif
return delta;
}
......
......@@ -123,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
{
const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break;
}
......@@ -131,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
{
const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break;
}
......
......@@ -44,7 +44,7 @@
#include "LEGlyphStorage.h"
#include "IndicReordering.h"
#include <stdio.h>
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
......@@ -53,14 +53,14 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI
le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
{
if ( version2 ) {
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
} else {
if ( version2 ) {
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
} else {
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
}
fFeatureOrder = TRUE;
fVersion2 = version2;
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
}
fFeatureOrder = TRUE;
fVersion2 = version2;
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
}
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
......@@ -68,7 +68,7 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI
{
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
fVersion2 = FALSE;
fVersion2 = FALSE;
}
IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
......@@ -90,6 +90,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
return 0;
}
_LETRACE("IOTLE::gp, calling parent");
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
if (LE_FAILURE(success)) {
......@@ -97,11 +98,15 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
}
if (fVersion2) {
IndicReordering::finalReordering(glyphStorage,retCount);
IndicReordering::applyPresentationForms(glyphStorage,retCount);
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
_LETRACE("IOTLE::gp, v2 final,");
IndicReordering::finalReordering(glyphStorage,retCount);
_LETRACE("IOTLE::gp, v2 pres");
IndicReordering::applyPresentationForms(glyphStorage,retCount);
_LETRACE("IOTLE::gp, parent gsub");
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
} else {
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
_LETRACE("IOTLE::gp, adjust mpres");
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
}
return retCount;
}
......@@ -116,6 +121,8 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
return 0;
}
_LETRACE("IOTLE: charProc");
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
success = LE_ILLEGAL_ARGUMENT_ERROR;
return 0;
......@@ -143,8 +150,10 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
le_int32 outCharCount;
if (fVersion2) {
_LETRACE("v2process");
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
} else {
_LETRACE("reorder");
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
}
......
......@@ -254,8 +254,8 @@ public:
return fGlyphStorage.getAuxData(charIndex,success);
}
void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) {
le_int32 i;
void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) {
le_int32 i;
LEErrorCode success = LE_NO_ERROR;
for ( i = beginSyllable ; i < nextSyllable ; i++ ) {
......
......@@ -39,7 +39,7 @@
#include <stdio.h>
#define DEBUG 0
#define DEBUG_KERN_TABLE 0
U_NAMESPACE_BEGIN
......@@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
: pairsSwapped(NULL), fTable(base)
{
if(LE_FAILURE(success) || (fTable.isEmpty())) {
#if DEBUG
#if DEBUG_KERN_TABLE
fprintf(stderr, "no kern data\n");
#endif
return;
}
LEReferenceTo<KernTableHeader> header(fTable, success);
#if DEBUG
#if DEBUG_KERN_TABLE
// dump first 32 bytes of header
for (int i = 0; i < 64; ++i) {
fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
......@@ -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, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
#endif
#if DEBUG
#if DEBUG_KERN_TABLE
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped);
fprintf(stderr,
" searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n",
searchRange, entrySelector, rangeShift);
{
if (LE_SUCCESS(success)) {
// dump part of the pair list
char ids[256];
for (int i = 256; --i >= 0;) {
......@@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
p = tp;
}
#if DEBUG
#if DEBUG_KERN_TABLE
fprintf(stderr, "binary search for %0.8x\n", key);
#endif
......@@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
probe >>= 1;
tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
le_uint32 tkey = tp->key;
#if DEBUG
#if DEBUG_KERN_TABLE
fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
#endif
if (tkey <= key) {
if (tkey == key) {
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",
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
fflush(stdout);
......
......@@ -181,6 +181,10 @@ public:
*
* 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')
*
* @return the address of the table in memory, or <code>NULL</code>
......@@ -200,6 +204,8 @@ public:
* Subclasses which represent composite fonts should always return <code>NULL</code>.
*
* 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 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)
U_NAMESPACE_END
#endif
......@@ -62,7 +62,7 @@ public:
*
* @internal
*/
virtual le_bool accept(LEGlyphID glyph) const = 0;
virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const = 0;
};
#endif /* U_HIDE_INTERNAL_API */
......
......@@ -458,7 +458,7 @@ void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorC
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
return;
}
_LETRACE("set%-4d\t(%.2f, %.2f)", glyphIndex, x, y);
fPositions[glyphIndex * 2] = x;
fPositions[glyphIndex * 2 + 1] = y;
}
......@@ -688,10 +688,9 @@ le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGl
// the source glyph we're pointing at
// just got replaced by the insertion
fSrcIndex -= 1;
fSrcIndex -= 1;
return FALSE;
}
U_NAMESPACE_END
......@@ -568,4 +568,3 @@ inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
U_NAMESPACE_END
#endif
......@@ -30,7 +30,7 @@
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* 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
......@@ -262,7 +262,16 @@ enum ScriptCodes {
khojScriptCode = 157,
tirhScriptCode = 158,
scriptCodeCount = 159
/**
* @stable ICU 52
*/
aghbScriptCode = 159,
mahjScriptCode = 160,
/**
* @stable ICU 2.2
*/
scriptCodeCount
};
U_NAMESPACE_END
......
......@@ -132,6 +132,9 @@ enum LEErrorCode {
#define uprv_memcpy memcpy
#define uprv_realloc realloc
#define U_EXPORT2
#define U_CAPI extern "C"
#if !defined(U_IS_BIG_ENDIAN)
#ifdef _LITTLE_ENDIAN
#define U_IS_BIG_ENDIAN 0
......
......@@ -37,34 +37,47 @@
#include "LETypes.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 kTildeTableTag 0x7e7e7e7eUL
#define kQuestionmarkTableTag 0x3F3F3F3FUL /* ???? */
#define kStaticTableTag 0x30303030UL /* 0000 */
#define kTildeTableTag 0x7e7e7e7eUL /* ~~~~ */
#ifdef __cplusplus
// internal - interface for range checking
U_NAMESPACE_BEGIN
#if LE_ASSERT_BAD_FONT
#ifndef LE_TRACE_TR
#define LE_TRACE_TR 0
#endif
class LETableReference; // fwd
/**
* defined in OpenTypeUtilities.cpp
* @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_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
#if 0
#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#if LE_TRACE_TR
#define _TRTRACE(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#else
#define LE_TRACE_TR(x)
#define _TRTRACE(x)
#endif
#else
#define LE_DEBUG_TR(x)
#define LE_DEBUG_TR3(x,y,z)
#define LE_TRACE_TR(x)
#define _TRTRACE(x)
#endif
/**
......@@ -72,6 +85,13 @@ extern void _debug_LETableReference(const char *f, int l, const char *msg, const
*/
class LETableReference {
public:
/**
* Dummy enum asserting that a value is actually static data
* and does not need to be range checked
*/
enum EStaticData { kStaticData = 0 };
/**
* @internal
* Construct from a specific tag
......@@ -79,28 +99,42 @@ public:
LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
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) {
if(LE_FAILURE(success)) {
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) :
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() :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
LE_TRACE_TR("INFO: new empty")
_TRTRACE("INFO: new empty")
}
~LETableReference() {
fTag=kTildeTableTag;
LE_TRACE_TR("INFO: new dtor")
fTag= (LETag)kTildeTableTag;
_TRTRACE("INFO: new dtor")
}
/**
......@@ -126,7 +160,7 @@ public:
fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
}
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);
err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
clear();
......@@ -136,11 +170,13 @@ public:
} else {
clear();
}
LE_TRACE_TR("INFO: new subset")
_TRTRACE("INFO: new subset")
}
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 isValid() const { return !isEmpty(); }
le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
......@@ -233,7 +269,18 @@ protected:
void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
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;
fStart = (const le_uint8*)data;
fLength = length;
......@@ -276,6 +323,90 @@ size_t LETableVarSizer<T>::getSize() {
* 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
* define an array with no *known* bound. Will trim to available size.
......@@ -288,12 +419,12 @@ class LEReferenceToArrayOf : public LETableReference {
public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 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(count == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
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)) {
fCount=0;
......@@ -303,23 +434,23 @@ public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 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(count == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
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();
}
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) {
LE_TRACE_TR("INFO: new RTAO")
_TRTRACE("INFO: new RTAO")
if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
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();
}
......@@ -328,18 +459,40 @@ LE_TRACE_TR("INFO: new RTAO")
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 {
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 {
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 {
return *getAlias(i,success);
}
......@@ -348,6 +501,7 @@ LE_TRACE_TR("INFO: new RTAO")
if(LE_SUCCESS(success)&&i<getCount()) {
return LETableVarSizer<T>::getSize()*i;
} else {
LE_DEBUG_TR3("getOffsetFor failed (%p) index=%d",NULL, i);
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
}
return 0;
......@@ -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) {
LE_TRACE_TR("INFO: null RTAO")
_TRTRACE("INFO: null RTAO")
}
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
......
......@@ -337,6 +337,20 @@ struct LEPoint
typedef struct LEPoint LEPoint;
#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
......@@ -553,7 +567,7 @@ enum LEFeatureTags {
LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */
LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */
LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */
LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */
LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */
......@@ -701,6 +715,12 @@ enum LEFeatureENUMs {
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_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM)
......@@ -727,6 +747,9 @@ enum LEFeatureENUMs {
#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_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 */
......@@ -768,7 +791,7 @@ typedef enum LEErrorCode LEErrorCode;
*
* @stable ICU 2.4
*/
#ifndef LE_FAILURE
#ifndef LE_SUCCESS
#define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code))
#endif
......@@ -781,4 +804,4 @@ typedef enum LEErrorCode LEErrorCode;
#define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
#endif
#endif /* __LETYPES_H */
#endif
......@@ -156,7 +156,7 @@ public:
CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
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)
......@@ -169,9 +169,8 @@ CanonMarkFilter::~CanonMarkFilter()
// 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);
if(LE_FAILURE(success)) return false;
return glyphClass != 0;
......@@ -207,7 +206,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
fGlyphStorage = new LEGlyphStorage();
if (fGlyphStorage == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
}
}
}
le_int32 LayoutEngine::getGlyphCount() const
......@@ -263,7 +262,9 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return count;
}
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable);
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable(LETableReference::kStaticData,
(GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable,
CanonShaping::glyphSubstitutionTableLen);
LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
le_int32 i, dir = 1, out = 0, outCharCount = count;
......@@ -300,7 +301,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
inChars = reordered;
}
}
fakeGlyphStorage.allocateAuxData(success);
......@@ -323,7 +324,8 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
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)) {
delete substitutionFilter;
......@@ -403,10 +405,13 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y
LEPoint advance;
glyphStorage.setPosition(i, x, y, success);
_LETRACE("g#%-4d (%.2f, %.2f)", i, x, y);
fFontInstance->getGlyphAdvance(glyphStorage[i], advance);
x += advance.fX;
y += advance.fY;
}
glyphStorage.setPosition(glyphCount, x, y, success);
......@@ -424,7 +429,7 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
return;
}
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen);
CanonMarkFilter filter(gdefTable, success);
......@@ -464,9 +469,10 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
xAdvance = next - prev;
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
glyphStorage.adjustPosition(p, xAdjust, 0, success);
if (markFilter->accept(glyphStorage[p])) {
if (markFilter->accept(glyphStorage[p], success)) {
xAdjust -= xAdvance;
}
......@@ -506,9 +512,13 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
xAdvance = next - prev;
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
glyphStorage.adjustPosition(p, xAdjust, 0, success);
if (markFilter->accept(chars[c])) {
if (markFilter->accept(chars[c], success)) {
xAdjust -= xAdvance;
}
......@@ -662,8 +672,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
break;
}
} else {
MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag);
if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) {
LEReferenceTo<MorphTableHeader2> morxTable(fontInstance, morxTableTag, success);
if (LE_SUCCESS(success) &&
morxTable.isValid() &&
SWAPL(morxTable->version)==0x00020000) {
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
} else {
LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
......@@ -686,21 +698,20 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
break;
}
case arabScriptCode:
//case hebrScriptCode:
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
case arabScriptCode:
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
//case hebrScriptCode:
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
//case hebrScriptCode:
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
case thaiScriptCode:
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
case thaiScriptCode:
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
case hangScriptCode:
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
case hangScriptCode:
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
default:
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
......@@ -711,9 +722,9 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
}
if (result && LE_FAILURE(success)) {
delete result;
result = NULL;
}
delete result;
result = NULL;
}
if (result == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
......
......@@ -156,8 +156,8 @@ protected:
* @param fontInstance - the font for the text
* @param scriptCode - the script for the text
* @param languageCode - the language for the text
* @param typoFlags - the typographic control flags for the text. Set bit 1 if kerning
* is desired, set bit 2 if ligature formation is desired. Others are reserved.
* @param typoFlags - the typographic control flags for the text (a bitfield). Use kTypoFlagKern
* if kerning is desired, kTypoFlagLiga if ligature formation is desired. Others are reserved.
* @param success - set to an error code if the operation fails
*
* @see LEFontInstance
......
......@@ -105,7 +105,7 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
if(LE_FAILURE(success)) {
currGlyph+= dir;
return nextStateIndex; // get out! bad font
return nextStateIndex; // get out! bad font
}
do {
......
......@@ -49,14 +49,20 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
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]);
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);
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]);
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_int32 startPosition = glyphIterator->getCurrStreamPosition();
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
......@@ -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);
TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
......
......@@ -60,9 +60,11 @@ le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lo
LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
if (delta > 0 || LE_FAILURE(success)) {
return 1;
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;
}
glyphIterator->setCurrStreamPosition(startPosition);
......@@ -86,7 +88,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
}
GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
rightToLeft, 0, 0, glyphDefinitionTableHeader);
rightToLeft, 0, 0, glyphDefinitionTableHeader, success);
le_int32 newGlyphCount = glyphCount;
for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
......@@ -94,6 +96,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
FeatureMask selectMask = lookupSelectArray[lookup];
if (selectMask != 0) {
_LETRACE("Processing order#%d/%d", order, lookupOrderCount);
const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
continue;
......@@ -103,8 +106,11 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
glyphIterator.reset(lookupFlags, selectMask);
while (glyphIterator.findFeatureTag()) {
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
if (LE_FAILURE(success)) {
#if LE_TRACE
_LETRACE("Failure for lookup 0x%x - %s\n", lookup, u_errorName((UErrorCode)success));
#endif
return 0;
}
}
......@@ -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_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);
......@@ -147,6 +153,9 @@ le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featu
if (lookupListIndex >= lookupSelectCount) {
continue;
}
if (store >= lookupOrderCount) {
continue;
}
lookupSelectArray[lookupListIndex] |= featureMask;
lookupOrderArray[store++] = lookupListIndex;
......@@ -246,7 +255,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
if (requiredFeatureIndex != 0xFFFF) {
requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
featureReferences += SWAPW(featureTable->lookupCount);
featureReferences += SWAPW(requiredFeatureTable->lookupCount);
}
lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
......@@ -254,6 +263,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
success = LE_MEMORY_ALLOCATION_ERROR;
return;
}
lookupOrderCount = featureReferences;
for (le_int32 f = 0; f < featureMapCount; f += 1) {
FeatureMap fm = featureMap[f];
......
......@@ -65,7 +65,7 @@ le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &b
if(LE_FAILURE(success)) return 0;
return coverageTable->getGlyphCoverage(glyphID);
return coverageTable->getGlyphCoverage(coverageTable, glyphID, success);
}
U_NAMESPACE_END
......@@ -38,20 +38,28 @@
U_NAMESPACE_BEGIN
le_int32 MarkArray::getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor) const
le_int32 MarkArray::getMarkClass(const LETableReference &base, LEGlyphID glyphID,
le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{
le_int32 markClass = -1;
if (coverageIndex >= 0) {
if ( coverageIndex >= 0 && LE_SUCCESS(success) ) {
le_uint16 mCount = SWAPW(markCount);
if (coverageIndex < mCount) {
LEReferenceToArrayOf<MarkRecord> markRecordArrayRef(base, success, markRecordArray, mCount);
if(LE_FAILURE(success)) {
return markClass;
}
const MarkRecord *markRecord = &markRecordArray[coverageIndex];
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);
}
......
......@@ -54,8 +54,9 @@ struct MarkArray
le_uint16 markCount;
MarkRecord markRecordArray[ANY_NUMBER];
le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor) const;
le_int32 getMarkClass(const LETableReference &base, LEGlyphID glyphID,
le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
};
LE_VAR_ARRAY(MarkArray, markRecordArray)
......
......@@ -66,11 +66,11 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
}
LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
LEReferenceTo<MarkArray> markArray(base, success, (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)));
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
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
// mark class is too big. The table is mal-formed!
return 0;
......@@ -80,7 +80,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
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);
if (baseCoverage < 0 || baseCoverage >= baseCount) {
......@@ -89,19 +90,23 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
// table is mal-formed...
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]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) baseArray + anchorTableOffset);
LEPoint baseAnchor, markAdvance, pixels;
if (anchorTableOffset == 0) {
if (anchorTableOffset <= 0) {
// this means the table is mal-formed...
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
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->pixelsToUnits(pixels, markAdvance);
......@@ -109,6 +114,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
float anchorDiffX = baseAnchor.fX - markAnchor.fX;
float anchorDiffY = baseAnchor.fY - markAnchor.fY;
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X", anchorDiffX, anchorDiffY, markGlyph);
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) {
......@@ -132,7 +139,6 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
gi.next();
}
// end of JK patch
fontInstance->pixelsToUnits(pixels, baseAdvance);
glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY);
......
......@@ -65,8 +65,11 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
}
LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
if( LE_FAILURE(success) ) {
return 0;
}
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) {
......@@ -79,7 +82,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
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);
if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) {
......@@ -91,7 +94,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
le_int32 markPosition = glyphIterator->getCurrStreamPosition();
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 component = ligatureIterator.getMarkComponent(markPosition);
......@@ -100,12 +103,14 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
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]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) ligatureAttachTable + anchorTableOffset);
LEReferenceTo<AnchorTable> anchorTable(ligatureAttachTable, success, anchorTableOffset);
LEPoint ligatureAnchor, markAdvance, pixels;
anchorTable->getAnchor(ligatureGlyph, fontInstance, ligatureAnchor);
anchorTable->getAnchor(anchorTable, ligatureGlyph, fontInstance, ligatureAnchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance);
......
......@@ -66,8 +66,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
}
LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
if(LE_FAILURE(success)) {
return 0;
}
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) {
......@@ -79,7 +82,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
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);
if (mark2Coverage < 0 || mark2Coverage >= mark2Count) {
......@@ -89,9 +93,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
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]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset);
LEReferenceTo<AnchorTable> anchorTable(mark2Array, success, anchorTableOffset);
if(LE_FAILURE(success)) return 0;
LEPoint mark2Anchor, markAdvance, pixels;
if (anchorTableOffset == 0) {
......@@ -99,7 +105,7 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
return 0;
}
anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor);
anchorTable->getAnchor(anchorTable, mark2Glyph, fontInstance, mark2Anchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance);
......@@ -107,6 +113,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
float anchorDiffX = mark2Anchor.fX - markAnchor.fX;
float anchorDiffY = mark2Anchor.fY - markAnchor.fY;
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X mark2 0x%X", anchorDiffX, anchorDiffY, markGlyph, mark2Glyph);
glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) {
......
......@@ -54,9 +54,10 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
// FIXME: is this always the right thing to do?
// FIXME: should this only be done for a non-zero
// glyphCount?
if (filter != NULL && filter->accept(glyph)) {
if (filter != NULL && filter->accept(glyph, success)) {
return 0;
}
if(LE_FAILURE(success)) return 0;
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount);
......@@ -67,7 +68,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
if (coverageIndex >= 0 && coverageIndex < seqCount) {
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);
if (glyphCount == 0) {
......@@ -76,7 +77,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
} else if (glyphCount == 1) {
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;
}
......@@ -89,7 +90,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
for (le_int32 i = 0; i < glyphCount; i += 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
if (! filter->accept(substitute)) {
if (! filter->accept(substitute, success)) {
return 0;
}
}
......
......@@ -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,
LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
_LETRACE("OTLE::adjustGPOS");
if (LE_FAILURE(success)) {
return;
}
......@@ -510,14 +511,17 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
if (!fGPOSTable.isEmpty()) {
if (fScriptTagV2 != nullScriptTag &&
fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
_LETRACE("OTLE::process [0]");
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} else {
_LETRACE("OTLE::process [1]");
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
}
} else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
_LETRACE("OTLE::kerning");
LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success);
kt.process(glyphStorage, success);
......@@ -546,6 +550,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
xPlacement = fFontInstance->xUnitsToPoints(xPlacement);
yPlacement = fFontInstance->yUnitsToPoints(yPlacement);
_LETRACE("OTLE GPOS: #%d, (%.2f,%.2f)", i, xPlacement, yPlacement);
glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success);
xAdjust += fFontInstance->xUnitsToPoints(xAdvance);
......
......@@ -46,15 +46,14 @@ class OpenTypeUtilities /* not : public UObject because all methods are static *
public:
static le_int8 highBit(le_int32 value);
static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success);
/**
* @deprecated TODO remove
*/
#if LE_ENABLE_RAW
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) {
LEErrorCode success = LE_NO_ERROR;
LETableReference recordRef0((const le_uint8*)records);
LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount);
return getGlyphRangeIndex(glyphID, recordRef, success);
}
#endif
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_uint32 value, const le_uint32 array[], le_int32 count);
......
......@@ -76,19 +76,17 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
{
LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
if (LE_FAILURE(success)) {
return 0;
}
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]);
LEReferenceTo<PairSetTable> pairSetTable(base, success, ((char *) this + pairSetTableOffset));
if (LE_FAILURE(success)) {
return 0;
}
LEReferenceTo<PairSetTable> pairSetTable(base, success, pairSetTableOffset);
if( LE_FAILURE(success) ) return 0;
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 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
le_int16 recordSize = sizeof(PairValueRecord) - sizeof(ValueRecord) + valueRecord1Size + valueRecord2Size;
......@@ -96,21 +94,22 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
LEReferenceTo<PairValueRecord> pairValueRecord;
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;
}
if (valueFormat1 != 0) {
pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance);
pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
}
if (valueFormat2 != 0) {
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size);
valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, *glyphIterator, fontInstance);
LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size));
if(LE_SUCCESS(success)) {
valueRecord2->adjustPosition(SWAPW(valueFormat2), base, *glyphIterator, fontInstance, success);
}
}
// back up glyphIterator so second glyph can be
......@@ -135,26 +134,28 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
if (coverageIndex >= 0 && glyphIterator->next()) {
LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID();
const ClassDefinitionTable *classDef1 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef1Offset));
const ClassDefinitionTable *classDef2 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef2Offset));
le_int32 class1 = classDef1->getGlyphClass(firstGlyph);
le_int32 class2 = classDef2->getGlyphClass(secondGlyph);
const LEReferenceTo<ClassDefinitionTable> classDef1(base, success, SWAPW(classDef1Offset));
const LEReferenceTo<ClassDefinitionTable> classDef2(base, success, SWAPW(classDef2Offset));
le_int32 class1 = classDef1->getGlyphClass(classDef1, firstGlyph, success);
le_int32 class2 = classDef2->getGlyphClass(classDef2, secondGlyph, success);
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size;
le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count);
const Class1Record *class1Record = (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1));
const Class2Record *class2Record = (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2));
if (valueFormat1 != 0) {
class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance);
}
if (valueFormat2 != 0) {
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &class2Record->valueRecord1 + valueRecord1Size);
valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, *glyphIterator, fontInstance);
const LEReferenceTo<Class1Record> class1Record(base, success, (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)));
const LEReferenceTo<Class2Record> class2Record(base, success, (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)));
if( LE_SUCCESS(success) ) {
if (valueFormat1 != 0) {
class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
}
if (valueFormat2 != 0) {
const LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &class2Record->valueRecord1) + valueRecord1Size);
LEReferenceTo<PairPositioningFormat2Subtable> thisRef(base, success, this);
if(LE_SUCCESS(success)) {
valueRecord2->adjustPosition(SWAPW(valueFormat2), thisRef, *glyphIterator, fontInstance, success);
}
}
}
// back up glyphIterator so second glyph can be
......@@ -166,23 +167,24 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
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
// The OpenType spec. says that the ValueRecord table is
// sorted by secondGlyph. Unfortunately, there are fonts
// around that have an unsorted ValueRecord table.
LEReferenceTo<PairValueRecord> record(base, success, records);
record.verifyLength(0, recordSize, success);
LEReferenceTo<PairValueRecord> record(records);
for(le_int32 r = 0; r < recordCount; r += 1) {
if (LE_FAILURE(success)) return (const PairValueRecord*)NULL;
if (SWAPW(record->secondGlyph) == glyphID) {
return record;
}
if(LE_FAILURE(success)) return LEReferenceTo<PairValueRecord>();
if (SWAPW(record->secondGlyph) == glyphID) {
return record;
}
record = LEReferenceTo<PairValueRecord>(base, success, ((const char*)record.getAlias())+ recordSize);
record.verifyLength(0, recordSize, success);
record.addOffset(recordSize, success);
}
#else
#error dead code - not updated.
......@@ -211,7 +213,7 @@ LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueReco
}
#endif
return (const PairValueRecord*)NULL;
return LEReferenceTo<PairValueRecord>();
}
U_NAMESPACE_END
......@@ -77,9 +77,8 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable
le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
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_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray)
......
......@@ -106,7 +106,8 @@ LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &b
}
} else {
LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success);
}
if (scriptTableOffset != 0) {
......
......@@ -126,13 +126,13 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
linaScriptTag, /* 'lina' (LINA) */
mandScriptTag, /* 'mand' (MANDAIC) */
mayaScriptTag, /* 'maya' (MAYA) */
meroScriptTag, /* 'mero' (MERO) */
meroScriptTag, /* 'mero' (MEROITIC_HIEROGLYPHS) */
nkooScriptTag, /* 'nko ' (NKO) */
orkhScriptTag, /* 'orkh' (OLD_TURKIC) */
permScriptTag, /* 'perm' (PERM) */
phagScriptTag, /* 'phag' (PHAGS_PA) */
phnxScriptTag, /* 'phnx' (PHOENICIAN) */
plrdScriptTag, /* 'plrd' (PLRD) */
plrdScriptTag, /* 'plrd' (MIAO/POLLARD) */
roroScriptTag, /* 'roro' (RORO) */
saraScriptTag, /* 'sara' (SARA) */
syreScriptTag, /* 'syre' (SYRE) */
......@@ -158,7 +158,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
mteiScriptTag, /* 'mtei' (MEETEI_MAYEK) */
armiScriptTag, /* 'armi' (IMPERIAL_ARAMAIC) */
avstScriptTag, /* 'avst' (AVESTAN) */
cakmScriptTag, /* 'cakm' (CAKM) */
cakmScriptTag, /* 'cakm' (CHAKMA) */
koreScriptTag, /* 'kore' (KORE) */
kthiScriptTag, /* 'kthi' (KAITHI) */
maniScriptTag, /* 'mani' (MANI) */
......@@ -181,7 +181,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
kpelScriptTag, /* 'kpel' (KPEL) */
lomaScriptTag, /* 'loma' (LOMA) */
mendScriptTag, /* 'mend' (MEND) */
mercScriptTag, /* 'merc' (MERC) */
mercScriptTag, /* 'merc' (MEROITIC_CURSIVE) */
narbScriptTag, /* 'narb' (NARB) */
nbatScriptTag, /* 'nbat' (NBAT) */
palmScriptTag, /* 'palm' (PALM) */
......
......@@ -140,13 +140,13 @@ const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPCHA) */
const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */
const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MANDAIC) */
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 orkhScriptTag = 0x6F726B68; /* 'orkh' (OLD_TURKIC) */
const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */
const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */
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 saraScriptTag = 0x73617261; /* 'sara' (SARA) */
const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */
......@@ -172,7 +172,7 @@ const LETag moonScriptTag = 0x6D6F6F6E; /* 'moon' (MOON) */
const LETag mteiScriptTag = 0x6D746569; /* 'mtei' (MEETEI_MAYEK) */
const LETag armiScriptTag = 0x61726D69; /* 'armi' (IMPERIAL_ARAMAIC) */
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 kthiScriptTag = 0x6B746869; /* 'kthi' (KAITHI) */
const LETag maniScriptTag = 0x6D616E69; /* 'mani' (MANI) */
......@@ -195,7 +195,7 @@ const LETag granScriptTag = 0x6772616E; /* 'gran' (GRAN) */
const LETag kpelScriptTag = 0x6B70656C; /* 'kpel' (KPEL) */
const LETag lomaScriptTag = 0x6C6F6D61; /* 'loma' (LOMA) */
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 nbatScriptTag = 0x6E626174; /* 'nbat' (NBAT) */
const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */
......
......@@ -65,17 +65,18 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &
for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph];
// lookupSegment already range checked by lookupSegment() function.
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) {
if (lookupSegment != NULL&& LE_SUCCESS(success)) {
TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
TTGlyphID lastGlyph = SWAPW(lookupSegment->lastGlyph);
le_int16 offset = SWAPW(lookupSegment->value);
if (offset != 0) {
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader.getAliasTODO() + offset);
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
TTGlyphID thisGlyphId= LE_GET_GLYPH(thisGlyph);
LEReferenceToArrayOf<TTGlyphID> glyphArray(subtableHeader, success, offset, lastGlyph - firstGlyph + 1);
if (offset != 0 && thisGlyphId <= lastGlyph && thisGlyphId >= firstGlyph && LE_SUCCESS(success) ) {
TTGlyphID newGlyph = SWAPW(glyphArray[thisGlyphId]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
}
}
......
......@@ -75,7 +75,7 @@ le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePo
}
if (coverageIndex >= 0) {
valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance);
valueRecord.adjustPosition(SWAPW(valueFormat), base, *glyphIterator, fontInstance, success);
return 1;
}
......@@ -92,7 +92,7 @@ le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePo
}
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;
}
......
......@@ -76,7 +76,7 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleS
if (coverageIndex >= 0) {
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);
}
......@@ -97,7 +97,7 @@ le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleS
if (coverageIndex >= 0) {
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);
}
......
......@@ -39,7 +39,7 @@
*/
#ifndef __TIBETANREORDERING_H
#define __TIBETANORDERING_H
#define __TIBETANREORDERING_H
/**
* \file
......
......@@ -59,8 +59,8 @@ le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, Val
return SWAPW(value);
}
void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const
void ValueRecord::adjustPosition(ValueFormat valueFormat, const LETableReference& base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode &success) const
{
float xPlacementAdjustment = 0;
float yPlacementAdjustment = 0;
......@@ -118,8 +118,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
}
......@@ -129,8 +129,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
}
......@@ -140,8 +140,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
}
......@@ -151,10 +151,10 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
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
xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
}
void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const
void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const LETableReference& base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode &success) const
{
float xPlacementAdjustment = 0;
float yPlacementAdjustment = 0;
......@@ -222,8 +222,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
}
......@@ -233,8 +233,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
}
......@@ -244,8 +244,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
}
......@@ -255,8 +255,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem);
LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
}
......
......@@ -53,10 +53,10 @@ struct ValueRecord
le_int16 getFieldValue(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,
const LEFontInstance *fontInstance) const;
void adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const;
void adjustPosition(ValueFormat valueFormat, const LETableReference &base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode &success) const;
void adjustPosition(le_int16 index, ValueFormat valueFormat, const LETableReference &base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode &success) const;
static le_int16 getSize(ValueFormat valueFormat);
......
......@@ -215,6 +215,11 @@ void LinLerp1D(register const cmsUInt16Number Value[],
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
static
......@@ -227,13 +232,15 @@ void LinLerp1Dfloat(const cmsFloat32Number Value[],
int cell0, cell1;
const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
val2 = fclamp(Value[0]);
// if last value...
if (Value[0] == 1.0) {
if (val2 == 1.0) {
Output[0] = LutTable[p -> Domain[0]];
return;
}
val2 = p -> Domain[0] * Value[0];
val2 *= p -> Domain[0];
cell0 = (int) floor(val2);
cell1 = (int) ceil(val2);
......@@ -292,13 +299,15 @@ void Eval1InputFloat(const cmsFloat32Number Value[],
cmsUInt32Number OutChan;
const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
val2 = fclamp(Value[0]);
// if last value...
if (Value[0] == 1.0) {
if (val2 == 1.0) {
Output[0] = LutTable[p -> Domain[0]];
return;
}
val2 = p -> Domain[0] * Value[0];
val2 *= p -> Domain[0];
cell0 = (int) floor(val2);
cell1 = (int) ceil(val2);
......@@ -339,8 +348,8 @@ void BilinearInterpFloat(const cmsFloat32Number Input[],
dxy;
TotalOut = p -> nOutputs;
px = Input[0] * p->Domain[0];
py = Input[1] * p->Domain[1];
px = fclamp(Input[0]) * p->Domain[0];
py = fclamp(Input[1]) * p->Domain[1];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
......@@ -454,20 +463,9 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
TotalOut = p -> nOutputs;
// We need some clipping here
px = Input[0];
py = Input[1];
pz = Input[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];
px = fclamp(Input[0]) * p->Domain[0];
py = fclamp(Input[1]) * p->Domain[1];
pz = fclamp(Input[2]) * p->Domain[2];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
......@@ -609,20 +607,9 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
TotalOut = p -> nOutputs;
// We need some clipping here
px = Input[0];
py = Input[1];
pz = Input[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];
px = fclamp(Input[0]) * p->Domain[0];
py = fclamp(Input[1]) * p->Domain[1];
pz = fclamp(Input[2]) * p->Domain[2];
x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0);
y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0);
......@@ -1039,8 +1026,7 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
pk = Input[0] * p->Domain[0];
pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
......@@ -1127,7 +1113,7 @@ void Eval5InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
pk = Input[0] * p->Domain[0];
pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
......@@ -1214,7 +1200,7 @@ void Eval6InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
pk = Input[0] * p->Domain[0];
pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
......@@ -1299,7 +1285,7 @@ void Eval7InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
pk = Input[0] * p->Domain[0];
pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
......@@ -1384,7 +1370,7 @@ void Eval8InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
pk = Input[0] * p->Domain[0];
pk = fclamp(Input[0]) * p->Domain[0];
k0 = _cmsQuickFloor(pk);
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
SctpNet.throwAlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkListen(isa.getPort());
}
Net.bind(fd, isa.getAddress(), isa.getPort());
InetSocketAddress boundIsa = Net.localAddress(fd);
port = boundIsa.getPort();
......
......@@ -138,8 +138,7 @@ static int useExclBind = 0;
* of the parameter is assumed to be an 'int'. If the parameter
* cannot be obtained return -1
*/
static int
getParam(char *driver, char *param)
int net_getParam(char *driver, char *param)
{
struct strioctl stri;
char buf [64];
......@@ -166,7 +165,7 @@ getParam(char *driver, char *param)
/*
* 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).
*
* 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,
* If that fails, we use the search algorithm in findMaxBuf()
*/
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) {
tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM);
if (tcp_max_buf == -1) {
......@@ -1368,7 +1367,7 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg,
}
init_tcp_max_buf = 1;
} 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) {
udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM);
if (udp_max_buf == -1) {
......
......@@ -81,6 +81,9 @@ extern int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout);
int getDefaultIPv6Interface(struct in6_addr *target_addr);
#endif
#ifdef __solaris__
extern int net_getParam(char *driver, char *param);
#endif
/* needed from libsocket on Solaris 8 */
......
......@@ -577,8 +577,8 @@ SplashEventLoop(Splash * splash) {
SplashUnlock(splash);
rc = poll(pfd, 2, timeout);
SplashLock(splash);
if (splash->isVisible>0 && SplashTime() >= splash->time +
splash->frames[splash->currentFrame].delay) {
if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
SplashNextFrame(splash);
SplashUpdateShape(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;
import java.net.*;
import java.util.concurrent.*;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import sun.misc.Unsafe;
/**
......@@ -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
<A> Future<Void> implConnect(SocketAddress remote,
A attachment,
......@@ -330,7 +346,12 @@ class WindowsAsynchronousSocketChannelImpl
throw new ConnectionPendingException();
if (localAddress == null) {
try {
bind(new InetSocketAddress(0));
SocketAddress any = new InetSocketAddress(0);
if (sm == null) {
bind(any);
} else {
doPrivilegedBind(any);
}
} catch (IOException 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 @@
/*
* @test
* @bug 6741606 7146431 8000450 8019830
* @bug 6741606 7146431 8000450 8019830 8022945
* @summary Make sure all restricted packages listed in the package.access
* property in the java.security file are blocked
* @run main/othervm CheckPackageAccess
......@@ -56,6 +56,7 @@ public class CheckPackageAccess {
"com.sun.istack.internal.",
"com.sun.jmx.",
"com.sun.media.sound.",
"com.sun.naming.internal.",
"com.sun.proxy.",
"com.sun.corba.se.",
"com.sun.org.apache.bcel.internal.",
......
/*
* 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 {
TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT);
rmid.addOptions(new String[]{
"-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();
/*
......
......@@ -29,6 +29,10 @@
# @run shell readTest.sh
OS=`uname -s`
VER=`uname -r`
ARGS=""
REGARGS=""
case "$OS" in
SunOS | Linux | Darwin )
PS=":"
......@@ -39,11 +43,19 @@ case "$OS" in
PS=";"
FS="\\"
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* )
PS=";"
FS="/"
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!"
......@@ -61,8 +73,8 @@ RMIREG_OUT=rmi.out
#start rmiregistry without any local classes on classpath
cd rmi_tmp
# NOTE: This RMI Registry port must match TestLibrary.READTEST_REGISTRY_PORT
${TESTJAVA}${FS}bin${FS}rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false \
${TESTTOOLVMOPTS} 64005 > ..${FS}${RMIREG_OUT} 2>&1 &
${TESTJAVA}${FS}bin${FS}rmiregistry ${REGARGS} -J-Djava.rmi.server.useCodebaseOnly=false \
${TESTTOOLVMOPTS} 60005 > ..${FS}${RMIREG_OUT} 2>&1 &
RMIREG_PID=$!
# allow some time to start
sleep 3
......@@ -74,10 +86,10 @@ case "$OS" in
;;
* )
CODEBASE=`pwd`
;;
;;
esac
# 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=$!
#bulk of testcase - let it run for a while
sleep 5
......@@ -100,7 +112,7 @@ grep "Test passed" OUT.TXT
result2=$?
if [ $result1 -eq 0 -a $result2 -eq 0 ]
then
then
echo "Passed"
exitCode=0;
else
......@@ -108,6 +120,6 @@ else
exitCode=1
fi
rm -rf OUT.TXT ${RMIREG_OUT} rmi_tmp
exit ${exitCode}
exit ${exitCode}
......@@ -86,13 +86,13 @@ public class TestLibrary {
* FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust
* FIXED_PORT_MIN/MAX appropriately.
*/
public final static int FIXED_PORT_MIN = 64001;
public final static int FIXED_PORT_MAX = 64010;
public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 64001;
public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 64002;
public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 64003;
public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 64004;
public final static int READTEST_REGISTRY_PORT = 64005;
public final static int FIXED_PORT_MIN = 60001;
public final static int FIXED_PORT_MAX = 60010;
public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 60001;
public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 60002;
public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 60003;
public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 60004;
public final static int READTEST_REGISTRY_PORT = 60005;
private final static int MAX_SERVER_SOCKET_TRIES = 2*(FIXED_PORT_MAX-FIXED_PORT_MIN+1);
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 {
" -J-Djava.security.egd=file:/dev/./urandom" +
" -debug -keystore " + TSKS + " -storepass changeit" +
" -tsa http://localhost:" + port + "/%d" +
" -signedjar new.jar " + JAR + " old";
" -signedjar new_%d.jar " + JAR + " old";
} else {
cmd = System.getProperty("java.home") + "/bin/jarsigner" +
" -J-Djava.security.egd=file:/dev/./urandom" +
" -debug -keystore " + TSKS + " -storepass changeit" +
" -tsa http://localhost:" + port + "/%d" +
" -signedjar new.jar " + JAR + " old";
" -signedjar new_%d.jar " + JAR + " old";
}
try {
......@@ -280,7 +280,7 @@ public class TimestampCheck {
static void jarsigner(String cmd, int path, boolean expected)
throws Exception {
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(
new InputStreamReader(p.getErrorStream()));
while (true) {
......@@ -288,9 +288,25 @@ public class TimestampCheck {
if (s == null) break;
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();
if (expected && result != 0 || !expected && result == 0) {
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`
# 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 notyetvalid -dname CN=notyetvalid -startdate +1m
$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 | \
$KT -importcert -alias badchain
$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
[ $? = 4 ] || exit $LINENO
......
......@@ -22,7 +22,7 @@
#
# @test
# @bug 6543842 6543440 6939248 8009636
# @bug 6543842 6543440 6939248 8009636 8024302
# @summary checking response of timestamp
#
# @run shell/timeout=600 ts.sh
......@@ -53,7 +53,7 @@ fi
JAR="${TESTJAVA}${FS}bin${FS}jar"
JAVA="${TESTJAVA}${FS}bin${FS}java"
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
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.
先完成此消息的编辑!
想要评论请 注册