# HG changeset patch # User asaha # Date 1386461708 28800 # Node ID d92379723173d679b2fac54962d9ecf8ae96cfcd # Parent 92ce9338bec4c95c28b79cf6e7c7007cf525ae06# Parent f87d595570497df03853380c00456d096ac76273 Merge diff -r 92ce9338bec4 -r d92379723173 make/CompileJavaClasses.gmk --- a/make/CompileJavaClasses.gmk Wed Dec 04 23:11:27 2013 -0800 +++ b/make/CompileJavaClasses.gmk Sat Dec 07 16:15:08 2013 -0800 @@ -274,11 +274,6 @@ $(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 @@ ########################################################################################## -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 ########################################################################################## diff -r 92ce9338bec4 -r d92379723173 make/CompileNativeLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/CreateJars.gmk --- a/make/CreateJars.gmk Wed Dec 04 23:11:27 2013 -0800 +++ b/make/CreateJars.gmk Sat Dec 07 16:15:08 2013 -0800 @@ -693,13 +693,6 @@ ########################################################################################## -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. diff -r 92ce9338bec4 -r d92379723173 make/CreateSecurityJars.gmk diff -r 92ce9338bec4 -r d92379723173 make/GenerateSources.gmk --- a/make/GenerateSources.gmk Wed Dec 04 23:11:27 2013 -0800 +++ b/make/GenerateSources.gmk Sat Dec 07 16:15:08 2013 -0800 @@ -85,11 +85,6 @@ 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) diff -r 92ce9338bec4 -r d92379723173 make/Images.gmk --- a/make/Images.gmk Wed Dec 04 23:11:27 2013 -0800 +++ b/make/Images.gmk Sat Dec 07 16:15:08 2013 -0800 @@ -303,14 +303,13 @@ $(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)/%,%,$@) diff -r 92ce9338bec4 -r d92379723173 make/Profiles.gmk --- a/make/Profiles.gmk Wed Dec 04 23:11:27 2013 -0800 +++ b/make/Profiles.gmk Sat Dec 07 16:15:08 2013 -0800 @@ -105,10 +105,6 @@ 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) diff -r 92ce9338bec4 -r d92379723173 make/lib/Awt2dLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/lib/CoreLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/lib/NetworkingLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/lib/NioLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/lib/PlatformLibraries.gmk --- a/make/lib/PlatformLibraries.gmk Wed Dec 04 23:11:27 2013 -0800 +++ b/make/lib/PlatformLibraries.gmk Sat Dec 07 16:15:08 2013 -0800 @@ -136,64 +136,6 @@ ########################################################################################## -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) diff -r 92ce9338bec4 -r d92379723173 make/lib/SecurityLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/lib/ServiceabilityLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 make/lib/SoundLibraries.gmk diff -r 92ce9338bec4 -r d92379723173 src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m --- a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m Wed Dec 04 23:11:27 2013 -0800 +++ b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m Sat Dec 07 16:15:08 2013 -0800 @@ -290,8 +290,8 @@ 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); } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/beans/decoder/DocumentHandler.java --- a/src/share/classes/com/sun/beans/decoder/DocumentHandler.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/beans/decoder/DocumentHandler.java Sat Dec 07 16:15:08 2013 -0800 @@ -29,6 +29,7 @@ import java.beans.ExceptionListener; import java.io.IOException; +import java.io.StringReader; import java.lang.ref.Reference; import java.lang.ref.WeakReference; @@ -246,6 +247,14 @@ } /** + * 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. */ @Override diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java --- a/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,13 +72,17 @@ 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"); } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/jmx/snmp/agent/SnmpMibEntry.java --- a/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibEntry.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibEntry.java Sat Dec 07 16:15:08 2013 -0800 @@ -27,17 +27,9 @@ // 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 void validateVarId(long arc, Object userData) throws SnmpStatusException { - if (isVariable(arc) == false) throw noSuchNameException; + if (isVariable(arc) == false) { + throw new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName); + } } /** diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/jmx/snmp/agent/SnmpMibGroup.java --- a/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibGroup.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibGroup.java Sat Dec 07 16:15:08 2013 -0800 @@ -108,8 +108,9 @@ */ 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 @@ 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 @@ 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 @@ depth+1,handlers, checker); }catch(SnmpStatusException ex) { - throw noSuchObjectException; + throw new SnmpStatusException(SnmpStatusException.noSuchObject); } finally { checker.remove(depth); } @@ -455,7 +460,7 @@ try { checker.checkCurrentOid(); } catch(SnmpStatusException e) { - throw noSuchObjectException; + throw new SnmpStatusException(SnmpStatusException.noSuchObject); } finally { checker.remove(depth,2); } @@ -500,7 +505,7 @@ // 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 diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/jmx/snmp/agent/SnmpMibNode.java --- a/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibNode.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibNode.java Sat Dec 07 16:15:08 2013 -0800 @@ -155,7 +155,7 @@ long[] oid, int depth, SnmpRequestTree handlers) throws SnmpStatusException { - throw noSuchObjectException; + throw new SnmpStatusException(SnmpStatusException.noSuchObject); } /** @@ -183,7 +183,7 @@ long[] oid, int pos, int depth, SnmpRequestTree handlers, AcmChecker checker) throws SnmpStatusException { - throw noSuchObjectException; + throw new SnmpStatusException(SnmpStatusException.noSuchObject); } /** @@ -346,8 +346,9 @@ 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 @@ // 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 @@ * 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); } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/jmx/snmp/agent/SnmpMibOid.java --- a/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibOid.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibOid.java Sat Dec 07 16:15:08 2013 -0800 @@ -160,12 +160,10 @@ 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 @@ 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 @@ // 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 @@ // 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 @@ try { child = children.elementAtNonSync(pos); } catch(ArrayIndexOutOfBoundsException e) { - throw noSuchObjectException; + throw new SnmpStatusException(SnmpStatusException.noSuchObject); } - if (child == null) - throw noSuchInstanceException; + if (child == null) { + throw new SnmpStatusException(SnmpStatusException.noSuchInstance); + } return child; } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/jmx/snmp/agent/SnmpMibTable.java --- a/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibTable.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/jmx/snmp/agent/SnmpMibTable.java Sat Dec 07 16:15:08 2013 -0800 @@ -280,7 +280,7 @@ SnmpVarBind var; for (Enumeration e= r.getElements(); e.hasMoreElements();) { var = e.nextElement(); - r.registerGetException(var,noSuchInstanceException); + r.registerGetException(var,new SnmpStatusException(SnmpStatusException.noSuchInstance)); } } @@ -1607,8 +1607,9 @@ 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 @@ 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 @@ // 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 @@ */ 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 @@ // 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 @@ 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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); + } } // ---------------------------------------------------------------------- diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/jmx/snmp/daemon/SnmpRequestHandler.java --- a/src/share/classes/com/sun/jmx/snmp/daemon/SnmpRequestHandler.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/jmx/snmp/daemon/SnmpRequestHandler.java Sat Dec 07 16:15:08 2013 -0800 @@ -1146,7 +1146,4 @@ static final private String InterruptSysCallMsg = "Interrupted system call"; - - static final private SnmpStatusException noSuchNameException = - new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName) ; } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/naming/internal/FactoryEnumeration.java --- a/src/share/classes/com/sun/naming/internal/FactoryEnumeration.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/naming/internal/FactoryEnumeration.java Sat Dec 07 16:15:08 2013 -0800 @@ -56,9 +56,12 @@ * 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> factories, ClassLoader loader) { @@ -79,7 +82,9 @@ try { if (answer == null) { // reload class if weak ref cleared - answer = Class.forName(className, true, loader); + Class cls = Class.forName(className, true, loader); + VersionHelper12.checkPackageAccess(cls); + answer = cls; } // Instantiate Class to get factory answer = ((Class) answer).newInstance(); diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/naming/internal/VersionHelper12.java --- a/src/share/classes/com/sun/naming/internal/VersionHelper12.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/naming/internal/VersionHelper12.java Sat Dec 07 16:15:08 2013 -0800 @@ -39,6 +39,7 @@ import java.util.Properties; import javax.naming.*; +import sun.reflect.misc.ReflectUtil; /** * VersionHelper was used by JNDI to accommodate differences between @@ -53,21 +54,39 @@ final class VersionHelper12 extends VersionHelper { - private boolean getSystemPropsFailed = false; + // workaround to disable additional package access control with + // Thread Context Class Loader (TCCL). + private final static boolean noPackageAccessWithTCCL = "true".equals( + AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return System.getProperty( + "com.sun.naming.untieAccessContextWithTCCL"); + } + } + )); - 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); + if (!noPackageAccessWithTCCL) { + checkPackageAccess(cls); + } + return cls; } /** @@ -75,13 +94,42 @@ * @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 loadClass(className, cl); + } - return Class.forName(className, true, cl); + /** + * check package access of a class that is loaded with Thread Context + * Class Loader (TCCL). + * + * Similar to java.lang.ClassLoader.checkPackageAccess() + */ + static void checkPackageAccess(Class cls) { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (ReflectUtil.isNonPublicProxyClass(cls)) { + for (Class intf: cls.getInterfaces()) { + checkPackageAccess(intf); + } + return; + } + + final String name = cls.getName(); + final int i = name.lastIndexOf('.'); + if (i != -1) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + sm.checkPackageAccess(name.substring(0, i)); + return null; + } + }, AccessController.getContext()); + } + } } String getJndiProperty(final int i) { @@ -99,16 +147,12 @@ } String[] getJndiProperties() { - if (getSystemPropsFailed) { - return null; // after one failure, don't bother trying again - } Properties sysProps = AccessController.doPrivileged( new PrivilegedAction() { public Properties run() { try { return System.getProperties(); } catch (SecurityException e) { - getSystemPropsFailed = true; return null; } } @@ -173,7 +217,17 @@ return new InputStreamEnumeration(urls); } + /** + * Package private. + * + * This internal method makes use of Thread Context Class Loader (TCCL), + * please don't expose this method as public. + * + * Please take care of package access control on the current context + * whenever using TCCL. + */ ClassLoader getContextClassLoader() { + return AccessController.doPrivileged( new PrivilegedAction() { public ClassLoader run() { @@ -183,7 +237,6 @@ ); } - /** * Given an enumeration of URLs, an instance of this class represents * an enumeration of their InputStreams. Each operation on the URL diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java --- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java Sat Dec 07 16:15:08 2013 -0800 @@ -382,7 +382,8 @@ } 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) { diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java --- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java Sat Dec 07 16:15:08 2013 -0800 @@ -327,7 +327,8 @@ } 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) { diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java --- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java Sat Dec 07 16:15:08 2013 -0800 @@ -292,7 +292,7 @@ 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; diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java --- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java Sat Dec 07 16:15:08 2013 -0800 @@ -34,8 +34,6 @@ 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 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,7 +63,6 @@ public static final String XMLNS = "xmlns"; protected static final AttrCompare COMPARE = new AttrCompare(); - protected static final Attr nullNode; private static final byte[] END_PI = {'?','>'}; private static final byte[] BEGIN_PI = {'<','?'}; @@ -84,21 +82,11 @@ 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; private boolean includeComments; private Set xpathNodeSet; + /** * The node to be skipped/excluded from the DOM tree * in subtree canonicalizations. @@ -107,6 +95,11 @@ private OutputStream writer = new ByteArrayOutputStream(); /** + * The null xmlns definition. + */ + private Attr nullNode; + + /** * Constructor CanonicalizerBase * * @param includeComments @@ -641,8 +634,9 @@ 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())); } } @@ -879,4 +873,18 @@ } } + // 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; + } + } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java --- a/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -660,7 +660,7 @@ //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())); diff -r 92ce9338bec4 -r d92379723173 src/share/classes/java/util/jar/JarFile.java --- a/src/share/classes/java/util/jar/JarFile.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/java/util/jar/JarFile.java Sat Dec 07 16:15:08 2013 -0800 @@ -53,6 +53,13 @@ * 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 diff -r 92ce9338bec4 -r d92379723173 src/share/classes/java/util/jar/JarVerifier.java --- a/src/share/classes/java/util/jar/JarVerifier.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/java/util/jar/JarVerifier.java Sat Dec 07 16:15:08 2013 -0800 @@ -179,7 +179,9 @@ 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; } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/java/util/logging/LogManager.java --- a/src/share/classes/java/util/logging/LogManager.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/java/util/logging/LogManager.java Sat Dec 07 16:15:08 2013 -0800 @@ -241,6 +241,11 @@ * 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()); @@ -250,6 +255,19 @@ } } + 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 diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/print/SimpleDoc.java --- a/src/share/classes/javax/print/SimpleDoc.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/print/SimpleDoc.java Sat Dec 07 16:15:08 2013 -0800 @@ -91,7 +91,10 @@ 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"); } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/security/auth/Policy.java --- a/src/share/classes/javax/security/auth/Policy.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/security/auth/Policy.java Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ 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() { - public ClassLoader run() { - return Thread.currentThread().getContextClassLoader(); - } - }); - }; - /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) @@ -213,8 +210,8 @@ if (policy == null) { String policy_class = null; - policy_class = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { + policy_class = AccessController.doPrivileged + (new PrivilegedAction() { public String run() { return java.security.Security.getProperty ("auth.policy.provider"); @@ -226,18 +223,28 @@ try { final String finalClass = policy_class; - policy = java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - 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() { + public Policy run() throws ClassNotFoundException, + InstantiationException, + IllegalAccessException { + Class implClass = Class.forName( + finalClass, false, + Thread.currentThread().getContextClassLoader() + ).asSubclass(Policy.class); + return implClass.newInstance(); + } + }); + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + 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 diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/security/auth/Subject.java --- a/src/share/classes/javax/security/auth/Subject.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/security/auth/Subject.java Sat Dec 07 16:15:08 2013 -0800 @@ -964,6 +964,10 @@ s.defaultReadObject(); + // Rewrap the principals into a SecureSet + principals = Collections.synchronizedSet(new SecureSet + (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 diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/security/auth/login/Configuration.java --- a/src/share/classes/javax/security/auth/login/Configuration.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/security/auth/login/Configuration.java Sat Dec 07 16:15:08 2013 -0800 @@ -27,9 +27,6 @@ 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.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 @@ public abstract class Configuration { private static Configuration configuration; - private static ClassLoader contextClassLoader; - static { - contextClassLoader = AccessController.doPrivileged - (new PrivilegedAction() { - 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 @@ try { final String finalClass = config_class; - configuration = AccessController.doPrivileged - (new PrivilegedExceptionAction() { - public Configuration run() throws ClassNotFoundException, - InstantiationException, - IllegalAccessException { - return (Configuration)Class.forName - (finalClass, - true, - contextClassLoader).newInstance(); - } - }); + Configuration untrustedImpl = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Configuration run() throws ClassNotFoundException, + InstantiationException, + IllegalAccessException { + Class implClass = Class.forName( + finalClass, false, + Thread.currentThread().getContextClassLoader() + ).asSubclass(Configuration.class); + return implClass.newInstance(); + } + }); + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() { + setConfiguration(untrustedImpl); + return null; + } + }, Objects.requireNonNull(untrustedImpl.acc) + ); } catch (PrivilegedActionException e) { Exception ee = e.getException(); if (ee instanceof InstantiationException) { diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/security/auth/login/LoginContext.java --- a/src/share/classes/javax/security/auth/login/LoginContext.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/security/auth/login/LoginContext.java Sat Dec 07 16:15:08 2013 -0800 @@ -37,8 +37,10 @@ import javax.security.auth.callback.*; import java.security.AccessController; import java.security.AccessControlContext; +import java.security.PrivilegedAction; import sun.security.util.PendingException; import sun.security.util.ResourcesMgr; +import sun.reflect.misc.ReflectUtil; /** *

The {@code LoginContext} class describes the basic methods used @@ -209,8 +211,7 @@ private Map state = new HashMap(); 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 = { }; @@ -226,10 +227,23 @@ private static final sun.security.util.Debug debug = sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]"); + // workaround to disable additional package access control with + // Thread Context Class Loader (TCCL). + private static final boolean noPackageAccessWithTCCL = "true".equals( + AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return System.getProperty( + "auth.login.untieAccessContextWithTCCL"); + } + } + )); + + 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 +266,7 @@ AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name); if (entries == null) { - if (sm != null && !configProvided) { + if (sm != null && creatorAcc == null) { sm.checkPermission(new AuthPermission ("createLoginContext." + OTHER)); } @@ -298,10 +312,10 @@ (DEFAULT_HANDLER); if (defaultHandler == null || defaultHandler.length() == 0) return null; - Class c = Class.forName(defaultHandler, - true, - finalLoader); - return (CallbackHandler)c.newInstance(); + Class c = Class.forName( + defaultHandler, true, + finalLoader).asSubclass(CallbackHandler.class); + return c.newInstance(); } }); } catch (java.security.PrivilegedActionException pae) { @@ -309,7 +323,7 @@ } // 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 +512,7 @@ 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 +523,7 @@ } if (callbackHandler == null) { loadDefaultCallbackHandler(); - } else if (!configProvided) { + } else if (creatorAcc == null) { this.callbackHandler = new SecureCallbackHandler (java.security.AccessController.getContext(), callbackHandler); @@ -577,23 +590,13 @@ } 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 +631,8 @@ ("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,7 +675,8 @@ /** * 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. @@ -690,29 +689,6 @@ 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() { - public Void run() throws LoginException { - invoke(methodName); - return null; - } }, creatorAcc); } catch (java.security.PrivilegedActionException pae) { throw (LoginException)pae.getException(); @@ -735,24 +711,30 @@ } 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 if no customized config or + // noPackageAccessWithTCCL is true. + Class c = Class.forName( + moduleStack[i].entry.getLoginModuleName(), true, contextClassLoader); + // check package access for customized config + if (!noPackageAccessWithTCCL && creatorAcc != null) { + c.asSubclass(javax.security.auth.spi.LoginModule.class); + checkPackageAccess(c, creatorAcc); + } 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); + // call the LoginModule's initialize method methods = moduleStack[i].module.getClass().getMethods(); - - // call the LoginModule's initialize method 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 +742,28 @@ 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(); @@ -936,6 +927,35 @@ } /** + * check package access of a class that is loaded with Thread Context + * Class Loader (TCCL) with specified access control context. + * + * Similar to java.lang.ClassLoader.checkPackageAccess() + */ + static void checkPackageAccess(Class cls, AccessControlContext context) { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (ReflectUtil.isNonPublicProxyClass(cls)) { + for (Class intf: cls.getInterfaces()) { + checkPackageAccess(intf, context); + } + return; + } + + final String name = cls.getName(); + final int i = name.lastIndexOf('.'); + if (i != -1) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + sm.checkPackageAccess(name.substring(0, i)); + return null; + } + }, context); + } + } + } + + /** * Wrap the caller-specified CallbackHandler in our own * and invoke it within a privileged block, constrained by * the caller's AccessControlContext. diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/sql/rowset/spi/SyncFactory.java --- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Sat Dec 07 16:15:08 2013 -0800 @@ -35,6 +35,8 @@ 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 @@ /* * Dependent on application */ - String strRowsetProperties = System.getProperty("rowset.properties"); + String strRowsetProperties; + try { + strRowsetProperties = AccessController.doPrivileged(new PrivilegedAction() { + 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 @@ * load additional properties from -D command line */ properties.clear(); - String providerImpls = System.getProperty(ROWSET_SYNC_PROVIDER); + String providerImpls; + try { + providerImpls = AccessController.doPrivileged(new PrivilegedAction() { + 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; diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/swing/SwingUtilities.java --- a/src/share/classes/javax/swing/SwingUtilities.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/swing/SwingUtilities.java Sat Dec 07 16:15:08 2013 -0800 @@ -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.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 @@ static Class loadSystemClass(String className) throws ClassNotFoundException { + ReflectUtil.checkPackageAccess(className); return Class.forName(className, true, Thread.currentThread(). getContextClassLoader()); } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/javax/swing/event/EventListenerList.java --- a/src/share/classes/javax/swing/event/EventListenerList.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/javax/swing/event/EventListenerList.java Sat Dec 07 16:15:08 2013 -0800 @@ -27,6 +27,7 @@ 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 @@ while (null != (listenerTypeOrNull = s.readObject())) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); EventListener l = (EventListener)s.readObject(); - add((Class)Class.forName((String)listenerTypeOrNull, true, cl), l); + String name = (String) listenerTypeOrNull; + ReflectUtil.checkPackageAccess(name); + add((Class)Class.forName(name, true, cl), l); } } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java --- a/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Sat Dec 07 16:15:08 2013 -0800 @@ -28,7 +28,10 @@ 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.generics.factory.GenericsFactory; import sun.reflect.generics.tree.FieldTypeSignature; import sun.reflect.generics.visitor.Reifier; +import sun.reflect.misc.ReflectUtil; /** * Implementation of java.lang.reflect.TypeVariable interface @@ -95,6 +99,13 @@ TypeVariableImpl 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(decl, name, bs, f); } @@ -149,6 +160,13 @@ * @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 @@ @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(); diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/reflect/misc/ReflectUtil.java --- a/src/share/classes/sun/reflect/misc/ReflectUtil.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/reflect/misc/ReflectUtil.java Sat Dec 07 16:15:08 2013 -0800 @@ -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 { @@ -118,6 +120,40 @@ } /** + * 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. * * If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java --- a/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,11 +45,12 @@ private final int majorVersion; private final int minorVersion; + private final byte[] encodedSecret; /** * Constructs a new TlsRsaPremasterSecretParameterSpec. - * - *

The version numbers will be placed inside the premaster secret to + *

+ * The version numbers will be placed inside the premaster secret to * detect version rollbacks attacks as described in the TLS specification. * Note that they do not indicate the protocol version negotiated for * the handshake. @@ -65,7 +66,42 @@ this.majorVersion = TlsMasterSecretParameterSpec.checkVersion(majorVersion); this.minorVersion = - TlsMasterSecretParameterSpec.checkVersion(minorVersion); } + TlsMasterSecretParameterSpec.checkVersion(minorVersion); + this.encodedSecret = null; + } + + /** + * Constructs a new TlsRsaPremasterSecretParameterSpec. + *

+ * 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. + *

+ * 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 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(); + } } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/pkcs11/P11RSACipher.java --- a/src/share/classes/sun/security/pkcs11/P11RSACipher.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/pkcs11/P11RSACipher.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -451,30 +451,7 @@ // 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) { diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java --- a/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,23 +88,33 @@ 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"); } } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/provider/ByteArrayAccess.java --- a/src/share/classes/sun/security/provider/ByteArrayAccess.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/provider/ByteArrayAccess.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,10 +43,8 @@ * 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 @@ * 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 @@ // 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 @@ * 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 @@ // 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 @@ * 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 @@ // 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 @@ * 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 @@ // 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 @@ * 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 @@ // 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 @@ * 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 @@ out[outOfs++] = (byte)(i ); } } - } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/rsa/RSAPadding.java --- a/src/share/classes/sun/security/rsa/RSAPadding.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/rsa/RSAPadding.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -318,33 +318,53 @@ /** * 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; } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/ssl/Handshaker.java --- a/src/share/classes/sun/security/ssl/Handshaker.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/ssl/Handshaker.java Sat Dec 07 16:15:08 2013 -0800 @@ -1104,94 +1104,23 @@ 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); } - - // 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; - } + throw new ProviderException(iae); - // 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); } /* diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/ssl/RSAClientKeyExchange.java --- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Sat Dec 07 16:15:08 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,26 +133,37 @@ } 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); + // 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) { + // 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, preMaster, null); - } catch (Exception e) { - // polish the premaster secret - preMaster = - polishPreMasterSecretKey(currentVersion, maxVersion, - generator, null, e); - } + // polish the premaster secret + preMaster = polishPreMasterSecretKey( + currentVersion, maxVersion, generator, encoded, failover); } /** @@ -163,85 +174,74 @@ * * 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 generateDummySecret(clientHelloVersion); - } + return generatePreMasterSecret( + clientHelloVersion, random, generator); + } - // 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]) { + 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 @@ 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 @@ 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); } } diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/tools/jarsigner/Main.java --- a/src/share/classes/sun/security/tools/jarsigner/Main.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/tools/jarsigner/Main.java Sat Dec 07 16:15:08 2013 -0800 @@ -158,8 +158,13 @@ private String altSignerClasspath = null; private ZipFile zipFile = null; + // 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 hasExpiringCert = false; private boolean notYetValidCert = false; private boolean chainNotValidated = false; private boolean notSignedByAlias = false; @@ -258,9 +263,6 @@ if (strict) { int exitCode = 0; - if (hasExpiringCert) { - exitCode |= 2; - } if (chainNotValidated || hasExpiredCert || notYetValidCert) { exitCode |= 4; } @@ -754,14 +756,25 @@ 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) { - System.out.println(); - System.out.println(rb.getString("Warning.")); + 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; + } + 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 @@ 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 @@ 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 @@ 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 @@ tsaCert = getTsaCert(tsaAlias); } + if (tsaUrl == null && tsaCert == null) { + noTimestamp = true; + } + SignatureFile.Block block = null; try { @@ -1380,12 +1415,20 @@ } } - 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 @@ 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 @@ 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 @@ 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. diff -r 92ce9338bec4 -r d92379723173 src/share/classes/sun/security/tools/jarsigner/Resources.java --- a/src/share/classes/sun/security/tools/jarsigner/Resources.java Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/classes/sun/security/tools/jarsigner/Resources.java Sat Dec 07 16:15:08 2013 -0800 @@ -112,9 +112,9 @@ {"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 @@ {".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 @@ "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 @@ "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: "}, diff -r 92ce9338bec4 -r d92379723173 src/share/lib/security/java.security-linux --- a/src/share/lib/security/java.security-linux Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/lib/security/java.security-linux Sat Dec 07 16:15:08 2013 -0800 @@ -182,6 +182,7 @@ 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 @@ 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 @@ 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 @@ 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.,\ diff -r 92ce9338bec4 -r d92379723173 src/share/lib/security/java.security-macosx --- a/src/share/lib/security/java.security-macosx Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/lib/security/java.security-macosx Sat Dec 07 16:15:08 2013 -0800 @@ -183,6 +183,7 @@ 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 @@ 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.,\ diff -r 92ce9338bec4 -r d92379723173 src/share/lib/security/java.security-solaris --- a/src/share/lib/security/java.security-solaris Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/lib/security/java.security-solaris Sat Dec 07 16:15:08 2013 -0800 @@ -184,6 +184,7 @@ 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 @@ 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 @@ 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 @@ 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.,\ diff -r 92ce9338bec4 -r d92379723173 src/share/lib/security/java.security-windows --- a/src/share/lib/security/java.security-windows Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/lib/security/java.security-windows Sat Dec 07 16:15:08 2013 -0800 @@ -183,6 +183,7 @@ 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 @@ 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 @@ 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 @@ 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.,\ diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/awt/splashscreen/splashscreen_impl.c --- a/src/share/native/sun/awt/splashscreen/splashscreen_impl.c Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/awt/splashscreen/splashscreen_impl.c Sat Dec 07 16:15:08 2013 -0800 @@ -111,8 +111,9 @@ 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 @@ 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 @@ 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 @@ 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) { diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/AlternateSubstSubtables.cpp --- a/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -55,7 +55,7 @@ (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])); } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/AnchorTables.cpp --- a/src/share/native/sun/font/layout/AnchorTables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/AnchorTables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -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 f1(base, success); + f1->getAnchor(f1, fontInstance, anchor, success); break; } case 2: { - const Format2AnchorTable *f2 = (const Format2AnchorTable *) this; - - f2->getAnchor(glyphID, fontInstance, anchor); + LEReferenceTo f2(base, success); + f2->getAnchor(f2, glyphID, fontInstance, anchor, success); break; } case 3: { - const Format3AnchorTable *f3 = (const Format3AnchorTable *) this; - - f3->getAnchor(fontInstance, anchor); + LEReferenceTo 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 f1(base, success); + f1->getAnchor(f1, fontInstance, anchor, success); break; } + } } -void Format1AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const +void Format1AnchorTable::getAnchor(const LEReferenceTo& 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& base, + LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor + , LEErrorCode &success) const { LEPoint point; @@ -100,7 +99,8 @@ fontInstance->pixelsToUnits(point, anchor); } -void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const +void Format3AnchorTable::getAnchor(const LEReferenceTo &base, const LEFontInstance *fontInstance, + LEPoint &anchor, LEErrorCode &success) const { le_int16 x = SWAPW(xCoordinate); le_int16 y = SWAPW(yCoordinate); @@ -111,15 +111,15 @@ 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 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 dt(base, success, dtyOffset); + le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success); pixels.fY += adjy; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/AnchorTables.h --- a/src/share/native/sun/font/layout/AnchorTables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/AnchorTables.h Sat Dec 07 16:15:08 2013 -0800 @@ -49,20 +49,23 @@ 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& 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& base, + LEGlyphID glyphID, const LEFontInstance *fontInstance, + LEPoint &anchor, LEErrorCode &success) const; }; struct Format3AnchorTable : AnchorTable @@ -70,7 +73,9 @@ Offset xDeviceTableOffset; Offset yDeviceTableOffset; - void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const; + void getAnchor(const LEReferenceTo& base, + const LEFontInstance *fontInstance, LEPoint &anchor, + LEErrorCode &success) const; }; U_NAMESPACE_END diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ArabicLayoutEngine.cpp --- a/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ GDEFMarkFilter filter(fGDEFTable, success); adjustMarkGlyphs(glyphStorage, &filter, success); } else { - LEReferenceTo gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); + LEReferenceTo gdefTable(LETableReference::kStaticData, + CanonShaping::glyphDefinitionTable, + CanonShaping::glyphDefinitionTableLen); GDEFMarkFilter filter(gdefTable, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); @@ -157,9 +159,9 @@ 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() diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ArabicShaping.cpp --- a/src/share/native/sun/font/layout/ArabicShaping.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ArabicShaping.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -59,7 +59,8 @@ ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) { LEErrorCode success = LE_NO_ERROR; - const LEReferenceTo joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable, + const LEReferenceTo joiningTypes(LETableReference::kStaticData, + (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable, ArabicShaping::shapingTypeTableLen); le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/CanonShaping.cpp --- a/src/share/native/sun/font/layout/CanonShaping.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/CanonShaping.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -60,7 +60,7 @@ LEUnicode *outChars, LEGlyphStorage &glyphStorage) { LEErrorCode success = LE_NO_ERROR; - LEReferenceTo gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); + LEReferenceTo gdefTable(LETableReference::kStaticData, CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); LEReferenceTo classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success); le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount); le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/CharSubstitutionFilter.h --- a/src/share/native/sun/font/layout/CharSubstitutionFilter.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/CharSubstitutionFilter.h Sat Dec 07 16:15:08 2013 -0800 @@ -43,6 +43,8 @@ * 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 @@ * * @internal */ - le_bool accept(LEGlyphID glyph) const; + le_bool accept(LEGlyphID glyph, LEErrorCode &success) const; }; U_NAMESPACE_END diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ClassDefinitionTables.h --- a/src/share/native/sun/font/layout/ClassDefinitionTables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ClassDefinitionTables.h Sat Dec 07 16:15:08 2013 -0800 @@ -49,6 +49,7 @@ 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 @@ LEErrorCode ignored = LE_NO_ERROR; return hasGlyphClass(base,glyphClass,ignored); } +#endif }; struct ClassDefFormat1Table : ClassDefinitionTable diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ContextualSubstSubtables.cpp --- a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -48,7 +48,7 @@ */ void ContextualSubstitutionBase::applySubstitutionLookups( const LookupProcessor *lookupProcessor, - const SubstitutionLookupRecord *substLookupRecordArray, + const LEReferenceToArrayOf& substLookupRecordArray, le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, @@ -60,10 +60,11 @@ } 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 @@ } } -le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, le_uint16 glyphCount, +le_bool ContextualSubstitutionBase::matchGlyphIDs(const LEReferenceToArrayOf& glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator, le_bool backtrack) { le_int32 direction = 1; @@ -101,10 +102,13 @@ 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 &classArray, + le_uint16 glyphCount, + GlyphIterator *glyphIterator, + const LEReferenceTo &classDefinitionTable, + LEErrorCode &success, + le_bool backtrack) { le_int32 direction = 1; le_int32 match = 0; @@ -120,7 +124,7 @@ } 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 @@ // 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 @@ 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 &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 @@ while (glyphCount > 0) { Offset coverageTableOffset = SWAPW(coverageTableOffsetArray[glyph]); - const CoverageTable *coverageTable = (const CoverageTable *) (offsetBase + coverageTableOffset); + LEReferenceTo 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 @@ 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 @@ case 1: { - const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this; - return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); + LEReferenceTo 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 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 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 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 @@ if (coverageIndex < srSetCount) { Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); - const SubRuleSetTable *subRuleSetTable = - (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset); + LEReferenceTo + 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(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 inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2); + if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) { + LEReferenceToArrayOf + substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); @@ -259,10 +274,11 @@ 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 @@ } if (coverageIndex >= 0) { - const ClassDefinitionTable *classDefinitionTable = - (const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)); + LEReferenceTo 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(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(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 classArray(base, success, subClassRuleTable->classArray, matchCount+1); + + if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) { + LEReferenceToArrayOf + substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); @@ -314,7 +334,8 @@ 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 @@ // 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 covTableOffsetArray(base, success, coverageTableOffsetArray, gCount); + + if( LE_FAILURE(success) ) { return 0; } + + if (ContextualSubstitutionBase::matchGlyphCoverages(covTableOffsetArray, gCount, glyphIterator, base, success)) { + LEReferenceToArrayOf + substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount], subCount); ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success); @@ -347,7 +372,8 @@ return 0; } -le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, +le_uint32 ChainingContextualSubstitutionSubtable::process(const LEReferenceTo &base, + const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const @@ -363,20 +389,23 @@ case 1: { - const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this; - return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); + LEReferenceTo 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 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 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 @@ // 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 @@ if (coverageIndex < srSetCount) { Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); - const ChainSubRuleSetTable *chainSubRuleSetTable = - (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset); + LEReferenceTo + 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 @@ 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 = LEReferenceTo(chainSubRuleSetTable, success, chainSubRuleTableOffset); + if( LE_FAILURE(success) ) { return 0; } le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount); + LEReferenceToArrayOf 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 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 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 @@ } tempIterator.prev(); - if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) { + + if (! matchGlyphIDs(backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) { continue; } @@ -446,8 +482,8 @@ } if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) { - const SubstitutionLookupRecord *substLookupRecordArray = - (const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1]; + LEReferenceToArrayOf + substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadGlyphArray.getAlias(lookaheadGlyphCount + 1,success), substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); @@ -464,7 +500,7 @@ 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 @@ } 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 + backtrackClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset))); + LEReferenceTo + inputClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset))); + LEReferenceTo + 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(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 @@ 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(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 inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count + le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success)); + LEReferenceToArrayOf 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 @@ } tempIterator.prev(); - if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount, - &tempIterator, backtrackClassDefinitionTable, TRUE)) { + LEReferenceToArrayOf 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 + substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); @@ -547,7 +589,7 @@ 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_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); - const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1]; + LEReferenceToArrayOf 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 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 @@ 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 @@ glyphIterator->prev(); if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray, - inputGlyphCount, glyphIterator, (const char *) this)) { - const SubstitutionLookupRecord *substLookupRecordArray = - (const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1]; + inputGlyphCount, glyphIterator, base, success)) { + LEReferenceToArrayOf + substLookupRecordArray(base, success, + (const SubstitutionLookupRecord *) lookaheadCoverageTableOffsetArray.getAlias(lookaheadGlyphCount + 1,success), substCount); ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ContextualSubstSubtables.h --- a/src/share/native/sun/font/layout/ContextualSubstSubtables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.h Sat Dec 07 16:15:08 2013 -0800 @@ -56,20 +56,32 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable { static le_bool matchGlyphIDs( - const TTGlyphID *glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator, + const LEReferenceToArrayOf &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 &classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator, + const LEReferenceTo &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 &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 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& substLookupRecordArray, le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, @@ -79,7 +91,8 @@ 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 @@ 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 @@ 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 @@ 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 &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable @@ -166,7 +182,8 @@ 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 @@ 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 @@ //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) diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/CoverageTables.cpp --- a/src/share/native/sun/font/layout/CoverageTables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/CoverageTables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ case 1: { - const CoverageFormat1Table *f1Table = (const CoverageFormat1Table *) this; + LEReferenceTo f1Table(base, success); - return f1Table->getGlyphCoverage(glyphID); + return f1Table->getGlyphCoverage(f1Table, glyphID, success); } case 2: { - const CoverageFormat2Table *f2Table = (const CoverageFormat2Table *) this; + LEReferenceTo f2Table(base, success); - return f2Table->getGlyphCoverage(glyphID); + return f2Table->getGlyphCoverage(f2Table, glyphID, success); } default: @@ -63,8 +65,10 @@ } } -le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const +le_int32 CoverageFormat1Table::getGlyphCoverage(LEReferenceTo &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_uint16 probe = power; le_uint16 index = 0; - if (count == 0) { - return -1; - } + if (count == 0) { + return -1; + } + + LEReferenceToArrayOf(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 &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 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; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/CoverageTables.h --- a/src/share/native/sun/font/layout/CoverageTables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/CoverageTables.h Sat Dec 07 16:15:08 2013 -0800 @@ -46,7 +46,7 @@ { 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 @@ le_uint16 glyphCount; TTGlyphID glyphArray[ANY_NUMBER]; - le_int32 getGlyphCoverage(LEGlyphID glyphID) const; + le_int32 getGlyphCoverage(LEReferenceTo &base, LEGlyphID glyphID, LEErrorCode &success) const; }; LE_VAR_ARRAY(CoverageFormat1Table, glyphArray) @@ -64,7 +64,7 @@ le_uint16 rangeCount; GlyphRangeRecord rangeRecordArray[ANY_NUMBER]; - le_int32 getGlyphCoverage(LEGlyphID glyphID) const; + le_int32 getGlyphCoverage(LEReferenceTo &base, LEGlyphID glyphID, LEErrorCode &success) const; }; LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray) diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp --- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -51,23 +51,27 @@ } 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 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 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(); } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/DeviceTables.cpp --- a/src/share/native/sun/font/layout/DeviceTables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/DeviceTables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -43,7 +43,7 @@ #define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits) -le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const +le_int16 DeviceTable::getAdjustment(const LEReferenceTo&base, le_uint16 ppem, LEErrorCode &success) const { le_uint16 start = SWAPW(startSize); le_uint16 format = SWAPW(deltaFormat) - 1; @@ -53,6 +53,13 @@ le_uint16 sizeIndex = ppem - start; le_uint16 bits = fieldBits[format]; le_uint16 count = 16 / bits; + + LEReferenceToArrayOf 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)); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/DeviceTables.h --- a/src/share/native/sun/font/layout/DeviceTables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/DeviceTables.h Sat Dec 07 16:15:08 2013 -0800 @@ -50,7 +50,7 @@ le_uint16 deltaFormat; le_uint16 deltaValues[ANY_NUMBER]; - le_int16 getAdjustment(le_uint16 ppem) const; + le_int16 getAdjustment(const LEReferenceTo &base, le_uint16 ppem, LEErrorCode &success) const; private: static const le_uint16 fieldMasks[]; diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ExtensionSubtables.cpp --- a/src/share/native/sun/font/layout/ExtensionSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ExtensionSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -48,7 +48,6 @@ const LookupProcessor *lookupProcessor, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { - if (LE_FAILURE(success)) { return 0; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ExtensionSubtables.h --- a/src/share/native/sun/font/layout/ExtensionSubtables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ExtensionSubtables.h Sat Dec 07 16:15:08 2013 -0800 @@ -52,8 +52,7 @@ le_uint16 extensionLookupType; le_uint32 extensionOffset; - le_uint32 process(const LEReferenceTo &extRef, - const LookupProcessor *lookupProcessor, le_uint16 lookupType, + le_uint32 process(const LEReferenceTo &base, const LookupProcessor *lookupProcessor, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/GDEFMarkFilter.cpp --- a/src/share/native/sun/font/layout/GDEFMarkFilter.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/GDEFMarkFilter.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -49,11 +49,11 @@ // 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 diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/GDEFMarkFilter.h --- a/src/share/native/sun/font/layout/GDEFMarkFilter.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/GDEFMarkFilter.h Sat Dec 07 16:15:08 2013 -0800 @@ -55,7 +55,7 @@ GDEFMarkFilter(const LEReferenceTo &gdefTable, LEErrorCode &success); virtual ~GDEFMarkFilter(); - virtual le_bool accept(LEGlyphID glyph) const; + virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const; }; U_NAMESPACE_END diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/GlyphIterator.cpp --- a/src/share/native/sun/font/layout/GlyphIterator.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/GlyphIterator.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -41,14 +41,13 @@ U_NAMESPACE_BEGIN GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, - FeatureMask theFeatureMask, const LEReferenceTo &theGlyphDefinitionTableHeader) + FeatureMask theFeatureMask, const LEReferenceTo &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::filterResetCache(void) { filterCacheValid = FALSE; - } +} le_bool GlyphIterator::filterGlyph(le_uint32 index) { @@ -399,53 +398,53 @@ 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; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/GlyphIterator.h --- a/src/share/native/sun/font/layout/GlyphIterator.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/GlyphIterator.h Sat Dec 07 16:15:08 2013 -0800 @@ -49,7 +49,7 @@ class GlyphIterator : public UMemory { public: GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, - FeatureMask theFeatureMask, const LEReferenceTo &theGlyphDefinitionTableHeader); + FeatureMask theFeatureMask, const LEReferenceTo &theGlyphDefinitionTableHeader, LEErrorCode &success); GlyphIterator(GlyphIterator &that); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp --- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -95,6 +95,8 @@ le_uint32 delta = 0; + //_LETRACE("attempting lookupType #%d", lookupType); + switch(lookupType) { case 0: @@ -152,21 +154,21 @@ { LEReferenceTo subtable(lookupSubtable, success); - delta = subtable->process(this, glyphIterator, fontInstance, success); + delta = subtable->process(subtable, this , glyphIterator, fontInstance, success); break; } case gpstChainedContext: { - LEReferenceTo subtable(lookupSubtable, success); + const LEReferenceTo subtable(lookupSubtable, success); - delta = subtable->process(this, glyphIterator, fontInstance, success); + delta = subtable->process(subtable, this, glyphIterator, fontInstance, success); break; } case gpstExtension: { - LEReferenceTo subtable(lookupSubtable, success); + const LEReferenceTo subtable(lookupSubtable, success); delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success); break; @@ -176,6 +178,12 @@ break; } +#if LE_TRACE + if(delta != 0) { + _LETRACE("GlyphPositioningLookupProcessor applied #%d -> delta %d @ %d", lookupType, delta, glyphIterator->getCurrStreamPosition()); + } +#endif + return delta; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp --- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -123,7 +123,7 @@ { const LEReferenceTo subtable(lookupSubtable, success); - delta = subtable->process(this, glyphIterator, fontInstance, success); + delta = subtable->process(subtable, this, glyphIterator, fontInstance, success); break; } @@ -131,7 +131,7 @@ { const LEReferenceTo subtable(lookupSubtable, success); - delta = subtable->process(this, glyphIterator, fontInstance, success); + delta = subtable->process(subtable, this, glyphIterator, fontInstance, success); break; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/IndicLayoutEngine.cpp --- a/src/share/native/sun/font/layout/IndicLayoutEngine.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/IndicLayoutEngine.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -44,7 +44,7 @@ #include "LEGlyphStorage.h" #include "IndicReordering.h" -#include + U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) @@ -53,14 +53,14 @@ le_int32 typoFlags, le_bool version2, const LEReferenceTo &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 @@ { fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); fFeatureOrder = TRUE; - fVersion2 = FALSE; + fVersion2 = FALSE; } IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine() @@ -90,6 +90,7 @@ 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 @@ } 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 @@ 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 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); } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/IndicReordering.cpp --- a/src/share/native/sun/font/layout/IndicReordering.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/IndicReordering.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -254,8 +254,8 @@ 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++ ) { diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/KernTable.cpp --- a/src/share/native/sun/font/layout/KernTable.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/KernTable.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -39,7 +39,7 @@ #include -#define DEBUG 0 +#define DEBUG_KERN_TABLE 0 U_NAMESPACE_BEGIN @@ -99,14 +99,14 @@ : 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 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 @@ 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 @@ p = tp; } -#if DEBUG +#if DEBUG_KERN_TABLE fprintf(stderr, "binary search for %0.8x\n", key); #endif @@ -251,13 +251,13 @@ 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); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LEFontInstance.h --- a/src/share/native/sun/font/layout/LEFontInstance.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LEFontInstance.h Sat Dec 07 16:15:08 2013 -0800 @@ -181,6 +181,10 @@ * * Subclasses which represent composite fonts should always return NULL. * + * 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 NULL @@ -200,6 +204,8 @@ * Subclasses which represent composite fonts should always return NULL. * * 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 @@ U_NAMESPACE_END #endif - - diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LEGlyphFilter.h --- a/src/share/native/sun/font/layout/LEGlyphFilter.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LEGlyphFilter.h Sat Dec 07 16:15:08 2013 -0800 @@ -62,7 +62,7 @@ * * @internal */ - virtual le_bool accept(LEGlyphID glyph) const = 0; + virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const = 0; }; #endif /* U_HIDE_INTERNAL_API */ diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LEGlyphStorage.cpp --- a/src/share/native/sun/font/layout/LEGlyphStorage.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LEGlyphStorage.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -458,7 +458,7 @@ 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 @@ // the source glyph we're pointing at // just got replaced by the insertion - fSrcIndex -= 1; + fSrcIndex -= 1; return FALSE; } U_NAMESPACE_END - diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LEGlyphStorage.h --- a/src/share/native/sun/font/layout/LEGlyphStorage.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LEGlyphStorage.h Sat Dec 07 16:15:08 2013 -0800 @@ -568,4 +568,3 @@ U_NAMESPACE_END #endif - diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LEScripts.h --- a/src/share/native/sun/font/layout/LEScripts.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LEScripts.h Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ khojScriptCode = 157, tirhScriptCode = 158, - scriptCodeCount = 159 +/** + * @stable ICU 52 + */ + aghbScriptCode = 159, + mahjScriptCode = 160, + +/** + * @stable ICU 2.2 + */ + scriptCodeCount }; U_NAMESPACE_END diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LEStandalone.h --- a/src/share/native/sun/font/layout/LEStandalone.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LEStandalone.h Sat Dec 07 16:15:08 2013 -0800 @@ -132,6 +132,9 @@ #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 diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LETableReference.h --- a/src/share/native/sun/font/layout/LETableReference.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LETableReference.h Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ */ 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 @@ 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 @@ 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 @@ } 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 @@ 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,97 +323,6 @@ * Open a new entry based on an existing table */ -/** - * \def LE_UNBOUNDED_ARRAY - * define an array with no *known* bound. Will trim to available size. - * @internal - */ -#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX - -template -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") - if(LE_SUCCESS(success)) { - if(count == LE_UNBOUNDED_ARRAY) { // not a known length - count = getLength()/LETableVarSizer::getSize(); // fit to max size - } - LETableReference::verifyLength(0, LETableVarSizer::getSize()*count, success); - } - if(LE_FAILURE(success)) { - fCount=0; - clear(); - } - } - - 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") - if(LE_SUCCESS(success)) { - if(count == LE_UNBOUNDED_ARRAY) { // not a known length - count = getLength()/LETableVarSizer::getSize(); // fit to max size - } - LETableReference::verifyLength(0, LETableVarSizer::getSize()*count, 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") - if(LE_SUCCESS(success)) { - if(count == LE_UNBOUNDED_ARRAY) { // not a known length - count = getLength()/LETableVarSizer::getSize(); // fit to max size - } - LETableReference::verifyLength(0, LETableVarSizer::getSize()*count, success); - } - if(LE_FAILURE(success)) clear(); - } - - LEReferenceToArrayOf() :LETableReference(), fCount(0) {} - - le_uint32 getCount() const { return fCount; } - - using LETableReference::getAlias; - - 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; } - - const T& getObject(le_uint32 i, LEErrorCode &success) const { - return *getAlias(i,success); - } - - const T& operator()(le_uint32 i, LEErrorCode &success) const { - return *getAlias(i,success); - } - - size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const { - if(LE_SUCCESS(success)&&i::getSize()*i; - } else { - success = LE_INDEX_OUT_OF_BOUNDS_ERROR; - } - return 0; - } - - LEReferenceToArrayOf &reparent(const LETableReference &base) { - fParent = &base; - return *this; - } - - LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) { - LE_TRACE_TR("INFO: null RTAO") - } - -private: - le_uint32 fCount; -}; - - template class LEReferenceTo : public LETableReference { public: @@ -404,14 +360,26 @@ verifyLength(0, LETableVarSizer::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) {} - inline LEReferenceTo() : LETableReference(NULL) {} +#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& operator=(const T* other) { setRaw(other); return *this; } +#endif + + LEReferenceTo& setTo(LETableReference::EStaticData staticData, const T* other, size_t length) { + LETableReference::setTo(staticData, other, length); + return *this; + } LEReferenceTo &reparent(const LETableReference &base) { fParent = &base; @@ -430,11 +398,135 @@ } const T *operator->() const { return getAlias(); } + 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; } +#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. + * @internal + */ +#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX + +template +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) { + _TRTRACE("INFO: new RTAO by offset") + if(LE_SUCCESS(success)) { + if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length + fCount = getLength()/LETableVarSizer::getSize(); // fit to max size + } + LETableReference::verifyLength(0, LETableVarSizer::getSize()*fCount, success); + } + if(LE_FAILURE(success)) { + fCount=0; + clear(); + } + } + + LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count) + : LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) { +_TRTRACE("INFO: new RTAO") + if(LE_SUCCESS(success)) { + if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length + fCount = getLength()/LETableVarSizer::getSize(); // fit to max size + } + LETableReference::verifyLength(0, LETableVarSizer::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) { +_TRTRACE("INFO: new RTAO") + if(LE_SUCCESS(success)) { + if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length + fCount = getLength()/LETableVarSizer::getSize(); // fit to max size + } + LETableReference::verifyLength(0, LETableVarSizer::getSize()*fCount, success); + } + if(LE_FAILURE(success)) clear(); + } + + LEReferenceToArrayOf() :LETableReference(), fCount(0) {} + + le_uint32 getCount() const { return fCount; } + + 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))); + } + +#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 getReference(le_uint32 i, LEErrorCode &success) const { + if(LE_FAILURE(success)) return LEReferenceTo(); + return LEReferenceTo(*this, success, getAlias(i,success)); + } + + const T& operator()(le_uint32 i, LEErrorCode &success) const { + return *getAlias(i,success); + } + + size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const { + if(LE_SUCCESS(success)&&i::getSize()*i; + } else { + LE_DEBUG_TR3("getOffsetFor failed (%p) index=%d",NULL, i); + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + } + return 0; + } + + LEReferenceToArrayOf &reparent(const LETableReference &base) { + fParent = &base; + return *this; + } + + LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) { + _TRTRACE("INFO: null RTAO") + } + +private: + le_uint32 fCount; +}; + + + + +#ifdef _TRTRACE +#undef _TRTRACE +#endif + U_NAMESPACE_END #endif diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LETypes.h --- a/src/share/native/sun/font/layout/LETypes.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LETypes.h Sat Dec 07 16:15:08 2013 -0800 @@ -337,6 +337,20 @@ typedef struct LEPoint LEPoint; #endif +/** + * \def LE_TRACE + * @internal + */ +#ifndef LE_TRACE +# define LE_TRACE 0 +#endif + +#if LE_TRACE +# include +# define _LETRACE printf("\n%s:%d: LE: ", __FILE__, __LINE__),printf +#else +# define _LETRACE 0&& +#endif #ifndef U_HIDE_INTERNAL_API @@ -553,7 +567,7 @@ 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 @@ 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 @@ #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 @@ * * @stable ICU 2.4 */ -#ifndef LE_FAILURE +#ifndef LE_SUCCESS #define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code)) #endif @@ -781,4 +804,4 @@ #define LE_FAILURE(code) (U_FAILURE((UErrorCode)code)) #endif -#endif /* __LETYPES_H */ +#endif diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LayoutEngine.cpp --- a/src/share/native/sun/font/layout/LayoutEngine.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LayoutEngine.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -156,7 +156,7 @@ CanonMarkFilter(const LEReferenceTo &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 &gdefTable, LEErrorCode &success) @@ -169,9 +169,8 @@ // 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 @@ fGlyphStorage = new LEGlyphStorage(); if (fGlyphStorage == NULL) { success = LE_MEMORY_ALLOCATION_ERROR; -} + } } le_int32 LayoutEngine::getGlyphCount() const @@ -263,7 +262,9 @@ return count; } - LEReferenceTo canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable); + LEReferenceTo 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 @@ CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage); inChars = reordered; - } + } fakeGlyphStorage.allocateAuxData(success); @@ -323,7 +324,8 @@ LE_DELETE_ARRAY(reordered); } - outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); + const LEReferenceTo 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 @@ 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 @@ return; } - LEReferenceTo gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, + LEReferenceTo gdefTable(LETableReference::kStaticData, (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); CanonMarkFilter filter(gdefTable, success); @@ -464,9 +469,10 @@ 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 @@ 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 @@ break; } } else { - MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag); - if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) { + LEReferenceTo 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 mortTable(fontInstance, mortTableTag, success); @@ -686,21 +698,20 @@ 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 @@ } if (result && LE_FAILURE(success)) { - delete result; - result = NULL; - } + delete result; + result = NULL; + } if (result == NULL) { success = LE_MEMORY_ALLOCATION_ERROR; diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LayoutEngine.h --- a/src/share/native/sun/font/layout/LayoutEngine.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LayoutEngine.h Sat Dec 07 16:15:08 2013 -0800 @@ -156,8 +156,8 @@ * @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 diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LigatureSubstProc2.cpp --- a/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -105,7 +105,7 @@ LEReferenceToArrayOf 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 { diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LigatureSubstSubtables.cpp --- a/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -49,14 +49,20 @@ return 0; } - if (coverageIndex >= 0) { + LEReferenceToArrayOf 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 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 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 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 @@ } } - 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; diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/LookupProcessor.cpp --- a/src/share/native/sun/font/layout/LookupProcessor.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/LookupProcessor.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -60,9 +60,11 @@ LEReferenceTo 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 @@ } 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 @@ FeatureMask selectMask = lookupSelectArray[lookup]; if (selectMask != 0) { + _LETRACE("Processing order#%d/%d", order, lookupOrderCount); const LEReferenceTo lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success); if (!lookupTable.isValid() ||LE_FAILURE(success) ) { continue; @@ -103,8 +106,11 @@ 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_int32 LookupProcessor::selectLookups(const LEReferenceTo &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 lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount); @@ -147,6 +153,9 @@ if (lookupListIndex >= lookupSelectCount) { continue; } + if (store >= lookupOrderCount) { + continue; + } lookupSelectArray[lookupListIndex] |= featureMask; lookupOrderArray[store++] = lookupListIndex; @@ -246,7 +255,7 @@ 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 @@ success = LE_MEMORY_ALLOCATION_ERROR; return; } + lookupOrderCount = featureReferences; for (le_int32 f = 0; f < featureMapCount; f += 1) { FeatureMap fm = featureMap[f]; diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/Lookups.cpp --- a/src/share/native/sun/font/layout/Lookups.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/Lookups.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -65,7 +65,7 @@ if(LE_FAILURE(success)) return 0; - return coverageTable->getGlyphCoverage(glyphID); + return coverageTable->getGlyphCoverage(coverageTable, glyphID, success); } U_NAMESPACE_END diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/MarkArrays.cpp --- a/src/share/native/sun/font/layout/MarkArrays.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/MarkArrays.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -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 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(base, success, anchorTableOffset); - anchorTable->getAnchor(glyphID, fontInstance, anchor); + if(LE_FAILURE(success)) { + return markClass; + } + + anchorTable->getAnchor(anchorTable, glyphID, fontInstance, anchor, success); markClass = SWAPW(markRecord->markClass); } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/MarkArrays.h --- a/src/share/native/sun/font/layout/MarkArrays.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/MarkArrays.h Sat Dec 07 16:15:08 2013 -0800 @@ -54,8 +54,9 @@ 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) diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp --- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -66,11 +66,11 @@ } LEPoint markAnchor; - const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); - le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); + LEReferenceTo 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 @@ 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(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 @@ // table is mal-formed... return 0; } + LEReferenceTo baseRecord(base, success, &baseArray->baseRecordArray[baseCoverage * mcCount]); + if( LE_FAILURE(success) ) { return 0; } + LEReferenceToArrayOf 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(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 @@ 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 @@ gi.next(); } // end of JK patch - fontInstance->pixelsToUnits(pixels, baseAdvance); glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp --- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -65,8 +65,11 @@ } LEPoint markAnchor; - const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); - le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); + LEReferenceTo 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 @@ 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(base, success, SWAPW(baseArrayOffset)); le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount); if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) { @@ -91,7 +94,7 @@ le_int32 markPosition = glyphIterator->getCurrStreamPosition(); Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]); - const LigatureAttachTable *ligatureAttachTable = (const LigatureAttachTable *) ((char *) ligatureArray + ligatureAttachOffset); + LEReferenceTo ligatureAttachTable(ligatureArray, success, ligatureAttachOffset); le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount); le_int32 component = ligatureIterator.getMarkComponent(markPosition); @@ -100,12 +103,14 @@ component = componentCount - 1; } - const ComponentRecord *componentRecord = &ligatureAttachTable->componentRecordArray[component * mcCount]; + LEReferenceTo componentRecord(base, success, &ligatureAttachTable->componentRecordArray[component * mcCount]); + LEReferenceToArrayOf 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(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); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp --- a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -66,8 +66,11 @@ } LEPoint markAnchor; - const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); - le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); + LEReferenceTo 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 @@ 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(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 @@ return 0; } - const Mark2Record *mark2Record = &mark2Array->mark2RecordArray[mark2Coverage * mcCount]; + LEReferenceTo 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(mark2Array, success, anchorTableOffset); + if(LE_FAILURE(success)) return 0; LEPoint mark2Anchor, markAdvance, pixels; if (anchorTableOffset == 0) { @@ -99,7 +105,7 @@ 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 @@ 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()) { diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/MultipleSubstSubtables.cpp --- a/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -54,9 +54,10 @@ // 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 @@ if (coverageIndex >= 0 && coverageIndex < seqCount) { Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); - const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset); + LEReferenceTo sequenceTable(base, success, sequenceTableOffset); le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount); if (glyphCount == 0) { @@ -76,7 +77,7 @@ } 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 @@ 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; } } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp --- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -470,6 +470,7 @@ 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 @@ 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 @@ 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); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/OpenTypeUtilities.h --- a/src/share/native/sun/font/layout/OpenTypeUtilities.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/OpenTypeUtilities.h Sat Dec 07 16:15:08 2013 -0800 @@ -46,15 +46,14 @@ public: static le_int8 highBit(le_int32 value); static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf &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 recordRef(recordRef0, success, (size_t)0, recordCount); return getGlyphRangeIndex(glyphID, recordRef, success); } +#endif static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf &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); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/PairPositioningSubtables.cpp --- a/src/share/native/sun/font/layout/PairPositioningSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/PairPositioningSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -76,19 +76,17 @@ { 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 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(base, success, ((char *) this + pairSetTableOffset)); - if (LE_FAILURE(success)) { - return 0; - } + LEReferenceTo pairSetTable(base, success, pairSetTableOffset); + if( LE_FAILURE(success) ) return 0; le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount); + LEReferenceTo 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 @@ LEReferenceTo 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 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 @@ 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 classDef1(base, success, SWAPW(classDef1Offset)); + const LEReferenceTo 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)); - + const LEReferenceTo class1Record(base, success, (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1))); + const LEReferenceTo class2Record(base, success, (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); + if( LE_SUCCESS(success) ) { + if (valueFormat1 != 0) { + class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success); + } + if (valueFormat2 != 0) { + const LEReferenceTo valueRecord2(base, success, ((char *) &class2Record->valueRecord1) + valueRecord1Size); + LEReferenceTo 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 @@ return 0; } -LEReferenceTo PairPositioningFormat1Subtable::findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const +LEReferenceTo +PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, LEReferenceTo& 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 record(base, success, records); - record.verifyLength(0, recordSize, success); + LEReferenceTo 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(); + if (SWAPW(record->secondGlyph) == glyphID) { + return record; + } - record = LEReferenceTo(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 @@ } #endif - return (const PairValueRecord*)NULL; + return LEReferenceTo(); } U_NAMESPACE_END diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/PairPositioningSubtables.h --- a/src/share/native/sun/font/layout/PairPositioningSubtables.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/PairPositioningSubtables.h Sat Dec 07 16:15:08 2013 -0800 @@ -77,9 +77,8 @@ le_uint32 process(const LEReferenceTo &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; private: - LEReferenceTo findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, + LEReferenceTo findPairValueRecord(TTGlyphID glyphID, LEReferenceTo &records, le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const; - }; LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray) diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ScriptAndLanguage.cpp --- a/src/share/native/sun/font/layout/ScriptAndLanguage.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ScriptAndLanguage.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -106,7 +106,8 @@ } } else { LEReferenceToArrayOf scriptRecordArrayRef(base, success, &scriptRecordArray[0], count); - scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO + + scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); } if (scriptTableOffset != 0) { diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp --- a/src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -126,13 +126,13 @@ 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 @@ 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 @@ 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) */ diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ScriptAndLanguageTags.h --- a/src/share/native/sun/font/layout/ScriptAndLanguageTags.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ScriptAndLanguageTags.h Sat Dec 07 16:15:08 2013 -0800 @@ -140,13 +140,13 @@ 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 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 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) */ diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp --- a/src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -65,17 +65,18 @@ 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 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); } } } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/SinglePositioningSubtables.cpp --- a/src/share/native/sun/font/layout/SinglePositioningSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/SinglePositioningSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -75,7 +75,7 @@ } 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 @@ } 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; } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp --- a/src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -76,7 +76,7 @@ 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 @@ 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); } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/TibetanReordering.h --- a/src/share/native/sun/font/layout/TibetanReordering.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/TibetanReordering.h Sat Dec 07 16:15:08 2013 -0800 @@ -39,7 +39,7 @@ */ #ifndef __TIBETANREORDERING_H -#define __TIBETANORDERING_H +#define __TIBETANREORDERING_H /** * \file diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ValueRecords.cpp --- a/src/share/native/sun/font/layout/ValueRecords.cpp Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ValueRecords.cpp Sat Dec 07 16:15:08 2013 -0800 @@ -59,8 +59,8 @@ 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 @@ Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 xAdj = dt->getAdjustment(xppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 xAdj = dt->getAdjustment(dt, xppem, success); xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj); } @@ -129,8 +129,8 @@ Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 yAdj = dt->getAdjustment(yppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 yAdj = dt->getAdjustment(dt, yppem, success); yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj); } @@ -140,8 +140,8 @@ Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 xAdj = dt->getAdjustment(xppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 xAdj = dt->getAdjustment(dt, xppem, success); xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj); } @@ -151,10 +151,10 @@ Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 yAdj = dt->getAdjustment(yppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 yAdj = dt->getAdjustment(dt, yppem, success); - yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); + yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); } } } @@ -163,8 +163,8 @@ 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 @@ Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 xAdj = dt->getAdjustment(xppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 xAdj = dt->getAdjustment(dt, xppem, success); xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj); } @@ -233,8 +233,8 @@ Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 yAdj = dt->getAdjustment(yppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 yAdj = dt->getAdjustment(dt, yppem, success); yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj); } @@ -244,8 +244,8 @@ Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 xAdj = dt->getAdjustment(xppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 xAdj = dt->getAdjustment(dt, xppem, success); xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj); } @@ -255,8 +255,8 @@ Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice); if (dtOffset != 0) { - const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); - le_int16 yAdj = dt->getAdjustment(yppem); + LEReferenceTo dt(base, success, dtOffset); + le_int16 yAdj = dt->getAdjustment(dt, yppem, success); yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); } diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/font/layout/ValueRecords.h --- a/src/share/native/sun/font/layout/ValueRecords.h Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/font/layout/ValueRecords.h Sat Dec 07 16:15:08 2013 -0800 @@ -53,10 +53,10 @@ 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); diff -r 92ce9338bec4 -r d92379723173 src/share/native/sun/java2d/cmm/lcms/cmsintrp.c --- a/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Wed Dec 04 23:11:27 2013 -0800 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Sat Dec 07 16:15:08 2013 -0800 @@ -215,6 +215,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; diff -r 92ce9338bec4 -r d92379723173 src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c --- a/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Wed Dec 04 23:11:27 2013 -0800 +++ b/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Sat Dec 07 16:15:08 2013 -0800 @@ -577,8 +577,8 @@ 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); diff -r 92ce9338bec4 -r d92379723173 test/java/lang/SecurityManager/CheckPackageAccess.java --- a/test/java/lang/SecurityManager/CheckPackageAccess.java Wed Dec 04 23:11:27 2013 -0800 +++ b/test/java/lang/SecurityManager/CheckPackageAccess.java Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ "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.", diff -r 92ce9338bec4 -r d92379723173 test/sun/security/tools/jarsigner/TimestampCheck.java --- a/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Dec 04 23:11:27 2013 -0800 +++ b/test/sun/security/tools/jarsigner/TimestampCheck.java Sat Dec 07 16:15:08 2013 -0800 @@ -239,13 +239,13 @@ " -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 @@ 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 @@ 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"); + } } } diff -r 92ce9338bec4 -r d92379723173 test/sun/security/tools/jarsigner/concise_jarsigner.sh --- a/test/sun/security/tools/jarsigner/concise_jarsigner.sh Wed Dec 04 23:11:27 2013 -0800 +++ b/test/sun/security/tools/jarsigner/concise_jarsigner.sh Sat Dec 07 16:15:08 2013 -0800 @@ -139,7 +139,6 @@ # 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 -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 diff -r 92ce9338bec4 -r d92379723173 test/sun/security/tools/jarsigner/ts.sh --- a/test/sun/security/tools/jarsigner/ts.sh Wed Dec 04 23:11:27 2013 -0800 +++ b/test/sun/security/tools/jarsigner/ts.sh Sat Dec 07 16:15:08 2013 -0800 @@ -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 @@ 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 diff -r 92ce9338bec4 -r d92379723173 test/sun/security/tools/jarsigner/warnings.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/tools/jarsigner/warnings.sh Sat Dec 07 16:15:08 2013 -0800 @@ -0,0 +1,119 @@ +# +# 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 + +