# HG changeset patch # User duke # Date 1499277883 -7200 # Node ID 98b357b2e8a6aa782f75eb1be27f69d851cca817 # Parent d1480cb4928339808b9644435392c2e3c3dc1fe7# Parent 64a78dd937667dc1cf7fec98e6c1aba2a154c404 Merge diff -r d1480cb49283 -r 98b357b2e8a6 .hgtags-top-repo --- a/.hgtags-top-repo Thu Oct 16 14:55:17 2014 -0700 +++ b/.hgtags-top-repo Wed Jul 05 20:04:43 2017 +0200 @@ -277,3 +277,4 @@ 7e3512dae8e020d44399c0f1c579ff1fe3090ed6 jdk9-b32 e4ba01b726e263953ae129be37c94de6ed145b1d jdk9-b33 087b23f35631e68e950496a36fce8ccca612966a jdk9-b34 +c173ba994245380fb11ef077d1e59823386840eb jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 corba/.hgtags --- a/corba/.hgtags Thu Oct 16 14:55:17 2014 -0700 +++ b/corba/.hgtags Wed Jul 05 20:04:43 2017 +0200 @@ -277,3 +277,4 @@ b5b139354630edb2d06190bf31653acbdcea63a8 jdk9-b32 cfdac5887952c2dd73c73a1d8d9aa880d0539bbf jdk9-b33 24a0bad5910f775bb4002d1dacf8b3af87c63cd8 jdk9-b34 +9bc2dbd3dfb8c9fa88e00056b8b93a81ee6d306e jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/.hgtags --- a/hotspot/.hgtags Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/.hgtags Wed Jul 05 20:04:43 2017 +0200 @@ -437,3 +437,4 @@ af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32 9b3f5e4f33725f7c1d9b8e523133fe8383a54d9f jdk9-b33 821164b0131a47ca065697c7d27d8f215e608c8d jdk9-b34 +438cb613151c4bd290bb732697517cba1cafcb04 jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/aix/makefiles/fastdebug.make --- a/hotspot/make/aix/makefiles/fastdebug.make Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/aix/makefiles/fastdebug.make Wed Jul 05 20:04:43 2017 +0200 @@ -67,7 +67,6 @@ # not justified. LFLAGS_QIPA= -G_SUFFIX = _g VERSION = optimized SYSDEFS += -DASSERT -DFASTDEBUG PICFLAGS = DEFAULT diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/aix/makefiles/mapfile-vers-debug --- a/hotspot/make/aix/makefiles/mapfile-vers-debug Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/aix/makefiles/mapfile-vers-product --- a/hotspot/make/aix/makefiles/mapfile-vers-product Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/aix/makefiles/mapfile-vers-product Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Wed Jul 05 20:04:43 2017 +0200 @@ -82,6 +82,7 @@ _JVM_EnableCompiler _JVM_Exit _JVM_FillInStackTrace + _JVM_FindClassFromCaller _JVM_FindClassFromClass _JVM_FindClassFromClassLoader _JVM_FindClassFromBootLoader @@ -115,7 +116,6 @@ _JVM_GetClassDeclaredMethods _JVM_GetClassFieldsCount _JVM_GetClassInterfaces - _JVM_GetClassLoader _JVM_GetClassMethodsCount _JVM_GetClassModifiers _JVM_GetClassName diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/bsd/makefiles/mapfile-vers-darwin-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Wed Jul 05 20:04:43 2017 +0200 @@ -82,6 +82,7 @@ _JVM_EnableCompiler _JVM_Exit _JVM_FillInStackTrace + _JVM_FindClassFromCaller _JVM_FindClassFromClass _JVM_FindClassFromClassLoader _JVM_FindClassFromBootLoader @@ -115,7 +116,6 @@ _JVM_GetClassDeclaredMethods _JVM_GetClassFieldsCount _JVM_GetClassInterfaces - _JVM_GetClassLoader _JVM_GetClassMethodsCount _JVM_GetClassModifiers _JVM_GetClassName diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/bsd/makefiles/mapfile-vers-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/bsd/makefiles/mapfile-vers-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/linux/makefiles/mapfile-vers-debug --- a/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/linux/makefiles/mapfile-vers-product --- a/hotspot/make/linux/makefiles/mapfile-vers-product Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/make/solaris/makefiles/mapfile-vers --- a/hotspot/make/solaris/makefiles/mapfile-vers Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/make/solaris/makefiles/mapfile-vers Wed Jul 05 20:04:43 2017 +0200 @@ -84,6 +84,7 @@ JVM_EnableCompiler; JVM_Exit; JVM_FillInStackTrace; + JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; @@ -117,7 +118,6 @@ JVM_GetClassDeclaredMethods; JVM_GetClassFieldsCount; JVM_GetClassInterfaces; - JVM_GetClassLoader; JVM_GetClassMethodsCount; JVM_GetClassModifiers; JVM_GetClassName; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/assembler_ppc.hpp --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -268,8 +268,35 @@ ISEL_OPCODE = (31u << OPCODE_SHIFT | 15u << 1), - MTLR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 8 << SPR_0_4_SHIFT), - MFLR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 8 << SPR_0_4_SHIFT), + // Special purpose registers + MTSPR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1), + MFSPR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1), + + MTXER_OPCODE = (MTSPR_OPCODE | 1 << SPR_0_4_SHIFT), + MFXER_OPCODE = (MFSPR_OPCODE | 1 << SPR_0_4_SHIFT), + + MTDSCR_OPCODE = (MTSPR_OPCODE | 3 << SPR_0_4_SHIFT), + MFDSCR_OPCODE = (MFSPR_OPCODE | 3 << SPR_0_4_SHIFT), + + MTLR_OPCODE = (MTSPR_OPCODE | 8 << SPR_0_4_SHIFT), + MFLR_OPCODE = (MFSPR_OPCODE | 8 << SPR_0_4_SHIFT), + + MTCTR_OPCODE = (MTSPR_OPCODE | 9 << SPR_0_4_SHIFT), + MFCTR_OPCODE = (MFSPR_OPCODE | 9 << SPR_0_4_SHIFT), + + MTTFHAR_OPCODE = (MTSPR_OPCODE | 128 << SPR_0_4_SHIFT), + MFTFHAR_OPCODE = (MFSPR_OPCODE | 128 << SPR_0_4_SHIFT), + MTTFIAR_OPCODE = (MTSPR_OPCODE | 129 << SPR_0_4_SHIFT), + MFTFIAR_OPCODE = (MFSPR_OPCODE | 129 << SPR_0_4_SHIFT), + MTTEXASR_OPCODE = (MTSPR_OPCODE | 130 << SPR_0_4_SHIFT), + MFTEXASR_OPCODE = (MFSPR_OPCODE | 130 << SPR_0_4_SHIFT), + MTTEXASRU_OPCODE = (MTSPR_OPCODE | 131 << SPR_0_4_SHIFT), + MFTEXASRU_OPCODE = (MFSPR_OPCODE | 131 << SPR_0_4_SHIFT), + + MTVRSAVE_OPCODE = (MTSPR_OPCODE | 256 << SPR_0_4_SHIFT), + MFVRSAVE_OPCODE = (MFSPR_OPCODE | 256 << SPR_0_4_SHIFT), + + MFTB_OPCODE = (MFSPR_OPCODE | 268 << SPR_0_4_SHIFT), MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1), MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1), @@ -291,9 +318,6 @@ // CTR-related opcodes BCCTR_OPCODE = (19u << OPCODE_SHIFT | 528u << 1), - MTCTR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 9 << SPR_0_4_SHIFT), - MFCTR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 9 << SPR_0_4_SHIFT), - LWZ_OPCODE = (32u << OPCODE_SHIFT), LWZX_OPCODE = (31u << OPCODE_SHIFT | 23u << 1), @@ -585,6 +609,37 @@ MTVSCR_OPCODE = (4u << OPCODE_SHIFT | 1604u ), MFVSCR_OPCODE = (4u << OPCODE_SHIFT | 1540u ), + // AES (introduced with Power 8) + VCIPHER_OPCODE = (4u << OPCODE_SHIFT | 1288u), + VCIPHERLAST_OPCODE = (4u << OPCODE_SHIFT | 1289u), + VNCIPHER_OPCODE = (4u << OPCODE_SHIFT | 1352u), + VNCIPHERLAST_OPCODE = (4u << OPCODE_SHIFT | 1353u), + VSBOX_OPCODE = (4u << OPCODE_SHIFT | 1480u), + + // SHA (introduced with Power 8) + VSHASIGMAD_OPCODE = (4u << OPCODE_SHIFT | 1730u), + VSHASIGMAW_OPCODE = (4u << OPCODE_SHIFT | 1666u), + + // Vector Binary Polynomial Multiplication (introduced with Power 8) + VPMSUMB_OPCODE = (4u << OPCODE_SHIFT | 1032u), + VPMSUMD_OPCODE = (4u << OPCODE_SHIFT | 1224u), + VPMSUMH_OPCODE = (4u << OPCODE_SHIFT | 1096u), + VPMSUMW_OPCODE = (4u << OPCODE_SHIFT | 1160u), + + // Vector Permute and Xor (introduced with Power 8) + VPERMXOR_OPCODE = (4u << OPCODE_SHIFT | 45u), + + // Transactional Memory instructions (introduced with Power 8) + TBEGIN_OPCODE = (31u << OPCODE_SHIFT | 654u << 1), + TEND_OPCODE = (31u << OPCODE_SHIFT | 686u << 1), + TABORT_OPCODE = (31u << OPCODE_SHIFT | 910u << 1), + TABORTWC_OPCODE = (31u << OPCODE_SHIFT | 782u << 1), + TABORTWCI_OPCODE = (31u << OPCODE_SHIFT | 846u << 1), + TABORTDC_OPCODE = (31u << OPCODE_SHIFT | 814u << 1), + TABORTDCI_OPCODE = (31u << OPCODE_SHIFT | 878u << 1), + TSR_OPCODE = (31u << OPCODE_SHIFT | 750u << 1), + TCHECK_OPCODE = (31u << OPCODE_SHIFT | 718u << 1), + // Icache and dcache related instructions DCBA_OPCODE = (31u << OPCODE_SHIFT | 758u << 1), DCBZ_OPCODE = (31u << OPCODE_SHIFT | 1014u << 1), @@ -1420,6 +1475,25 @@ inline void mcrf( ConditionRegister crd, ConditionRegister cra); inline void mtcr( Register s); + // Special purpose registers + // Exception Register + inline void mtxer(Register s1); + inline void mfxer(Register d); + // Vector Register Save Register + inline void mtvrsave(Register s1); + inline void mfvrsave(Register d); + // Timebase + inline void mftb(Register d); + // Introduced with Power 8: + // Data Stream Control Register + inline void mtdscr(Register s1); + inline void mfdscr(Register d ); + // Transactional Memory Registers + inline void mftfhar(Register d); + inline void mftfiar(Register d); + inline void mftexasr(Register d); + inline void mftexasru(Register d); + // PPC 1, section 2.4.1 Branch Instructions inline void b( address a, relocInfo::relocType rt = relocInfo::none); inline void b( Label& L); @@ -1860,6 +1934,39 @@ inline void mtvscr( VectorRegister b); inline void mfvscr( VectorRegister d); + // AES (introduced with Power 8) + inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vncipher( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vncipherlast(VectorRegister d, VectorRegister a, VectorRegister b); + inline void vsbox( VectorRegister d, VectorRegister a); + + // SHA (introduced with Power 8) + // Not yet implemented. + + // Vector Binary Polynomial Multiplication (introduced with Power 8) + inline void vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vpmsumd( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vpmsumh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b); + + // Vector Permute and Xor (introduced with Power 8) + inline void vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); + + // Transactional Memory instructions (introduced with Power 8) + inline void tbegin_(); // R=0 + inline void tbeginrot_(); // R=1 Rollback-Only Transaction + inline void tend_(); // A=0 + inline void tendall_(); // A=1 + inline void tabort_(Register a); + inline void tabortwc_(int t, Register a, Register b); + inline void tabortwci_(int t, Register a, int si); + inline void tabortdc_(int t, Register a, Register b); + inline void tabortdci_(int t, Register a, int si); + inline void tsuspend_(); // tsr with L=0 + inline void tresume_(); // tsr with L=1 + inline void tcheck(int f); + // The following encoders use r0 as second operand. These instructions // read r0 as '0'. inline void lwzx( Register d, Register s2); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -312,6 +312,25 @@ { emit_int32(MCRF_OPCODE | bf(crd) | bfa(cra)); } inline void Assembler::mtcr( Register s) { Assembler::mtcrf(0xff, s); } +// Special purpose registers +// Exception Register +inline void Assembler::mtxer(Register s1) { emit_int32(MTXER_OPCODE | rs(s1)); } +inline void Assembler::mfxer(Register d ) { emit_int32(MFXER_OPCODE | rt(d)); } +// Vector Register Save Register +inline void Assembler::mtvrsave(Register s1) { emit_int32(MTVRSAVE_OPCODE | rs(s1)); } +inline void Assembler::mfvrsave(Register d ) { emit_int32(MFVRSAVE_OPCODE | rt(d)); } +// Timebase +inline void Assembler::mftb(Register d ) { emit_int32(MFTB_OPCODE | rt(d)); } +// Introduced with Power 8: +// Data Stream Control Register +inline void Assembler::mtdscr(Register s1) { emit_int32(MTDSCR_OPCODE | rs(s1)); } +inline void Assembler::mfdscr(Register d ) { emit_int32(MFDSCR_OPCODE | rt(d)); } +// Transactional Memory Registers +inline void Assembler::mftfhar(Register d ) { emit_int32(MFTFHAR_OPCODE | rt(d)); } +inline void Assembler::mftfiar(Register d ) { emit_int32(MFTFIAR_OPCODE | rt(d)); } +inline void Assembler::mftexasr(Register d ) { emit_int32(MFTEXASR_OPCODE | rt(d)); } +inline void Assembler::mftexasru(Register d ) { emit_int32(MFTEXASRU_OPCODE | rt(d)); } + // SAP JVM 2006-02-13 PPC branch instruction. // PPC 1, section 2.4.1 Branch Instructions inline void Assembler::b( address a, relocInfo::relocType rt) { emit_data(BXX_OPCODE| li(disp( intptr_t(a), intptr_t(pc()))) |aa(0)|lk(0), rt); } @@ -735,6 +754,39 @@ inline void Assembler::mtvscr( VectorRegister b) { emit_int32( MTVSCR_OPCODE | vrb(b)); } inline void Assembler::mfvscr( VectorRegister d) { emit_int32( MFVSCR_OPCODE | vrt(d)); } +// AES (introduced with Power 8) +inline void Assembler::vcipher( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCIPHER_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCIPHERLAST_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vncipher( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNCIPHER_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vncipherlast(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNCIPHERLAST_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vsbox( VectorRegister d, VectorRegister a) { emit_int32( VSBOX_OPCODE | vrt(d) | vra(a) ); } + +// SHA (introduced with Power 8) +// Not yet implemented. + +// Vector Binary Polynomial Multiplication (introduced with Power 8) +inline void Assembler::vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMB_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vpmsumd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMD_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vpmsumh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b)); } + +// Vector Permute and Xor (introduced with Power 8) +inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); } + +// Transactional Memory instructions (introduced with Power 8) +inline void Assembler::tbegin_() { emit_int32( TBEGIN_OPCODE | rc(1)); } +inline void Assembler::tbeginrot_() { emit_int32( TBEGIN_OPCODE | /*R=1*/ 1u << (31-10) | rc(1)); } +inline void Assembler::tend_() { emit_int32( TEND_OPCODE | rc(1)); } +inline void Assembler::tendall_() { emit_int32( TEND_OPCODE | /*A=1*/ 1u << (31-6) | rc(1)); } +inline void Assembler::tabort_(Register a) { emit_int32( TABORT_OPCODE | ra(a) | rc(1)); } +inline void Assembler::tabortwc_(int t, Register a, Register b) { emit_int32( TABORTWC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); } +inline void Assembler::tabortwci_(int t, Register a, int si) { emit_int32( TABORTWCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); } +inline void Assembler::tabortdc_(int t, Register a, Register b) { emit_int32( TABORTDC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); } +inline void Assembler::tabortdci_(int t, Register a, int si) { emit_int32( TABORTDCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); } +inline void Assembler::tsuspend_() { emit_int32( TSR_OPCODE | rc(1)); } +inline void Assembler::tresume_() { emit_int32( TSR_OPCODE | /*L=1*/ 1u << (31-10) | rc(1)); } +inline void Assembler::tcheck(int f) { emit_int32( TCHECK_OPCODE | bf(f)); } + // ra0 version inline void Assembler::lwzx( Register d, Register s2) { emit_int32( LWZX_OPCODE | rt(d) | rb(s2));} inline void Assembler::lwz( Register d, int si16 ) { emit_int32( LWZ_OPCODE | rt(d) | d1(si16));} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp --- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -37,6 +37,8 @@ // signatures accordingly. const bool CCallingConventionRequiresIntsAsLongs = true; +#define SUPPORTS_NATIVE_CX8 + // The PPC CPUs are NOT multiple-copy-atomic. #define CPU_NOT_MULTIPLE_COPY_ATOMIC diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -25,7 +25,6 @@ #include "precompiled.hpp" -#include "asm/assembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "interp_masm_ppc_64.hpp" #include "interpreter/interpreterRuntime.hpp" diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -24,7 +24,6 @@ */ #include "precompiled.hpp" -#include "asm/assembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "interpreter/bytecodeHistogram.hpp" #include "interpreter/interpreter.hpp" diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -2366,7 +2366,7 @@ #endif // INCLUDE_ALL_GCS // Values for last_Java_pc, and last_Java_sp must comply to the rules -// in frame_ppc64.hpp. +// in frame_ppc.hpp. void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc) { // Always set last_Java_pc and flags first because once last_Java_sp // is visible has_last_Java_frame is true and users will look at the @@ -2493,6 +2493,7 @@ } void MacroAssembler::decode_klass_not_null(Register dst, Register src) { + assert(dst != R0, "Dst reg may not be R0, as R0 is used here."); if (src == noreg) src = dst; Register shifted_src = src; if (Universe::narrow_klass_shift() != 0 || @@ -2527,14 +2528,11 @@ void MacroAssembler::reinit_heapbase(Register d, Register tmp) { if (Universe::heap() != NULL) { - if (Universe::narrow_oop_base() == NULL) { - Assembler::xorr(R30, R30, R30); - } else { - load_const(R30, Universe::narrow_ptrs_base(), tmp); - } + load_const_optimized(R30, Universe::narrow_ptrs_base(), tmp); } else { - load_const(R30, Universe::narrow_ptrs_base_addr(), tmp); - ld(R30, 0, R30); + // Heap not yet allocated. Load indirectly. + int simm16_offset = load_const_optimized(R30, Universe::narrow_ptrs_base_addr(), tmp, true); + ld(R30, simm16_offset, R30); } } diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/ppc.ad --- a/hotspot/src/cpu/ppc/vm/ppc.ad Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/ppc.ad Wed Jul 05 20:04:43 2017 +0200 @@ -1249,6 +1249,7 @@ // Emit the trampoline stub which will be related to the branch-and-link below. CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); + if (Compile::current()->env()->failing()) { return offsets; } // Code cache may be full. __ relocate(rtype); } @@ -1410,7 +1411,7 @@ while (bang_offset <= bang_end) { // Need at least one stack bang at end of shadow zone. - // Again I had to copy code, this time from assembler_ppc64.cpp, + // Again I had to copy code, this time from assembler_ppc.cpp, // bang_stack_with_offset - see there for comments. // Stack grows down, caller passes positive offset. @@ -2000,7 +2001,7 @@ // Inline_cache contains a klass. Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); - Register receiver_klass = R0; // tmp + Register receiver_klass = R12_scratch2; // tmp assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); assert(R11_scratch1 == R11, "need prologue scratch register"); @@ -3484,6 +3485,7 @@ // Emit the trampoline stub which will be related to the branch-and-link below. CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); + if (Compile::current()->env()->failing()) { return; } // Code cache may be full. __ relocate(_optimized_virtual ? relocInfo::opt_virtual_call_type : relocInfo::static_call_type); } @@ -3527,6 +3529,7 @@ // Emit the trampoline stub which will be related to the branch-and-link below. CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); + if (ra_->C->env()->failing()) { return; } // Code cache may be full. assert(_optimized_virtual, "methodHandle call should be a virtual call"); __ relocate(relocInfo::opt_virtual_call_type); } @@ -3577,9 +3580,7 @@ const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); - - if (ra_->C->env()->failing()) - return; + if (ra_->C->env()->failing()) { return; } // Code cache may be full. // Build relocation at call site with ic position as data. assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || @@ -5638,19 +5639,6 @@ ins_pipe(pipe_class_memory); %} -//// Load compressed klass and decode it if narrow_klass_shift == 0. -//// TODO: will narrow_klass_shift ever be 0? -//instruct decodeNKlass2Klass(iRegPdst dst, memory mem) %{ -// match(Set dst (DecodeNKlass (LoadNKlass mem))); -// predicate(false /* TODO: PPC port Universe::narrow_klass_shift() == 0*); -// ins_cost(MEMORY_REF_COST); -// -// format %{ "LWZ $dst, $mem \t// DecodeNKlass (unscaled)" %} -// size(4); -// ins_encode( enc_lwz(dst, mem) ); -// ins_pipe(pipe_class_memory); -//%} - // Load Klass Pointer instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ match(Set dst (LoadKlass mem)); @@ -6070,11 +6058,15 @@ %} %} -instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{ +// We have seen a safepoint between the hi and lo parts, and this node was handled +// as an oop. Therefore this needs a match rule so that build_oop_map knows this is +// not a narrow oop. +instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ + match(Set dst src); effect(DEF dst, USE src); ins_cost(DEFAULT_COST); - format %{ "LIS $dst, $src \t// narrow oop hi" %} + format %{ "LIS $dst, $src \t// narrow klass hi" %} size(4); ins_encode %{ // TODO: PPC port $archOpcode(ppc64Opcode_addis); @@ -6084,6 +6076,21 @@ ins_pipe(pipe_class_default); %} +// As loadConNKlass_hi this must be recognized as narrow klass, not oop! +instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ + match(Set dst src1); + effect(TEMP src2); + ins_cost(DEFAULT_COST); + + format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask + size(4); + ins_encode %{ + // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); + __ clrldi($dst$$Register, $src2$$Register, 0x20); + %} + ins_pipe(pipe_class_default); +%} + // This needs a match rule so that build_oop_map knows this is // not a narrow oop. instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ @@ -6091,10 +6098,10 @@ effect(TEMP src2); ins_cost(DEFAULT_COST); - format %{ "ADDI $dst, $src1, $src2 \t// narrow oop lo" %} - size(4); - ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); + format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} + size(4); + ins_encode %{ + // TODO: PPC port $archOpcode(ppc64Opcode_ori); intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); @@ -6125,10 +6132,11 @@ MachNode *m2 = m1; if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { // Value might be 1-extended. Mask out these bits. - m2 = new clearMs32bNode(); + m2 = new loadConNKlass_maskNode(); m2->add_req(NULL, m1); m2->_opnds[0] = op_dst; - m2->_opnds[1] = op_dst; + m2->_opnds[1] = op_src; + m2->_opnds[2] = op_dst; ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); nodes->push(m2); } @@ -6973,7 +6981,7 @@ size(4); ins_encode %{ // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); - __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); + __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); %} ins_pipe(pipe_class_default); %} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -24,7 +24,6 @@ */ #include "precompiled.hpp" -#include "asm/assembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "interpreter/interpreter.hpp" #include "nativeInst_ppc.hpp" @@ -39,9 +38,6 @@ #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/top.hpp" -#ifdef COMPILER2 -#include "opto/runtime.hpp" -#endif #include "runtime/thread.inline.hpp" #define __ _masm-> @@ -216,7 +212,7 @@ { BLOCK_COMMENT("Call frame manager or native entry."); // Call frame manager or native entry. - Register r_new_arg_entry = R14; // PPC_state; + Register r_new_arg_entry = R14; assert_different_registers(r_new_arg_entry, r_top_of_arguments_addr, r_arg_method, r_arg_thread); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -353,7 +353,6 @@ __ sldi(Rscratch1, Rscratch1, LogBytesPerWord); __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Integer); __ bne(CCR0, notInt); - __ isync(); // Order load of constant wrt. tags. __ lwax(R17_tos, Rcpool, Rscratch1); __ push(itos); __ b(exit); @@ -365,7 +364,6 @@ __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float); __ asm_assert_eq("unexpected type", 0x8765); #endif - __ isync(); // Order load of constant wrt. tags. __ lfsx(F15_ftos, Rcpool, Rscratch1); __ push(ftos); @@ -424,13 +422,11 @@ // Check out Conversions.java for an example. // Also ConstantPool::header_size() is 20, which makes it very difficult // to double-align double on the constant pool. SG, 11/7/97 - __ isync(); // Order load of constant wrt. tags. __ lfdx(F15_ftos, Rcpool, Rindex); __ push(dtos); __ b(Lexit); __ bind(Llong); - __ isync(); // Order load of constant wrt. tags. __ ldx(R17_tos, Rcpool, Rindex); __ push(ltos); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/os/aix/vm/perfMemory_aix.cpp --- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1020,7 +1020,3 @@ unmap_shared(addr, bytes); } - -char* PerfMemory::backing_store_filename() { - return backing_store_file_name; -} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/os/bsd/vm/perfMemory_bsd.cpp --- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1043,7 +1043,3 @@ unmap_shared(addr, bytes); } - -char* PerfMemory::backing_store_filename() { - return backing_store_file_name; -} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/os/linux/vm/perfMemory_linux.cpp --- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1049,7 +1049,3 @@ unmap_shared(addr, bytes); } - -char* PerfMemory::backing_store_filename() { - return backing_store_file_name; -} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/os/solaris/vm/perfMemory_solaris.cpp --- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1068,7 +1068,3 @@ unmap_shared(addr, bytes); } - -char* PerfMemory::backing_store_filename() { - return backing_store_file_name; -} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/os/windows/vm/perfMemory_windows.cpp --- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1846,7 +1846,3 @@ remove_file_mapping(addr); } } - -char* PerfMemory::backing_store_filename() { - return sharedmem_fileName; -} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp --- a/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -47,4 +47,4 @@ ); } -#endif // OS_CPU_LINUX_PPC_VM_PREFETCH_LINUX_OJDKPPC_HPP +#endif // OS_CPU_LINUX_PPC_VM_PREFETCH_LINUX_PPC_INLINE_HPP diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -2069,14 +2069,14 @@ LIR_Opr base_op = base.result(); LIR_Opr index_op = idx.result(); #ifndef _LP64 - if (x->base()->type()->tag() == longTag) { + if (base_op->type() == T_LONG) { base_op = new_register(T_INT); __ convert(Bytecodes::_l2i, base.result(), base_op); } if (x->has_index()) { - if (x->index()->type()->tag() == longTag) { + if (index_op->type() == T_LONG) { LIR_Opr long_index_op = index_op; - if (x->index()->type()->is_constant()) { + if (index_op->is_constant()) { long_index_op = new_register(T_LONG); __ move(index_op, long_index_op); } @@ -2091,14 +2091,14 @@ assert(!x->has_index() || index_op->type() == T_INT, "index should be an int"); #else if (x->has_index()) { - if (x->index()->type()->tag() == intTag) { - if (!x->index()->type()->is_constant()) { + if (index_op->type() == T_INT) { + if (!index_op->is_constant()) { index_op = new_register(T_LONG); __ convert(Bytecodes::_i2l, idx.result(), index_op); } } else { - assert(x->index()->type()->tag() == longTag, "must be"); - if (x->index()->type()->is_constant()) { + assert(index_op->type() == T_LONG, "must be"); + if (index_op->is_constant()) { index_op = new_register(T_LONG); __ move(idx.result(), index_op); } @@ -2179,12 +2179,12 @@ LIR_Opr index_op = idx.result(); #ifndef _LP64 - if (x->base()->type()->tag() == longTag) { + if (base_op->type() == T_LONG) { base_op = new_register(T_INT); __ convert(Bytecodes::_l2i, base.result(), base_op); } if (x->has_index()) { - if (x->index()->type()->tag() == longTag) { + if (index_op->type() == T_LONG) { index_op = new_register(T_INT); __ convert(Bytecodes::_l2i, idx.result(), index_op); } @@ -2194,7 +2194,7 @@ assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int"); #else if (x->has_index()) { - if (x->index()->type()->tag() == intTag) { + if (index_op->type() == T_INT) { index_op = new_register(T_LONG); __ convert(Bytecodes::_i2l, idx.result(), index_op); } diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -2859,6 +2859,11 @@ "bootstrap_method_index %u has bad constant type in class file %s", bootstrap_method_index, CHECK); + + guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(), + "Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s", + CHECK); + operands->at_put(operand_fill_index++, bootstrap_method_index); operands->at_put(operand_fill_index++, argument_count); @@ -2875,8 +2880,6 @@ } } - assert(ConstantPool::operand_array_length(operands) == attribute_array_length, "correct decode"); - u1* current_end = cfs->current(); guarantee_property(current_end == current_start + attribute_byte_length, "Bad length on BootstrapMethods in class file %s", diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/classLoader.cpp --- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -75,6 +75,7 @@ typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf); typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf); typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n); +typedef jint (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len); static ZipOpen_t ZipOpen = NULL; static ZipClose_t ZipClose = NULL; @@ -83,6 +84,7 @@ static ReadMappedEntry_t ReadMappedEntry = NULL; static GetNextEntry_t GetNextEntry = NULL; static canonicalize_fn_t CanonicalizeEntry = NULL; +static Crc32_t Crc32 = NULL; // Globals @@ -799,9 +801,11 @@ ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry")); ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry")); GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry")); + Crc32 = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32")); // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL - if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || GetNextEntry == NULL) { + if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || + GetNextEntry == NULL || Crc32 == NULL) { vm_exit_during_initialization("Corrupted ZIP library", path); } @@ -811,6 +815,11 @@ // This lookup only works on 1.3. Do not check for non-null here } +int ClassLoader::crc32(int crc, const char* buf, int len) { + assert(Crc32 != NULL, "ZIP_CRC32 is not found"); + return (*Crc32)(crc, (const jbyte*)buf, len); +} + // PackageInfo data exists in order to support the java.lang.Package // class. A Package object provides information about a java package // (version, vendor, etc.) which originates in the manifest of the jar diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/classLoader.hpp --- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -226,6 +226,7 @@ // to avoid confusing the zip library static bool get_canonical_path(const char* orig, char* out, int len); public: + static int crc32(int crc, const char* buf, int len); static bool update_class_path_entry_list(const char *path, bool check_for_duplicates, bool throw_exception=true); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/stackMapFrame.cpp --- a/hotspot/src/share/vm/classfile/stackMapFrame.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/stackMapFrame.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -148,7 +148,7 @@ VerificationType* from, VerificationType* to, int32_t len, TRAPS) const { int32_t i = 0; for (i = 0; i < len; i++) { - if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) { + if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) { break; } } @@ -245,7 +245,7 @@ } VerificationType top = _stack[--_stack_size]; bool subtype = type.is_assignable_from( - top, verifier(), CHECK_(VerificationType::bogus_type())); + top, verifier(), false, CHECK_(VerificationType::bogus_type())); if (!subtype) { verifier()->verify_error( ErrorContext::bad_type(_offset, stack_top_ctx(), @@ -265,7 +265,7 @@ return VerificationType::bogus_type(); } bool subtype = type.is_assignable_from(_locals[index], - verifier(), CHECK_(VerificationType::bogus_type())); + verifier(), false, CHECK_(VerificationType::bogus_type())); if (!subtype) { verifier()->verify_error( ErrorContext::bad_type(_offset, @@ -288,14 +288,14 @@ "get long/double overflows locals"); return; } - bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK); + bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK); if (!subtype) { verifier()->verify_error( ErrorContext::bad_type(_offset, TypeOrigin::local(index, this), TypeOrigin::implicit(type1)), "Bad local variable type"); } else { - subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK); + subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK); if (!subtype) { /* Unreachable? All local store routines convert a split long or double * into a TOP during the store. So we should never end up seeing an diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/stackMapFrame.hpp --- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -234,7 +234,7 @@ if (_stack_size != 0) { VerificationType top = _stack[_stack_size - 1]; bool subtype = type.is_assignable_from( - top, verifier(), CHECK_(VerificationType::bogus_type())); + top, verifier(), false, CHECK_(VerificationType::bogus_type())); if (subtype) { --_stack_size; return top; @@ -249,9 +249,9 @@ assert(type2.is_long() || type2.is_double(), "must be long/double_2"); if (_stack_size >= 2) { VerificationType top1 = _stack[_stack_size - 1]; - bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK); + bool subtype1 = type1.is_assignable_from(top1, verifier(), false, CHECK); VerificationType top2 = _stack[_stack_size - 2]; - bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK); + bool subtype2 = type2.is_assignable_from(top2, verifier(), false, CHECK); if (subtype1 && subtype2) { _stack_size -= 2; return; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/verificationType.cpp --- a/hotspot/src/share/vm/classfile/verificationType.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/verificationType.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,8 @@ } bool VerificationType::is_reference_assignable_from( - const VerificationType& from, ClassVerifier* context, TRAPS) const { + const VerificationType& from, ClassVerifier* context, + bool from_field_is_protected, TRAPS) const { instanceKlassHandle klass = context->current_class(); if (from.is_null()) { // null is assignable to any reference @@ -62,9 +63,11 @@ Handle(THREAD, klass->protection_domain()), true, CHECK_false); KlassHandle this_class(THREAD, obj); - if (this_class->is_interface()) { - // We treat interfaces as java.lang.Object, including - // java.lang.Cloneable and java.io.Serializable + if (this_class->is_interface() && (!from_field_is_protected || + from.name() != vmSymbols::java_lang_Object())) { + // If we are not trying to access a protected field or method in + // java.lang.Object then we treat interfaces as java.lang.Object, + // including java.lang.Cloneable and java.io.Serializable. return true; } else if (from.is_object()) { Klass* from_class = SystemDictionary::resolve_or_fail( @@ -76,7 +79,8 @@ VerificationType comp_this = get_component(context, CHECK_false); VerificationType comp_from = from.get_component(context, CHECK_false); if (!comp_this.is_bogus() && !comp_from.is_bogus()) { - return comp_this.is_assignable_from(comp_from, context, CHECK_false); + return comp_this.is_assignable_from(comp_from, context, + from_field_is_protected, CHECK_false); } } return false; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/verificationType.hpp --- a/hotspot/src/share/vm/classfile/verificationType.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/verificationType.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -265,7 +265,8 @@ // is assignable to another. Returns true if one can assign 'from' to // this. bool is_assignable_from( - const VerificationType& from, ClassVerifier* context, TRAPS) const { + const VerificationType& from, ClassVerifier* context, + bool from_field_is_protected, TRAPS) const { if (equals(from) || is_bogus()) { return true; } else { @@ -286,7 +287,9 @@ return from.is_integer(); default: if (is_reference() && from.is_reference()) { - return is_reference_assignable_from(from, context, CHECK_false); + return is_reference_assignable_from(from, context, + from_field_is_protected, + CHECK_false); } else { return false; } @@ -308,7 +311,8 @@ private: bool is_reference_assignable_from( - const VerificationType&, ClassVerifier*, TRAPS) const; + const VerificationType&, ClassVerifier*, bool from_field_is_protected, + TRAPS) const; }; #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -98,6 +98,14 @@ HandleMark hm; ResourceMark rm(THREAD); + if (!is_eligible_for_verification(klass, should_verify_class)) { + return true; + } + + // If the class should be verified, first see if we can use the split + // verifier. If not, or if verification fails and FailOverToOldVerifier + // is set, then call the inference verifier. + Symbol* exception_name = NULL; const size_t message_buffer_len = klass->name()->utf8_length() + 1024; char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); @@ -105,47 +113,42 @@ const char* klassName = klass->external_name(); bool can_failover = FailOverToOldVerifier && - klass->major_version() < NOFAILOVER_MAJOR_VERSION; + klass->major_version() < NOFAILOVER_MAJOR_VERSION; - // If the class should be verified, first see if we can use the split - // verifier. If not, or if verification fails and FailOverToOldVerifier - // is set, then call the inference verifier. - if (is_eligible_for_verification(klass, should_verify_class)) { - if (TraceClassInitialization) { - tty->print_cr("Start class verification for: %s", klassName); + if (TraceClassInitialization) { + tty->print_cr("Start class verification for: %s", klassName); + } + if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { + ClassVerifier split_verifier(klass, THREAD); + split_verifier.verify_class(THREAD); + exception_name = split_verifier.result(); + if (can_failover && !HAS_PENDING_EXCEPTION && + (exception_name == vmSymbols::java_lang_VerifyError() || + exception_name == vmSymbols::java_lang_ClassFormatError())) { + if (TraceClassInitialization || VerboseVerification) { + tty->print_cr( + "Fail over class verification to old verifier for: %s", klassName); + } + exception_name = inference_verify( + klass, message_buffer, message_buffer_len, THREAD); } - if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { - ClassVerifier split_verifier(klass, THREAD); - split_verifier.verify_class(THREAD); - exception_name = split_verifier.result(); - if (can_failover && !HAS_PENDING_EXCEPTION && - (exception_name == vmSymbols::java_lang_VerifyError() || - exception_name == vmSymbols::java_lang_ClassFormatError())) { - if (TraceClassInitialization || VerboseVerification) { - tty->print_cr( - "Fail over class verification to old verifier for: %s", klassName); - } - exception_name = inference_verify( - klass, message_buffer, message_buffer_len, THREAD); - } - if (exception_name != NULL) { - exception_message = split_verifier.exception_message(); - } - } else { - exception_name = inference_verify( - klass, message_buffer, message_buffer_len, THREAD); + if (exception_name != NULL) { + exception_message = split_verifier.exception_message(); } + } else { + exception_name = inference_verify( + klass, message_buffer, message_buffer_len, THREAD); + } - if (TraceClassInitialization || VerboseVerification) { - if (HAS_PENDING_EXCEPTION) { - tty->print("Verification for %s has", klassName); - tty->print_cr(" exception pending %s ", - InstanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); - } else if (exception_name != NULL) { - tty->print_cr("Verification for %s failed", klassName); - } - tty->print_cr("End class verification for: %s", klassName); + if (TraceClassInitialization || VerboseVerification) { + if (HAS_PENDING_EXCEPTION) { + tty->print("Verification for %s has", klassName); + tty->print_cr(" exception pending %s ", + InstanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); + } else if (exception_name != NULL) { + tty->print_cr("Verification for %s failed", klassName); } + tty->print_cr("End class verification for: %s", klassName); } if (HAS_PENDING_EXCEPTION) { @@ -1718,7 +1721,7 @@ VerificationType throwable = VerificationType::reference_type(vmSymbols::java_lang_Throwable()); bool is_subclass = throwable.is_assignable_from( - catch_type, this, CHECK_VERIFY(this)); + catch_type, this, false, CHECK_VERIFY(this)); if (!is_subclass) { // 4286534: should throw VerifyError according to recent spec change verify_error(ErrorContext::bad_type(handler_pc, @@ -2171,7 +2174,7 @@ stack_object_type = current_type(); } is_assignable = target_class_type.is_assignable_from( - stack_object_type, this, CHECK_VERIFY(this)); + stack_object_type, this, false, CHECK_VERIFY(this)); if (!is_assignable) { verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx(), @@ -2198,7 +2201,7 @@ // It's protected access, check if stack object is assignable to // current class. is_assignable = current_type().is_assignable_from( - stack_object_type, this, CHECK_VERIFY(this)); + stack_object_type, this, true, CHECK_VERIFY(this)); if (!is_assignable) { verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx(), @@ -2472,7 +2475,7 @@ instanceKlassHandle mh(THREAD, m->method_holder()); if (m->is_protected() && !mh->is_same_class_package(_klass())) { bool assignable = current_type().is_assignable_from( - objectref_type, this, CHECK_VERIFY(this)); + objectref_type, this, true, CHECK_VERIFY(this)); if (!assignable) { verify_error(ErrorContext::bad_type(bci, TypeOrigin::cp(new_class_index, objectref_type), @@ -2643,11 +2646,11 @@ bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; if (!current_class()->is_anonymous()) { subtype = ref_class_type.is_assignable_from( - current_type(), this, CHECK_VERIFY(this)); + current_type(), this, false, CHECK_VERIFY(this)); } else { VerificationType host_klass_type = VerificationType::reference_type(current_class()->host_klass()->name()); - subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this)); + subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this)); // If invokespecial of IMR, need to recheck for same or // direct interface relative to the host class @@ -2691,7 +2694,7 @@ VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); VerificationType hosttype = VerificationType::reference_type(current_class()->host_klass()->name()); - bool subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this)); + bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this)); if (!subtype) { verify_error( ErrorContext::bad_type(current_frame->offset(), current_frame->stack_top_ctx(), @@ -2716,7 +2719,7 @@ // It's protected access, check if stack object is // assignable to current class. bool is_assignable = current_type().is_assignable_from( - stack_object_type, this, CHECK_VERIFY(this)); + stack_object_type, this, true, CHECK_VERIFY(this)); if (!is_assignable) { if (ref_class_type.name() == vmSymbols::java_lang_Object() && stack_object_type.is_array() @@ -2899,7 +2902,7 @@ "Method expects a return value"); return; } - bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this)); + bool match = return_type.is_assignable_from(type, this, false, CHECK_VERIFY(this)); if (!match) { verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)), diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/code/codeCache.cpp --- a/hotspot/src/share/vm/code/codeCache.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -254,8 +254,7 @@ if (!SegmentedCodeCache) { // No segmentation: use a single code heap return (code_blob_type == CodeBlobType::All); - } else if ((Arguments::mode() == Arguments::_int) || - (TieredStopAtLevel == CompLevel_none)) { + } else if (Arguments::mode() == Arguments::_int) { // Interpreter only: we don't need any method code heaps return (code_blob_type == CodeBlobType::NonNMethod); } else if (TieredCompilation && (TieredStopAtLevel > CompLevel_simple)) { diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1683,6 +1683,8 @@ int _failures; bool _verbose; + HeapRegionClaimer _hrclaimer; + public: G1ParVerifyFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm, @@ -1692,19 +1694,8 @@ _actual_region_bm(region_bm), _actual_card_bm(card_bm), _expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm), _failures(0), _verbose(false), - _n_workers(0) { + _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) { assert(VerifyDuringGC, "don't call this otherwise"); - - // Use the value already set as the number of active threads - // in the call to run_task(). - if (G1CollectedHeap::use_parallel_gc_threads()) { - assert( _g1h->workers()->active_workers() > 0, - "Should have been previously set"); - _n_workers = _g1h->workers()->active_workers(); - } else { - _n_workers = 1; - } - assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity"); assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity"); @@ -1721,10 +1712,7 @@ _verbose); if (G1CollectedHeap::use_parallel_gc_threads()) { - _g1h->heap_region_par_iterate_chunked(&verify_cl, - worker_id, - _n_workers, - HeapRegion::VerifyCountClaimValue); + _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer); } else { _g1h->heap_region_iterate(&verify_cl); } @@ -1813,22 +1801,14 @@ BitMap* _actual_card_bm; uint _n_workers; + HeapRegionClaimer _hrclaimer; public: G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm) : AbstractGangTask("G1 final counting"), _g1h(g1h), _cm(_g1h->concurrent_mark()), _actual_region_bm(region_bm), _actual_card_bm(card_bm), - _n_workers(0) { - // Use the value already set as the number of active threads - // in the call to run_task(). - if (G1CollectedHeap::use_parallel_gc_threads()) { - assert( _g1h->workers()->active_workers() > 0, - "Should have been previously set"); - _n_workers = _g1h->workers()->active_workers(); - } else { - _n_workers = 1; - } + _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) { } void work(uint worker_id) { @@ -1839,10 +1819,7 @@ _actual_card_bm); if (G1CollectedHeap::use_parallel_gc_threads()) { - _g1h->heap_region_par_iterate_chunked(&final_update_cl, - worker_id, - _n_workers, - HeapRegion::FinalCountClaimValue); + _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer); } else { _g1h->heap_region_iterate(&final_update_cl); } @@ -1929,12 +1906,12 @@ size_t _max_live_bytes; size_t _freed_bytes; FreeRegionList* _cleanup_list; + HeapRegionClaimer _hrclaimer; public: - G1ParNoteEndTask(G1CollectedHeap* g1h, - FreeRegionList* cleanup_list) : - AbstractGangTask("G1 note end"), _g1h(g1h), - _max_live_bytes(0), _freed_bytes(0), _cleanup_list(cleanup_list) { } + G1ParNoteEndTask(G1CollectedHeap* g1h, FreeRegionList* cleanup_list, uint n_workers) : + AbstractGangTask("G1 note end"), _g1h(g1h), _max_live_bytes(0), _freed_bytes(0), _cleanup_list(cleanup_list), _hrclaimer(n_workers) { + } void work(uint worker_id) { double start = os::elapsedTime(); @@ -1943,9 +1920,7 @@ G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list, &hrrs_cleanup_task); if (G1CollectedHeap::use_parallel_gc_threads()) { - _g1h->heap_region_par_iterate_chunked(&g1_note_end, worker_id, - _g1h->workers()->active_workers(), - HeapRegion::NoteEndClaimValue); + _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer); } else { _g1h->heap_region_iterate(&g1_note_end); } @@ -1991,16 +1966,16 @@ G1RemSet* _g1rs; BitMap* _region_bm; BitMap* _card_bm; + HeapRegionClaimer _hrclaimer; + public: - G1ParScrubRemSetTask(G1CollectedHeap* g1h, - BitMap* region_bm, BitMap* card_bm) : - AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()), - _region_bm(region_bm), _card_bm(card_bm) { } + G1ParScrubRemSetTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm, uint n_workers) : + AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()), _region_bm(region_bm), _card_bm(card_bm), _hrclaimer(n_workers) { + } void work(uint worker_id) { if (G1CollectedHeap::use_parallel_gc_threads()) { - _g1rs->scrub_par(_region_bm, _card_bm, worker_id, - HeapRegion::ScrubRemSetClaimValue); + _g1rs->scrub_par(_region_bm, _card_bm, worker_id, &_hrclaimer); } else { _g1rs->scrub(_region_bm, _card_bm); } @@ -2043,9 +2018,6 @@ G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm); if (G1CollectedHeap::use_parallel_gc_threads()) { - assert(g1h->check_heap_region_claim_values(HeapRegion::InitialClaimValue), - "sanity check"); - g1h->set_par_threads(); n_workers = g1h->n_par_threads(); assert(g1h->n_par_threads() == n_workers, @@ -2053,9 +2025,6 @@ g1h->workers()->run_task(&g1_par_count_task); // Done with the parallel phase so reset to 0. g1h->set_par_threads(0); - - assert(g1h->check_heap_region_claim_values(HeapRegion::FinalCountClaimValue), - "sanity check"); } else { n_workers = 1; g1_par_count_task.work(0); @@ -2080,9 +2049,6 @@ g1h->workers()->run_task(&g1_par_verify_task); // Done with the parallel phase so reset to 0. g1h->set_par_threads(0); - - assert(g1h->check_heap_region_claim_values(HeapRegion::VerifyCountClaimValue), - "sanity check"); } else { g1_par_verify_task.work(0); } @@ -2108,14 +2074,11 @@ g1h->reset_gc_time_stamp(); // Note end of marking in all heap regions. - G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list); + G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list, n_workers); if (G1CollectedHeap::use_parallel_gc_threads()) { g1h->set_par_threads((int)n_workers); g1h->workers()->run_task(&g1_par_note_end_task); g1h->set_par_threads(0); - - assert(g1h->check_heap_region_claim_values(HeapRegion::NoteEndClaimValue), - "sanity check"); } else { g1_par_note_end_task.work(0); } @@ -2132,15 +2095,11 @@ // regions. if (G1ScrubRemSets) { double rs_scrub_start = os::elapsedTime(); - G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm); + G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers); if (G1CollectedHeap::use_parallel_gc_threads()) { g1h->set_par_threads((int)n_workers); g1h->workers()->run_task(&g1_par_scrub_rs_task); g1h->set_par_threads(0); - - assert(g1h->check_heap_region_claim_values( - HeapRegion::ScrubRemSetClaimValue), - "sanity check"); } else { g1_par_scrub_rs_task.work(0); } @@ -3288,6 +3247,7 @@ BitMap* _cm_card_bm; uint _max_worker_id; int _active_workers; + HeapRegionClaimer _hrclaimer; public: G1AggregateCountDataTask(G1CollectedHeap* g1h, @@ -3295,18 +3255,18 @@ BitMap* cm_card_bm, uint max_worker_id, int n_workers) : - AbstractGangTask("Count Aggregation"), - _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm), - _max_worker_id(max_worker_id), - _active_workers(n_workers) { } + AbstractGangTask("Count Aggregation"), + _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm), + _max_worker_id(max_worker_id), + _active_workers(n_workers), + _hrclaimer(_active_workers) { + } void work(uint worker_id) { AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id); if (G1CollectedHeap::use_parallel_gc_threads()) { - _g1h->heap_region_par_iterate_chunked(&cl, worker_id, - _active_workers, - HeapRegion::AggregateCountClaimValue); + _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer); } else { _g1h->heap_region_iterate(&cl); } @@ -3323,15 +3283,9 @@ _max_worker_id, n_workers); if (G1CollectedHeap::use_parallel_gc_threads()) { - assert(_g1h->check_heap_region_claim_values(HeapRegion::InitialClaimValue), - "sanity check"); _g1h->set_par_threads(n_workers); _g1h->workers()->run_task(&g1_par_agg_task); _g1h->set_par_threads(0); - - assert(_g1h->check_heap_region_claim_values(HeapRegion::AggregateCountClaimValue), - "sanity check"); - _g1h->reset_heap_region_claim_values(); } else { g1_par_agg_task.work(0); } diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -90,8 +90,8 @@ // Notes on implementation of parallelism in different tasks. // -// G1ParVerifyTask uses heap_region_par_iterate_chunked() for parallelism. -// The number of GC workers is passed to heap_region_par_iterate_chunked(). +// G1ParVerifyTask uses heap_region_par_iterate() for parallelism. +// The number of GC workers is passed to heap_region_par_iterate(). // It does use run_task() which sets _n_workers in the task. // G1ParTask executes g1_process_roots() -> // SharedHeap::process_roots() which calls eventually to @@ -1215,17 +1215,15 @@ class ParRebuildRSTask: public AbstractGangTask { G1CollectedHeap* _g1; + HeapRegionClaimer _hrclaimer; + public: - ParRebuildRSTask(G1CollectedHeap* g1) - : AbstractGangTask("ParRebuildRSTask"), - _g1(g1) - { } + ParRebuildRSTask(G1CollectedHeap* g1) : + AbstractGangTask("ParRebuildRSTask"), _g1(g1), _hrclaimer(g1->workers()->active_workers()) {} void work(uint worker_id) { RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id); - _g1->heap_region_par_iterate_chunked(&rebuild_rs, worker_id, - _g1->workers()->active_workers(), - HeapRegion::RebuildRSClaimValue); + _g1->heap_region_par_iterate(&rebuild_rs, worker_id, &_hrclaimer); } }; @@ -1455,8 +1453,6 @@ set_par_threads(n_workers); ParRebuildRSTask rebuild_rs_task(this); - assert(check_heap_region_claim_values( - HeapRegion::InitialClaimValue), "sanity check"); assert(UseDynamicNumberOfGCThreads || workers()->active_workers() == workers()->total_workers(), "Unless dynamic should use total workers"); @@ -1466,9 +1462,6 @@ set_par_threads(workers()->active_workers()); workers()->run_task(&rebuild_rs_task); set_par_threads(0); - assert(check_heap_region_claim_values( - HeapRegion::RebuildRSClaimValue), "sanity check"); - reset_heap_region_claim_values(); } else { RebuildRSOutOfRegionClosure rebuild_rs(this); heap_region_iterate(&rebuild_rs); @@ -2343,6 +2336,7 @@ case GCCause::_gc_locker: return GCLockerInvokesConcurrent; case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent; case GCCause::_g1_humongous_allocation: return true; + case GCCause::_update_allocation_context_stats_inc: return true; default: return false; } } @@ -2633,110 +2627,11 @@ } void -G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, - uint worker_id, - uint num_workers, - jint claim_value) const { - _hrm.par_iterate(cl, worker_id, num_workers, claim_value); -} - -class ResetClaimValuesClosure: public HeapRegionClosure { -public: - bool doHeapRegion(HeapRegion* r) { - r->set_claim_value(HeapRegion::InitialClaimValue); - return false; - } -}; - -void G1CollectedHeap::reset_heap_region_claim_values() { - ResetClaimValuesClosure blk; - heap_region_iterate(&blk); -} - -void G1CollectedHeap::reset_cset_heap_region_claim_values() { - ResetClaimValuesClosure blk; - collection_set_iterate(&blk); -} - -#ifdef ASSERT -// This checks whether all regions in the heap have the correct claim -// value. I also piggy-backed on this a check to ensure that the -// humongous_start_region() information on "continues humongous" -// regions is correct. - -class CheckClaimValuesClosure : public HeapRegionClosure { -private: - jint _claim_value; - uint _failures; - HeapRegion* _sh_region; - -public: - CheckClaimValuesClosure(jint claim_value) : - _claim_value(claim_value), _failures(0), _sh_region(NULL) { } - bool doHeapRegion(HeapRegion* r) { - if (r->claim_value() != _claim_value) { - gclog_or_tty->print_cr("Region " HR_FORMAT ", " - "claim value = %d, should be %d", - HR_FORMAT_PARAMS(r), - r->claim_value(), _claim_value); - ++_failures; - } - if (!r->is_humongous()) { - _sh_region = NULL; - } else if (r->is_starts_humongous()) { - _sh_region = r; - } else if (r->is_continues_humongous()) { - if (r->humongous_start_region() != _sh_region) { - gclog_or_tty->print_cr("Region " HR_FORMAT ", " - "HS = "PTR_FORMAT", should be "PTR_FORMAT, - HR_FORMAT_PARAMS(r), - r->humongous_start_region(), - _sh_region); - ++_failures; - } - } - return false; - } - uint failures() { return _failures; } -}; - -bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) { - CheckClaimValuesClosure cl(claim_value); - heap_region_iterate(&cl); - return cl.failures() == 0; -} - -class CheckClaimValuesInCSetHRClosure: public HeapRegionClosure { -private: - jint _claim_value; - uint _failures; - -public: - CheckClaimValuesInCSetHRClosure(jint claim_value) : - _claim_value(claim_value), _failures(0) { } - - uint failures() { return _failures; } - - bool doHeapRegion(HeapRegion* hr) { - assert(hr->in_collection_set(), "how?"); - assert(!hr->is_humongous(), "H-region in CSet"); - if (hr->claim_value() != _claim_value) { - gclog_or_tty->print_cr("CSet Region " HR_FORMAT ", " - "claim value = %d, should be %d", - HR_FORMAT_PARAMS(hr), - hr->claim_value(), _claim_value); - _failures += 1; - } - return false; - } -}; - -bool G1CollectedHeap::check_cset_heap_region_claim_values(jint claim_value) { - CheckClaimValuesInCSetHRClosure cl(claim_value); - collection_set_iterate(&cl); - return cl.failures() == 0; -} -#endif // ASSERT +G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl, + uint worker_id, + HeapRegionClaimer *hrclaimer) const { + _hrm.par_iterate(cl, worker_id, hrclaimer); +} // Clear the cached CSet starting regions and (more importantly) // the time stamps. Called when we reset the GC time stamp. @@ -3251,19 +3146,21 @@ class G1ParVerifyTask: public AbstractGangTask { private: - G1CollectedHeap* _g1h; - VerifyOption _vo; - bool _failures; + G1CollectedHeap* _g1h; + VerifyOption _vo; + bool _failures; + HeapRegionClaimer _hrclaimer; public: // _vo == UsePrevMarking -> use "prev" marking information, // _vo == UseNextMarking -> use "next" marking information, // _vo == UseMarkWord -> use mark word from object header. G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) : - AbstractGangTask("Parallel verify task"), - _g1h(g1h), - _vo(vo), - _failures(false) { } + AbstractGangTask("Parallel verify task"), + _g1h(g1h), + _vo(vo), + _failures(false), + _hrclaimer(g1h->workers()->active_workers()) {} bool failures() { return _failures; @@ -3272,9 +3169,7 @@ void work(uint worker_id) { HandleMark hm; VerifyRegionClosure blk(true, _vo); - _g1h->heap_region_par_iterate_chunked(&blk, worker_id, - _g1h->workers()->active_workers(), - HeapRegion::ParVerifyClaimValue); + _g1h->heap_region_par_iterate(&blk, worker_id, &_hrclaimer); if (blk.failures()) { _failures = true; } @@ -3316,8 +3211,6 @@ if (!silent) { gclog_or_tty->print("HeapRegions "); } if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { - assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), - "sanity check"); G1ParVerifyTask task(this, vo); assert(UseDynamicNumberOfGCThreads || @@ -3331,15 +3224,6 @@ failures = true; } - // Checks that the expected amount of parallel work was done. - // The implication is that n_workers is > 0. - assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue), - "sanity check"); - - reset_heap_region_claim_values(); - - assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), - "sanity check"); } else { VerifyRegionClosure blk(false, vo); heap_region_iterate(&blk); @@ -3926,8 +3810,6 @@ } assert(check_young_list_well_formed(), "young list should be well formed"); - assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), - "sanity check"); // Don't dynamically change the number of GC threads this early. A value of // 0 is used to indicate serial work. When parallel work is done, @@ -4288,26 +4170,12 @@ } void G1CollectedHeap::remove_self_forwarding_pointers() { - assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity"); - double remove_self_forwards_start = os::elapsedTime(); + set_par_threads(); G1ParRemoveSelfForwardPtrsTask rsfp_task(this); - - if (G1CollectedHeap::use_parallel_gc_threads()) { - set_par_threads(); - workers()->run_task(&rsfp_task); - set_par_threads(0); - } else { - rsfp_task.work(0); - } - - assert(check_cset_heap_region_claim_values(HeapRegion::ParEvacFailureClaimValue), "sanity"); - - // Reset the claim values in the regions in the collection set. - reset_cset_heap_region_claim_values(); - - assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity"); + workers()->run_task(&rsfp_task); + set_par_threads(0); // Now restore saved marks, if any. assert(_objs_with_preserved_marks.size() == @@ -5948,11 +5816,6 @@ purge_code_root_memory(); - if (g1_policy()->during_initial_mark_pause()) { - // Reset the claim values set during marking the strong code roots - reset_heap_region_claim_values(); - } - finalize_for_evac_failure(); if (evacuation_failed()) { diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -211,6 +211,7 @@ friend class G1FreeHumongousRegionClosure; // Other related classes. friend class G1MarkSweep; + friend class HeapRegionClaimer; private: // The one and only G1CollectedHeap, so static functions can find it. @@ -1377,38 +1378,15 @@ inline HeapWord* bottom_addr_for_region(uint index) const; - // Divide the heap region sequence into "chunks" of some size (the number - // of regions divided by the number of parallel threads times some - // overpartition factor, currently 4). Assumes that this will be called - // in parallel by ParallelGCThreads worker threads with distinct worker - // ids in the range [0..max(ParallelGCThreads-1, 1)], that all parallel - // calls will use the same "claim_value", and that that claim value is - // different from the claim_value of any heap region before the start of - // the iteration. Applies "blk->doHeapRegion" to each of the regions, by - // attempting to claim the first region in each chunk, and, if - // successful, applying the closure to each region in the chunk (and - // setting the claim value of the second and subsequent regions of the - // chunk.) For now requires that "doHeapRegion" always returns "false", - // i.e., that a closure never attempt to abort a traversal. - void heap_region_par_iterate_chunked(HeapRegionClosure* cl, - uint worker_id, - uint num_workers, - jint claim_value) const; - - // It resets all the region claim values to the default. - void reset_heap_region_claim_values(); - - // Resets the claim values of regions in the current - // collection set to the default. - void reset_cset_heap_region_claim_values(); - -#ifdef ASSERT - bool check_heap_region_claim_values(jint claim_value); - - // Same as the routine above but only checks regions in the - // current collection set. - bool check_cset_heap_region_claim_values(jint claim_value); -#endif // ASSERT + // Iterate over the heap regions in parallel. Assumes that this will be called + // in parallel by ParallelGCThreads worker threads with distinct worker ids + // in the range [0..max(ParallelGCThreads-1, 1)]. Applies "blk->doHeapRegion" + // to each of the regions, by attempting to claim the region using the + // HeapRegionClaimer and, if successful, applying the closure to the claimed + // region. + void heap_region_par_iterate(HeapRegionClosure* cl, + uint worker_id, + HeapRegionClaimer* hrclaimer) const; // Clear the cached cset start regions and (more importantly) // the time stamps. Called when we reset the GC time stamp. diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1598,19 +1598,17 @@ CollectionSetChooser* _hrSorted; uint _chunk_size; G1CollectedHeap* _g1; + HeapRegionClaimer _hrclaimer; + public: - ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size) : - AbstractGangTask("ParKnownGarbageTask"), - _hrSorted(hrSorted), _chunk_size(chunk_size), - _g1(G1CollectedHeap::heap()) { } + ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size, uint n_workers) : + AbstractGangTask("ParKnownGarbageTask"), + _hrSorted(hrSorted), _chunk_size(chunk_size), + _g1(G1CollectedHeap::heap()), _hrclaimer(n_workers) {} void work(uint worker_id) { ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size); - - // Back to zero for the claim value. - _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, worker_id, - _g1->workers()->active_workers(), - HeapRegion::InitialClaimValue); + _g1->heap_region_par_iterate(&parKnownGarbageCl, worker_id, &_hrclaimer); } }; @@ -1641,12 +1639,8 @@ } _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(), WorkUnit); - ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, - (int) WorkUnit); + ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads); _g1->workers()->run_task(&parKnownGarbageTask); - - assert(_g1->check_heap_region_claim_values(HeapRegion::InitialClaimValue), - "sanity check"); } else { KnownGarbageClosure knownGarbagecl(_collectionSetChooser); _g1->heap_region_iterate(&knownGarbagecl); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -177,16 +177,18 @@ G1CollectedHeap* _g1h; ConcurrentMark* _cm; uint _worker_id; + HeapRegionClaimer* _hrclaimer; DirtyCardQueue _dcq; UpdateRSetDeferred _update_rset_cl; public: RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h, - uint worker_id) : - _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq), - _worker_id(worker_id), _cm(_g1h->concurrent_mark()) { - } + uint worker_id, + HeapRegionClaimer* hrclaimer) : + _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq), + _worker_id(worker_id), _cm(_g1h->concurrent_mark()), _hrclaimer(hrclaimer) { + } bool doHeapRegion(HeapRegion *hr) { bool during_initial_mark = _g1h->g1_policy()->during_initial_mark_pause(); @@ -195,7 +197,7 @@ assert(!hr->is_humongous(), "sanity"); assert(hr->in_collection_set(), "bad CS"); - if (hr->claimHeapRegion(HeapRegion::ParEvacFailureClaimValue)) { + if (_hrclaimer->claim_region(hr->hrm_index())) { if (hr->evacuation_failed()) { RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, &_update_rset_cl, during_initial_mark, @@ -233,14 +235,15 @@ class G1ParRemoveSelfForwardPtrsTask: public AbstractGangTask { protected: G1CollectedHeap* _g1h; + HeapRegionClaimer _hrclaimer; public: G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h) : - AbstractGangTask("G1 Remove Self-forwarding Pointers"), - _g1h(g1h) { } + AbstractGangTask("G1 Remove Self-forwarding Pointers"), _g1h(g1h), + _hrclaimer(g1h->workers()->active_workers()) {} void work(uint worker_id) { - RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id); + RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id, &_hrclaimer); HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id); _g1h->collection_set_iterate_from(hr, &rsfp_cl); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -425,13 +425,9 @@ _g1->heap_region_iterate(&scrub_cl); } -void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, - uint worker_num, int claim_val) { +void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) { ScrubRSClosure scrub_cl(region_bm, card_bm); - _g1->heap_region_par_iterate_chunked(&scrub_cl, - worker_num, - n_workers(), - claim_val); + _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer); } G1TriggerClosure::G1TriggerClosure() : diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -128,10 +128,10 @@ void scrub(BitMap* region_bm, BitMap* card_bm); // Like the above, but assumes is called in parallel: "worker_num" is the - // parallel thread id of the current thread, and "claim_val" is the - // value that should be used to claim heap regions. + // parallel thread id of the current thread, and "hrclaimer" is the shared + // HeapRegionClaimer that should be used to claim heap regions. void scrub_par(BitMap* region_bm, BitMap* card_bm, - uint worker_num, int claim_val); + uint worker_num, HeapRegionClaimer* hrclaimer); // Refine the card corresponding to "card_ptr". // If check_for_refs_into_cset is true, a true result is returned diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -217,7 +217,6 @@ } else { hrrs->clear(); } - _claimed = InitialClaimValue; } zero_marked_bytes(); @@ -294,17 +293,6 @@ _humongous_start_region = NULL; } -bool HeapRegion::claimHeapRegion(jint claimValue) { - jint current = _claimed; - if (current != claimValue) { - jint res = Atomic::cmpxchg(claimValue, &_claimed, current); - if (res == current) { - return true; - } - } - return false; -} - HeapRegion::HeapRegion(uint hrm_index, G1BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) : @@ -314,7 +302,7 @@ _humongous_start_region(NULL), _in_collection_set(false), _next_in_special_set(NULL), - _claimed(InitialClaimValue), _evacuation_failed(false), + _evacuation_failed(false), _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0), _next_young_region(NULL), _next_dirty_cards_region(NULL), _next(NULL), _prev(NULL), diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -254,9 +254,6 @@ HeapRegionSetBase* _containing_set; #endif // ASSERT - // For parallel heapRegion traversal. - jint _claimed; - // We use concurrent marking to determine the amount of live data // in each heap region. size_t _prev_marked_bytes; // Bytes known to be live via last completed marking. @@ -336,19 +333,6 @@ // up once during initialization time. static void setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size); - enum ClaimValues { - InitialClaimValue = 0, - FinalCountClaimValue = 1, - NoteEndClaimValue = 2, - ScrubRemSetClaimValue = 3, - ParVerifyClaimValue = 4, - RebuildRSClaimValue = 5, - ParEvacFailureClaimValue = 6, - AggregateCountClaimValue = 7, - VerifyCountClaimValue = 8, - ParMarkRootClaimValue = 9 - }; - // All allocated blocks are occupied by objects in a HeapRegion bool block_is_obj(const HeapWord* p) const; @@ -691,12 +675,6 @@ return (HeapWord *) obj >= next_top_at_mark_start(); } - // For parallel heapRegion traversal. - bool claimHeapRegion(int claimValue); - jint claim_value() { return _claimed; } - // Use this carefully: only when you're sure no one is claiming... - void set_claim_value(int claimValue) { _claimed = claimValue; } - // Returns the "evacuation_failed" property of the region. bool evacuation_failed() { return _evacuation_failed; } diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -260,20 +260,17 @@ return num_regions; } -uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const { - return num_regions * worker_i / num_workers; -} - -void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const { - const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length); +void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const { + const uint start_index = hrclaimer->start_region_for_worker(worker_id); // Every worker will actually look at all regions, skipping over regions that // are currently not committed. // This also (potentially) iterates over regions newly allocated during GC. This // is no problem except for some extra work. - for (uint count = 0; count < _allocated_heapregions_length; count++) { - const uint index = (start_index + count) % _allocated_heapregions_length; - assert(0 <= index && index < _allocated_heapregions_length, "sanity"); + const uint n_regions = hrclaimer->n_regions(); + for (uint count = 0; count < n_regions; count++) { + const uint index = (start_index + count) % n_regions; + assert(0 <= index && index < n_regions, "sanity"); // Skip over unavailable regions if (!is_available(index)) { continue; @@ -282,11 +279,11 @@ // We'll ignore "continues humongous" regions (we'll process them // when we come across their corresponding "start humongous" // region) and regions already claimed. - if (r->claim_value() == claim_value || r->is_continues_humongous()) { + if (hrclaimer->is_region_claimed(index) || r->is_continues_humongous()) { continue; } // OK, try to claim it - if (!r->claimHeapRegion(claim_value)) { + if (!hrclaimer->claim_region(index)) { continue; } // Success! @@ -306,13 +303,11 @@ assert(chr->humongous_start_region() == r, err_msg("Must work on humongous continuation of the original start region " PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr))); - assert(chr->claim_value() != claim_value, + assert(!hrclaimer->is_region_claimed(ch_index), "Must not have been claimed yet because claiming of humongous continuation first claims the start region"); - bool claim_result = chr->claimHeapRegion(claim_value); - // We should always be able to claim it; no one else should - // be trying to claim this region. - guarantee(claim_result, "We should always be able to claim the is_continues_humongous part of the humongous object"); + // There's no need to actually claim the continues humongous region, but we can do it in an assert as an extra precaution. + assert(hrclaimer->claim_region(ch_index), "We should always be able to claim the continuesHumongous part of the humongous object"); bool res2 = blk->doHeapRegion(chr); if (res2) { @@ -445,3 +440,31 @@ } #endif // PRODUCT +HeapRegionClaimer::HeapRegionClaimer(uint n_workers) : + _n_workers(n_workers), _n_regions(G1CollectedHeap::heap()->_hrm._allocated_heapregions_length), _claims(NULL) { + assert(n_workers > 0, "Need at least one worker."); + _claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC); + memset(_claims, Unclaimed, sizeof(*_claims) * _n_regions); +} + +HeapRegionClaimer::~HeapRegionClaimer() { + if (_claims != NULL) { + FREE_C_HEAP_ARRAY(uint, _claims, mtGC); + } +} + +uint HeapRegionClaimer::start_region_for_worker(uint worker_id) const { + assert(worker_id < _n_workers, "Invalid worker_id."); + return _n_regions * worker_id / _n_workers; +} + +bool HeapRegionClaimer::is_region_claimed(uint region_index) const { + assert(region_index < _n_regions, "Invalid index."); + return _claims[region_index] == Claimed; +} + +bool HeapRegionClaimer::claim_region(uint region_index) { + assert(region_index < _n_regions, "Invalid index."); + uint old_val = Atomic::cmpxchg(Claimed, &_claims[region_index], Unclaimed); + return old_val == Unclaimed; +} diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -31,6 +31,7 @@ class HeapRegion; class HeapRegionClosure; +class HeapRegionClaimer; class FreeRegionList; class G1HeapRegionTable : public G1BiasedMappedArray { @@ -66,6 +67,7 @@ class HeapRegionManager: public CHeapObj { friend class VMStructs; + friend class HeapRegionClaimer; G1HeapRegionTable _regions; @@ -99,9 +101,6 @@ // Notify other data structures about change in the heap layout. void update_committed_space(HeapWord* old_end, HeapWord* new_end); - // Calculate the starting region for each worker during parallel iteration so - // that they do not all start from the same region. - uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const; // Find a contiguous set of empty or uncommitted regions of length num and return // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful. @@ -223,7 +222,7 @@ // terminating the iteration early if doHeapRegion() returns true. void iterate(HeapRegionClosure* blk) const; - void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const; + void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const; // Uncommit up to num_regions_to_remove regions that are completely free. // Return the actual number of uncommitted regions. @@ -235,5 +234,33 @@ void verify_optional() PRODUCT_RETURN; }; +// The HeapRegionClaimer is used during parallel iteration over heap regions, +// allowing workers to claim heap regions, gaining exclusive rights to these regions. +class HeapRegionClaimer : public StackObj { + uint _n_workers; + uint _n_regions; + uint* _claims; + + static const uint Unclaimed = 0; + static const uint Claimed = 1; + + public: + HeapRegionClaimer(uint n_workers); + ~HeapRegionClaimer(); + + inline uint n_regions() const { + return _n_regions; + } + + // Calculate the starting region for given worker so + // that they do not all start from the same region. + uint start_region_for_worker(uint worker_id) const; + + // Check if region has been claimed with this HRClaimer. + bool is_region_claimed(uint region_index) const; + + // Claim the given region, returns true if successfully claimed. + bool claim_region(uint region_index); +}; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -95,8 +95,9 @@ assert(!_should_initiate_conc_mark || ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) || - _gc_cause == GCCause::_g1_humongous_allocation), - "only a GC locker, a System.gc() or a hum allocation induced GC should start a cycle"); + _gc_cause == GCCause::_g1_humongous_allocation || + _gc_cause == GCCause::_update_allocation_context_stats_inc), + "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle"); if (_word_size > 0) { // An allocation has been requested. So, try to do that first. diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_interface/gcCause.cpp --- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -54,7 +54,8 @@ case _wb_young_gc: return "WhiteBox Initiated Young GC"; - case _update_allocation_context_stats: + case _update_allocation_context_stats_inc: + case _update_allocation_context_stats_full: return "Update Allocation Context Stats"; case _no_gc: diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/gc_interface/gcCause.hpp --- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -47,7 +47,8 @@ _heap_inspection, _heap_dump, _wb_young_gc, - _update_allocation_context_stats, + _update_allocation_context_stats_inc, + _update_allocation_context_stats_full, /* implementation independent, but reserved for GC use */ _no_gc, diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -246,6 +246,12 @@ // Ignore overpasses so statics can be found during resolution Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass); + if (klass->oop_is_array()) { + // Only consider klass and super klass for arrays + result = methodHandle(THREAD, result_oop); + return; + } + // JDK 8, JVMS 5.4.3.4: Interface method resolution should // ignore static and non-public methods of java.lang.Object, // like clone, finalize, registerNatives. @@ -290,6 +296,11 @@ result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal)); } + if (klass->oop_is_array()) { + // Only consider klass and super klass for arrays + return; + } + if (result.is_null()) { Array* default_methods = InstanceKlass::cast(klass())->default_methods(); if (default_methods != NULL) { @@ -545,7 +556,7 @@ // 2. lookup method in resolved klass and its super klasses lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK); - if (resolved_method.is_null()) { // not found in the class hierarchy + if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy // 3. lookup method in all the interfaces implemented by the resolved klass lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); @@ -558,16 +569,16 @@ CLEAR_PENDING_EXCEPTION; } } + } - if (resolved_method.is_null()) { - // 4. method lookup failed - ResourceMark rm(THREAD); - THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), - Method::name_and_sig_as_C_string(resolved_klass(), - method_name, - method_signature), - nested_exception); - } + if (resolved_method.is_null()) { + // 4. method lookup failed + ResourceMark rm(THREAD); + THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), + Method::name_and_sig_as_C_string(resolved_klass(), + method_name, + method_signature), + nested_exception); } // 5. access checks, access checking may be turned off when calling from within the VM. @@ -633,17 +644,18 @@ // JDK8: also look for static methods lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK); - if (resolved_method.is_null()) { + if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // lookup method in all the super-interfaces lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); - if (resolved_method.is_null()) { - // no method found - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), - Method::name_and_sig_as_C_string(resolved_klass(), - method_name, - method_signature)); - } + } + + if (resolved_method.is_null()) { + // no method found + ResourceMark rm(THREAD); + THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), + Method::name_and_sig_as_C_string(resolved_klass(), + method_name, + method_signature)); } if (check_access) { @@ -775,7 +787,7 @@ } // Resolve instance field - KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); + KlassHandle sel_klass(THREAD, resolved_klass->find_field(field, sig, &fd)); // check if field exists; i.e., if a klass containing the field def has been selected if (sel_klass.is_null()) { ResourceMark rm(THREAD); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/memory/filemap.cpp --- a/hotspot/src/share/vm/memory/filemap.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/memory/filemap.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -331,6 +331,14 @@ return false; } + size_t len = lseek(fd, 0, SEEK_END); + struct FileMapInfo::FileMapHeader::space_info* si = + &_header->_space[MetaspaceShared::mc]; + if (si->_file_offset >= len || len - si->_file_offset < si->_used) { + fail_continue("The shared archive file has been truncated."); + return false; + } + _file_offset += (long)n; return true; } @@ -431,6 +439,7 @@ si->_capacity = capacity; si->_read_only = read_only; si->_allow_exec = allow_exec; + si->_crc = ClassLoader::crc32(0, base, (jint)size); write_bytes_aligned(base, (int)size); } @@ -455,14 +464,15 @@ // Align file position to an allocation unit boundary. void FileMapInfo::align_file_position() { - long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity()); + size_t new_file_offset = align_size_up(_file_offset, + os::vm_allocation_granularity()); if (new_file_offset != _file_offset) { _file_offset = new_file_offset; if (_file_open) { // Seek one byte back from the target and write a byte to insure // that the written file is the correct length. _file_offset -= 1; - if (lseek(_fd, _file_offset, SEEK_SET) < 0) { + if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) { fail_stop("Unable to seek."); } char zero = 0; @@ -569,6 +579,19 @@ return base; } +bool FileMapInfo::verify_region_checksum(int i) { + if (!VerifySharedSpaces) { + return true; + } + const char* buf = _header->_space[i]._base; + size_t sz = _header->_space[i]._used; + int crc = ClassLoader::crc32(0, buf, (jint)sz); + if (crc != _header->_space[i]._crc) { + fail_continue("Checksum verification failed."); + return false; + } + return true; +} // Unmap a memory region in the address space. @@ -629,7 +652,21 @@ return true; } +int FileMapInfo::FileMapHeader::compute_crc() { + char* header = data(); + // start computing from the field after _crc + char* buf = (char*)&_crc + sizeof(int); + size_t sz = data_size() - (buf - header); + int crc = ClassLoader::crc32(0, buf, (jint)sz); + return crc; +} + bool FileMapInfo::FileMapHeader::validate() { + if (VerifySharedSpaces && compute_crc() != _crc) { + fail_continue("Header checksum verification failed."); + return false; + } + if (_version != current_version()) { FileMapInfo::fail_continue("The shared archive file is the wrong version."); return false; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/memory/filemap.hpp --- a/hotspot/src/share/vm/memory/filemap.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -61,7 +61,7 @@ bool _file_open; int _fd; - long _file_offset; + size_t _file_offset; private: static SharedClassPathEntry* _classpath_entry_table; @@ -87,12 +87,14 @@ } int _magic; // identify file type. + int _crc; // header crc checksum. int _version; // (from enum, above.) size_t _alignment; // how shared archive should be aligned int _obj_alignment; // value of ObjectAlignmentInBytes struct space_info { - int _file_offset; // sizeof(this) rounded to vm page size + int _crc; // crc checksum of the current space + size_t _file_offset; // sizeof(this) rounded to vm page size char* _base; // copy-on-write base address size_t _capacity; // for validity checking size_t _used; // for setting space top on read @@ -135,6 +137,7 @@ virtual bool validate(); virtual void populate(FileMapInfo* info, size_t alignment); + int compute_crc(); }; FileMapHeader * _header; @@ -153,6 +156,8 @@ ~FileMapInfo(); static int current_version() { return _current_version; } + int compute_header_crc() { return _header->compute_crc(); } + void set_header_crc(int crc) { _header->_crc = crc; } void populate_header(size_t alignment); bool validate_header(); void invalidate(); @@ -181,6 +186,7 @@ void write_bytes_aligned(const void* buffer, int count); char* map_region(int i); void unmap_region(int i); + bool verify_region_checksum(int i); void close(); bool is_open() { return _file_open; } ReservedSpace reserve_shared_memory(); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/memory/metaspaceShared.cpp --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -608,6 +608,7 @@ // Pass 2 - write data. mapinfo->open_for_write(); + mapinfo->set_header_crc(mapinfo->compute_header_crc()); mapinfo->write_header(); mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true); mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false); @@ -937,9 +938,13 @@ // Map each shared region if ((_ro_base = mapinfo->map_region(ro)) != NULL && + mapinfo->verify_region_checksum(ro) && (_rw_base = mapinfo->map_region(rw)) != NULL && + mapinfo->verify_region_checksum(rw) && (_md_base = mapinfo->map_region(md)) != NULL && + mapinfo->verify_region_checksum(md) && (_mc_base = mapinfo->map_region(mc)) != NULL && + mapinfo->verify_region_checksum(mc) && (image_alignment == (size_t)max_alignment()) && mapinfo->validate_classpath_entry_table()) { // Success (no need to do anything) diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/oops/arrayKlass.cpp --- a/hotspot/src/share/vm/oops/arrayKlass.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -64,6 +64,13 @@ return NULL; } +// find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined +Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { + // There are no fields in an array klass but look to the super class (Object) + assert(super(), "super klass must be present"); + return super()->find_field(name, sig, fd); +} + Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { // There are no methods in an array klass but the super class (Object) has some assert(super(), "super klass must be present"); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/oops/arrayKlass.hpp --- a/hotspot/src/share/vm/oops/arrayKlass.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -28,6 +28,7 @@ #include "memory/universe.hpp" #include "oops/klass.hpp" +class fieldDescriptor; class klassVtable; // ArrayKlass is the abstract baseclass for all array classes @@ -77,6 +78,9 @@ virtual oop multi_allocate(int rank, jint* sizes, TRAPS); objArrayOop allocate_arrayArray(int n, int length, TRAPS); + // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined + Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; + // Lookup operations Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -130,6 +130,15 @@ return is_subclass_of(k); } +Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { +#ifdef ASSERT + tty->print_cr("Error: find_field called on a klass oop." + " Likely error: reflection method does not correctly" + " wrap return value in a mirror object."); +#endif + ShouldNotReachHere(); + return NULL; +} Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { #ifdef ASSERT diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/oops/klass.hpp --- a/hotspot/src/share/vm/oops/klass.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/oops/klass.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -62,6 +62,7 @@ class klassVtable; class ParCompactionManager; class KlassSizeStats; +class fieldDescriptor; class Klass : public Metadata { friend class VMStructs; @@ -411,6 +412,7 @@ virtual void initialize(TRAPS); // lookup operation for MethodLookupCache friend class MethodLookupCache; + virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const; virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; public: Method* lookup_method(Symbol* name, Symbol* signature) const { diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -1153,12 +1153,18 @@ assert(s == start(), ""); } +/** + * Return the 'StartNode'. We must not have a pending failure, since the ideal graph + * can be in an inconsistent state, i.e., we can get segmentation faults when traversing + * the ideal graph. + */ StartNode* Compile::start() const { - assert(!failing(), ""); + assert (!failing(), err_msg_res("Must not have pending failure. Reason is: %s", failure_reason())); for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) { Node* start = root()->fast_out(i); - if( start->is_Start() ) + if (start->is_Start()) { return start->as_Start(); + } } fatal("Did not find Start node!"); return NULL; diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/opto/compile.hpp --- a/hotspot/src/share/vm/opto/compile.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -707,12 +707,15 @@ void sort_expensive_nodes(); // Compilation environment. - Arena* comp_arena() { return &_comp_arena; } - ciEnv* env() const { return _env; } - CompileLog* log() const { return _log; } - bool failing() const { return _env->failing() || _failure_reason != NULL; } - const char* failure_reason() { return _failure_reason; } - bool failure_reason_is(const char* r) { return (r==_failure_reason) || (r!=NULL && _failure_reason!=NULL && strcmp(r, _failure_reason)==0); } + Arena* comp_arena() { return &_comp_arena; } + ciEnv* env() const { return _env; } + CompileLog* log() const { return _log; } + bool failing() const { return _env->failing() || _failure_reason != NULL; } + const char* failure_reason() const { return (_env->failing()) ? _env->failure_reason() : _failure_reason; } + + bool failure_reason_is(const char* r) const { + return (r == _failure_reason) || (r != NULL && _failure_reason != NULL && strcmp(r, _failure_reason) == 0); + } void record_failure(const char* reason); void record_method_not_compilable(const char* reason, bool all_tiers = false) { diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/opto/doCall.cpp --- a/hotspot/src/share/vm/opto/doCall.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -802,10 +802,16 @@ // each arm of the Phi. If I know something clever about the exceptions // I'm loading the class from, I can replace the LoadKlass with the // klass constant for the exception oop. - if( ex_node->is_Phi() ) { - ex_klass_node = new PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT ); - for( uint i = 1; i < ex_node->req(); i++ ) { - Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() ); + if (ex_node->is_Phi()) { + ex_klass_node = new PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT); + for (uint i = 1; i < ex_node->req(); i++) { + Node* ex_in = ex_node->in(i); + if (ex_in == top() || ex_in == NULL) { + // This path was not taken. + ex_klass_node->init_req(i, top()); + continue; + } + Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes()); Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); ex_klass_node->init_req( i, k ); } diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -805,6 +805,7 @@ return (jclass) JNIHandles::make_local(env, k->java_mirror()); JVM_END +// Not used; JVM_FindClassFromCaller replaces this. JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError)) @@ -831,6 +832,42 @@ return result; JVM_END +// Find a class with this name in this loader, using the caller's protection domain. +JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name, + jboolean init, jobject loader, + jclass caller)) + JVMWrapper2("JVM_FindClassFromCaller %s throws ClassNotFoundException", name); + // Java libraries should ensure that name is never null... + if (name == NULL || (int)strlen(name) > Symbol::max_length()) { + // It's impossible to create this class; the name cannot fit + // into the constant pool. + THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name); + } + + TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); + + oop loader_oop = JNIHandles::resolve(loader); + oop from_class = JNIHandles::resolve(caller); + oop protection_domain = NULL; + // If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get + // NPE. Put it in another way, the bootstrap class loader has all permission and + // thus no checkPackageAccess equivalence in the VM class loader. + // The caller is also passed as NULL by the java code if there is no security + // manager to avoid the performance cost of getting the calling class. + if (from_class != NULL && loader_oop != NULL) { + protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain(); + } + + Handle h_loader(THREAD, loader_oop); + Handle h_prot(THREAD, protection_domain); + jclass result = find_class_from_class_loader(env, h_name, init, h_loader, + h_prot, false, THREAD); + + if (TraceClassResolution && result != NULL) { + trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); + } + return result; +JVM_END JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from)) @@ -1073,17 +1110,6 @@ JVM_END -JVM_ENTRY(jobject, JVM_GetClassLoader(JNIEnv *env, jclass cls)) - JVMWrapper("JVM_GetClassLoader"); - if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { - return NULL; - } - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); - oop loader = k->class_loader(); - return JNIHandles::make_local(env, loader); -JVM_END - - JVM_QUICK_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) JVMWrapper("JVM_IsInterface"); oop mirror = JNIHandles::resolve_non_null(cls); @@ -3932,10 +3958,15 @@ // Shared JNI/JVM entry points ////////////////////////////////////////////////////////////// -jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) { +jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, + Handle loader, Handle protection_domain, + jboolean throwError, TRAPS) { // Security Note: // The Java level wrapper will perform the necessary security check allowing - // us to pass the NULL as the initiating class loader. + // us to pass the NULL as the initiating class loader. The VM is responsible for + // the checkPackageAccess relative to the initiating class loader via the + // protection_domain. The protection_domain is passed as NULL by the java code + // if there is no security manager in 3-arg Class.forName(). Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL); KlassHandle klass_handle(THREAD, klass); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 20:04:43 2017 +0200 @@ -420,6 +420,19 @@ JVM_FindClassFromBootLoader(JNIEnv *env, const char *name); /* + * Find a class from a given class loader. Throws ClassNotFoundException. + * name: name of class + * init: whether initialization is done + * loader: class loader to look up the class. This may not be the same as the caller's + * class loader. + * caller: initiating class. The initiating class may be null when a security + * manager is not installed. + */ +JNIEXPORT jclass JNICALL +JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init, + jobject loader, jclass caller); + +/* * Find a class from a given class. */ JNIEXPORT jclass JNICALL @@ -462,9 +475,6 @@ JNIEXPORT jobjectArray JNICALL JVM_GetClassInterfaces(JNIEnv *env, jclass cls); -JNIEXPORT jobject JNICALL -JVM_GetClassLoader(JNIEnv *env, jclass cls); - JNIEXPORT jboolean JNICALL JVM_IsInterface(JNIEnv *env, jclass cls); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -3836,6 +3836,11 @@ return JNI_ENOMEM; } + // Set up VerifySharedSpaces + if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) { + VerifySharedSpaces = true; + } + // Delay warning until here so that we've had a chance to process // the -XX:-PrintWarnings flag if (needs_hotspotrc_warning) { diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -1177,11 +1177,11 @@ "When true prevents OS-level spurious, or premature, wakeups " \ "from Object.wait (Ignored for Windows)") \ \ - product(intx, NativeMonitorTimeout, -1, "(Unstable)") \ - \ - product(intx, NativeMonitorFlags, 0, "(Unstable)") \ - \ - product(intx, NativeMonitorSpinLimit, 20, "(Unstable)") \ + experimental(intx, NativeMonitorTimeout, -1, "(Unstable)") \ + \ + experimental(intx, NativeMonitorFlags, 0, "(Unstable)") \ + \ + experimental(intx, NativeMonitorSpinLimit, 20, "(Unstable)") \ \ develop(bool, UsePthreads, false, \ "Use pthread-based instead of libthread-based synchronization " \ @@ -3790,6 +3790,10 @@ product(bool, UseSharedSpaces, true, \ "Use shared spaces for metadata") \ \ + product(bool, VerifySharedSpaces, false, \ + "Verify shared spaces (false for default archive, true for " \ + "archive specified by -XX:SharedArchiveFile)") \ + \ product(bool, RequireSharedSpaces, false, \ "Require shared spaces for metadata") \ \ diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/runtime/perfMemory.hpp --- a/hotspot/src/share/vm/runtime/perfMemory.hpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/runtime/perfMemory.hpp Wed Jul 05 20:04:43 2017 +0200 @@ -155,9 +155,6 @@ } } - // filename of backing store or NULL if none. - static char* backing_store_filename(); - // returns the complete file path of hsperfdata. // the caller is expected to free the allocated memory. static char* get_perfdata_file_path(); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/runtime/reflection.cpp --- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -507,7 +507,8 @@ if (access.is_protected()) { if (!protected_restriction) { // See if current_class (or outermost host class) is a subclass of field_class - if (host_class->is_subclass_of(field_class)) { + // An interface may not access protected members of j.l.Object + if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) { if (access.is_static() || // static fields are ok, see 6622385 current_class == resolved_class || field_class == resolved_class || diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/src/share/vm/runtime/sweeper.cpp --- a/hotspot/src/share/vm/runtime/sweeper.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/src/share/vm/runtime/sweeper.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -540,17 +540,25 @@ // If there are no current activations of this method on the // stack we can safely convert it to a zombie method if (nm->can_not_entrant_be_converted()) { - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); - } // Clear ICStubs to prevent back patching stubs of zombie or unloaded // nmethods during the next safepoint (see ICStub::finalize). - MutexLocker cl(CompiledIC_lock); - nm->clear_ic_stubs(); - // Code cache state change is tracked in make_zombie() - nm->make_zombie(); - _zombified_count++; - SWEEP(nm); + { + MutexLocker cl(CompiledIC_lock); + nm->clear_ic_stubs(); + } + // Acquiring the CompiledIC_lock may block for a safepoint and set the + // nmethod to zombie (see 'CodeCache::make_marked_nmethods_zombies'). + // Check if nmethod is still non-entrant at this point. + if (nm->is_not_entrant()) { + if (PrintMethodFlushing && Verbose) { + tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); + } + // Code cache state change is tracked in make_zombie() + nm->make_zombie(); + _zombified_count++; + SWEEP(nm); + } + assert(nm->is_zombie(), "nmethod must be zombie"); } else { // Still alive, clean up its inline caches MutexLocker cl(CompiledIC_lock); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/test/TEST.groups Wed Jul 05 20:04:43 2017 +0200 @@ -447,7 +447,7 @@ compiler/codegen/ \ compiler/cpuflags/RestoreMXCSR.java \ compiler/EscapeAnalysis/ \ - compiler/exceptions/TestRecursiveReplacedException.java \ + compiler/exceptions/ \ compiler/floatingpoint/ModNaN.java \ compiler/gcbarriers/G1CrashTest.java \ compiler/inlining/ \ diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java --- a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java Thu Oct 16 14:55:17 2014 -0700 +++ b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java Wed Jul 05 20:04:43 2017 +0200 @@ -38,22 +38,26 @@ private static void verifySegmentedCodeCache(ProcessBuilder pb, boolean enabled) throws Exception { OutputAnalyzer out = new OutputAnalyzer(pb.start()); + out.shouldHaveExitValue(0); if (enabled) { try { // Non-nmethod code heap should be always available with the segmented code cache out.shouldContain(NON_METHOD); } catch (RuntimeException e) { - // TieredCompilation is disabled in a client VM - out.shouldContain("TieredCompilation is disabled in this release."); + // Check if TieredCompilation is disabled (in a client VM) + if(!out.getOutput().contains("TieredCompilation is disabled in this release.")) { + // Code cache is not segmented + throw new RuntimeException("No code cache segmentation."); + } } } else { out.shouldNotContain(NON_METHOD); } - out.shouldHaveExitValue(0); } private static void verifyCodeHeapNotExists(ProcessBuilder pb, String... heapNames) throws Exception { OutputAnalyzer out = new OutputAnalyzer(pb.start()); + out.shouldHaveExitValue(0); for (String name : heapNames) { out.shouldNotContain(name); } @@ -86,6 +90,10 @@ "-XX:ReservedCodeCacheSize=240m", "-XX:+PrintCodeCache", "-version"); verifySegmentedCodeCache(pb, true); + pb = ProcessTools.createJavaProcessBuilder("-XX:+TieredCompilation", + "-XX:ReservedCodeCacheSize=400m", + "-XX:+PrintCodeCache", "-version"); + verifySegmentedCodeCache(pb, true); // Always enabled if SegmentedCodeCache is set pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache", @@ -100,12 +108,13 @@ "-Xint", "-XX:+PrintCodeCache", "-version"); verifyCodeHeapNotExists(pb, PROFILED, NON_PROFILED); + + // If we stop compilation at CompLevel_none or CompLevel_simple we + // don't need a profiled code heap. pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache", "-XX:TieredStopAtLevel=0", "-XX:+PrintCodeCache", "-version"); - verifyCodeHeapNotExists(pb, PROFILED, NON_PROFILED); - - // If we stop compilation at CompLevel_simple + verifyCodeHeapNotExists(pb, PROFILED); pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache", "-XX:TieredStopAtLevel=1", "-XX:+PrintCodeCache", "-version"); diff -r d1480cb49283 -r 98b357b2e8a6 hotspot/test/compiler/exceptions/CatchInlineExceptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/exceptions/CatchInlineExceptions.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8059299 + * @summary assert(adr_type != NULL) failed: expecting TypeKlassPtr + * @run main/othervm -Xbatch CatchInlineExceptions + */ + +class Exception1 extends Exception {}; +class Exception2 extends Exception {}; + +public class CatchInlineExceptions { + private static int counter0; + private static int counter1; + private static int counter2; + private static int counter; + + static void foo(int i) throws Exception { + if ((i & 1023) == 2) { + counter0++; + throw new Exception2(); + } + } + + static void test(int i) throws Exception { + try { + foo(i); + } + catch (Exception e) { + if (e instanceof Exception1) { + counter1++; + } else if (e instanceof Exception2) { + counter2++; + } + counter++; + throw e; + } + } + + public static void main(String[] args) throws Throwable { + for (int i = 0; i < 15000; i++) { + try { + test(i); + } catch (Exception e) { + // expected + } + } + if (counter1 != 0) { + throw new RuntimeException("Failed: counter1(" + counter1 + ") != 0"); + } + if (counter2 != counter) { + throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter0(" + counter0 + ")"); + } + if (counter2 != counter) { + throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter(" + counter + ")"); + } + System.out.println("TEST PASSED"); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/.hgtags --- a/jaxp/.hgtags Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/.hgtags Wed Jul 05 20:04:43 2017 +0200 @@ -277,3 +277,4 @@ b940ca3d2c7e8a279ca850706b89c2ad3a841e82 jdk9-b32 46b360454dadbb329d42c59bb8192daeb9d59875 jdk9-b33 6b343b9b7a7008f5f699a2d99881163cab7a2986 jdk9-b34 +b9370464572fc663a38956047aa612d6e7854c3d jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -51,8 +51,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; -import java.util.Vector; -import javax.xml.XMLConstants; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMErrorHandler; import org.w3c.dom.DOMException; @@ -976,41 +974,40 @@ */ public DOMStringList getParameterNames() { if (fRecognizedParameters == null){ - Vector parameters = new Vector(); + ArrayList parameters = new ArrayList(); - //Add DOM recognized parameters - //REVISIT: Would have been nice to have a list of - //recognized paramters. - parameters.add(Constants.DOM_COMMENTS); - parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); - parameters.add(Constants.DOM_CDATA_SECTIONS); - parameters.add(Constants.DOM_ENTITIES); - parameters.add(Constants.DOM_SPLIT_CDATA); - parameters.add(Constants.DOM_NAMESPACES); - parameters.add(Constants.DOM_VALIDATE); + //Add DOM recognized parameters + //REVISIT: Would have been nice to have a list of + //recognized paramters. + parameters.add(Constants.DOM_COMMENTS); + parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); + parameters.add(Constants.DOM_CDATA_SECTIONS); + parameters.add(Constants.DOM_ENTITIES); + parameters.add(Constants.DOM_SPLIT_CDATA); + parameters.add(Constants.DOM_NAMESPACES); + parameters.add(Constants.DOM_VALIDATE); - parameters.add(Constants.DOM_INFOSET); - parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); - parameters.add(Constants.DOM_CANONICAL_FORM); - parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); - parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); - parameters.add(Constants.DOM_WELLFORMED); + parameters.add(Constants.DOM_INFOSET); + parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); + parameters.add(Constants.DOM_CANONICAL_FORM); + parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); + parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); + parameters.add(Constants.DOM_WELLFORMED); - parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); - parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); + parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); + parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); - parameters.add(Constants.DOM_ERROR_HANDLER); - parameters.add(Constants.DOM_SCHEMA_TYPE); - parameters.add(Constants.DOM_SCHEMA_LOCATION); - parameters.add(Constants.DOM_RESOURCE_RESOLVER); + parameters.add(Constants.DOM_ERROR_HANDLER); + parameters.add(Constants.DOM_SCHEMA_TYPE); + parameters.add(Constants.DOM_SCHEMA_LOCATION); + parameters.add(Constants.DOM_RESOURCE_RESOLVER); - //Add recognized xerces features and properties - parameters.add(GRAMMAR_POOL); - parameters.add(SYMBOL_TABLE); - parameters.add(SEND_PSVI); + //Add recognized xerces features and properties + parameters.add(GRAMMAR_POOL); + parameters.add(SYMBOL_TABLE); + parameters.add(SEND_PSVI); - fRecognizedParameters = new DOMStringListImpl(parameters); - + fRecognizedParameters = new DOMStringListImpl(parameters); } return fRecognizedParameters; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIAttrNSImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIAttrNSImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIAttrNSImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,10 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,14 +17,16 @@ package com.sun.org.apache.xerces.internal.dom; +import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; +import com.sun.org.apache.xerces.internal.impl.xs.AttributePSVImpl; +import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; +import com.sun.org.apache.xerces.internal.xs.*; +import com.sun.org.apache.xerces.internal.xs.AttributePSVI; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import com.sun.org.apache.xerces.internal.xs.AttributePSVI; -import com.sun.org.apache.xerces.internal.xs.*; - /** * Attribute namespace implementation; stores PSVI attribute items. * @@ -67,20 +66,8 @@ * value in the original document, this is true; otherwise, it is false */ protected boolean fSpecified = true; - /** schema normalized value property */ - protected String fNormalizedValue = null; - - /** schema actual value */ - protected Object fActualValue = null; - - /** schema actual value type */ - protected short fActualValueType = XSConstants.UNAVAILABLE_DT; - - /** actual value types if the value is a list */ - protected ShortList fItemValueTypes = null; - - /** member type definition against which attribute was validated */ - protected XSSimpleTypeDefinition fMemberType = null; + /** Schema value */ + protected ValidatedInfo fValue = new ValidatedInfo(); /** validation attempted: none, partial, full */ protected short fValidationAttempted = AttributePSVI.VALIDATION_NONE; @@ -91,6 +78,9 @@ /** error codes */ protected StringList fErrorCodes = null; + /** error messages */ + protected StringList fErrorMessages = null; + /** validation context: could be QName or XPath expression*/ protected String fValidationContext = null; @@ -98,6 +88,20 @@ // AttributePSVI methods // + /* (non-Javadoc) + * @see org.apache.xerces.xs.ItemPSVI#constant() + */ + public ItemPSVI constant() { + return new AttributePSVImpl(true, this); + } + + /* (non-Javadoc) + * @see org.apache.xerces.xs.ItemPSVI#isConstant() + */ + public boolean isConstant() { + return false; + } + /** * [schema default] * @@ -116,7 +120,7 @@ * @return the normalized value of this item after validation */ public String getSchemaNormalizedValue() { - return fNormalizedValue; + return fValue.getNormalizedValue(); } /** @@ -157,7 +161,23 @@ * @return list of error codes */ public StringList getErrorCodes() { - return fErrorCodes; + if (fErrorCodes != null) { + return fErrorCodes; + } + return StringListImpl.EMPTY_LIST; + } + + /** + * A list of error messages generated from the validation attempt or + * an empty StringList if no errors occurred during the + * validation attempt. The indices of error messages in this list are + * aligned with those in the [schema error code] list. + */ + public StringList getErrorMessages() { + if (fErrorMessages != null) { + return fErrorMessages; + } + return StringListImpl.EMPTY_LIST; } // This is the only information we can provide in a pipeline. @@ -177,14 +197,14 @@ /** * If and only if that type definition is a simple type definition * with {variety} union, or a complex type definition whose {content type} - * is a simple thype definition with {variety} union, then an item isomorphic + * is a simple type definition with {variety} union, then an item isomorphic * to that member of the union's {member type definitions} which actually * validated the element item's normalized value. * * @return a simple type declaration */ public XSSimpleTypeDefinition getMemberTypeDefinition() { - return fMemberType; + return fValue.getMemberTypeDefinition(); } /** @@ -208,12 +228,9 @@ this.fValidity = attr.getValidity(); this.fValidationAttempted = attr.getValidationAttempted(); this.fErrorCodes = attr.getErrorCodes(); - this.fNormalizedValue = attr.getSchemaNormalizedValue(); - this.fActualValue = attr.getActualNormalizedValue(); - this.fActualValueType = attr.getActualNormalizedValueType(); - this.fItemValueTypes = attr.getItemValueTypes(); + this.fErrorMessages = attr.getErrorMessages(); + this.fValue.copyFrom(attr.getSchemaValue()); this.fTypeDecl = attr.getTypeDefinition(); - this.fMemberType = attr.getMemberTypeDefinition(); this.fSpecified = attr.getIsSchemaSpecified(); } @@ -221,21 +238,28 @@ * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue() */ public Object getActualNormalizedValue() { - return this.fActualValue; + return fValue.getActualValue(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType() */ public short getActualNormalizedValueType() { - return this.fActualValueType; + return fValue.getActualValueType(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes() */ public ShortList getItemValueTypes() { - return this.fItemValueTypes; + return fValue.getListValueTypes(); + } + + /* (non-Javadoc) + * @see org.apache.xerces.xs.ItemPSVI#getSchemaValue() + */ + public XSValue getSchemaValue() { + return fValue; } // REVISIT: Forbid serialization of PSVI DOM until diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIElementNSImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIElementNSImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIElementNSImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,10 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,14 +17,16 @@ package com.sun.org.apache.xerces.internal.dom; +import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; +import com.sun.org.apache.xerces.internal.impl.xs.ElementPSVImpl; +import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; +import com.sun.org.apache.xerces.internal.xs.*; +import com.sun.org.apache.xerces.internal.xs.ElementPSVI; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import com.sun.org.apache.xerces.internal.xs.ElementPSVI; -import com.sun.org.apache.xerces.internal.xs.*; - /** * Element namespace implementation; stores PSVI element items. * @@ -72,24 +71,12 @@ */ protected boolean fSpecified = true; - /** schema normalized value property */ - protected String fNormalizedValue = null; - - /** schema actual value */ - protected Object fActualValue = null; - - /** schema actual value type */ - protected short fActualValueType = XSConstants.UNAVAILABLE_DT; - - /** actual value types if the value is a list */ - protected ShortList fItemValueTypes = null; + /** Schema value */ + protected ValidatedInfo fValue = new ValidatedInfo(); /** http://www.w3.org/TR/xmlschema-1/#e-notation*/ protected XSNotationDeclaration fNotation = null; - /** member type definition against which element was validated */ - protected XSSimpleTypeDefinition fMemberType = null; - /** validation attempted: none, partial, full */ protected short fValidationAttempted = ElementPSVI.VALIDATION_NONE; @@ -99,6 +86,9 @@ /** error codes */ protected StringList fErrorCodes = null; + /** error messages */ + protected StringList fErrorMessages = null; + /** validation context: could be QName or XPath expression*/ protected String fValidationContext = null; @@ -109,6 +99,20 @@ // ElementPSVI methods // + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#constant() + */ + public ItemPSVI constant() { + return new ElementPSVImpl(true, this); + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#isConstant() + */ + public boolean isConstant() { + return false; + } + /** * [schema default] * @@ -127,7 +131,7 @@ * @return the normalized value of this item after validation */ public String getSchemaNormalizedValue() { - return fNormalizedValue; + return fValue.getNormalizedValue(); } /** @@ -167,9 +171,24 @@ * @return Array of error codes */ public StringList getErrorCodes() { - return fErrorCodes; + if (fErrorCodes != null) { + return fErrorCodes; + } + return StringListImpl.EMPTY_LIST; } + /** + * A list of error messages generated from the validation attempt or + * an empty StringList if no errors occurred during the + * validation attempt. The indices of error messages in this list are + * aligned with those in the [schema error code] list. + */ + public StringList getErrorMessages() { + if (fErrorMessages != null) { + return fErrorMessages; + } + return StringListImpl.EMPTY_LIST; + } // This is the only information we can provide in a pipeline. public String getValidationContext() { @@ -213,7 +232,7 @@ * @return a simple type declaration */ public XSSimpleTypeDefinition getMemberTypeDefinition() { - return fMemberType; + return fValue.getMemberTypeDefinition(); } /** @@ -239,7 +258,7 @@ /** * Copy PSVI properties from another psvi item. * - * @param attr the source of attribute PSVI items + * @param elem the source of element PSVI items */ public void setPSVI(ElementPSVI elem) { this.fDeclaration = elem.getElementDeclaration(); @@ -250,11 +269,15 @@ this.fValidity = elem.getValidity(); this.fValidationAttempted = elem.getValidationAttempted(); this.fErrorCodes = elem.getErrorCodes(); - this.fNormalizedValue = elem.getSchemaNormalizedValue(); - this.fActualValue = elem.getActualNormalizedValue(); - this.fActualValueType = elem.getActualNormalizedValueType(); - this.fItemValueTypes = elem.getItemValueTypes(); - this.fMemberType = elem.getMemberTypeDefinition(); + this.fErrorMessages = elem.getErrorMessages(); + if (fTypeDecl instanceof XSSimpleTypeDefinition || + fTypeDecl instanceof XSComplexTypeDefinition && + ((XSComplexTypeDefinition)fTypeDecl).getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE) { + this.fValue.copyFrom(elem.getSchemaValue()); + } + else { + this.fValue.reset(); + } this.fSpecified = elem.getIsSchemaSpecified(); this.fNil = elem.getNil(); } @@ -263,21 +286,28 @@ * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue() */ public Object getActualNormalizedValue() { - return this.fActualValue; + return fValue.getActualValue(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType() */ public short getActualNormalizedValueType() { - return this.fActualValueType; + return fValue.getActualValueType(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes() */ public ShortList getItemValueTypes() { - return this.fItemValueTypes; + return fValue.getListValueTypes(); + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getSchemaValue() + */ + public XSValue getSchemaValue() { + return fValue; } // REVISIT: Forbid serialization of PSVI DOM until diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,3 +1,6 @@ +/* + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -632,9 +635,12 @@ /** Validation manager property ("internal/validation-manager"). */ public static final String VALIDATION_MANAGER_PROPERTY = "internal/validation-manager"; - /** Schema type of the root element in a document ("validation/schema/root-type-definition"). */ + /** Schema type for the root element in a document ("validation/schema/root-type-definition"). */ public static final String ROOT_TYPE_DEFINITION_PROPERTY = "validation/schema/root-type-definition"; + /** Schema element declaration for the root element in a document ("validation/schema/root-element-declaration"). */ + public static final String ROOT_ELEMENT_DECLARATION_PROPERTY = "validation/schema/root-element-declaration"; + /** XPointer Schema property ("xpointer-schema"). */ public static final String XPOINTER_SCHEMA_PROPERTY = "xpointer-schema"; @@ -803,6 +809,7 @@ BUFFER_SIZE_PROPERTY, SECURITY_MANAGER_PROPERTY, ROOT_TYPE_DEFINITION_PROPERTY, + ROOT_ELEMENT_DECLARATION_PROPERTY, LOCALE_PROPERTY, SCHEMA_DV_FACTORY_PROPERTY, }; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -611,9 +611,9 @@ //fElementStack2.clear(); //fReplaceEntityReferences = true; //fSupportExternalEntities = true; - Boolean bo = (Boolean)propertyManager.getProperty(XMLInputFactoryImpl.IS_REPLACING_ENTITY_REFERENCES); + Boolean bo = (Boolean)propertyManager.getProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES); fReplaceEntityReferences = bo.booleanValue(); - bo = (Boolean)propertyManager.getProperty(XMLInputFactoryImpl.IS_SUPPORTING_EXTERNAL_ENTITIES); + bo = (Boolean)propertyManager.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES); fSupportExternalEntities = bo.booleanValue(); Boolean cdata = (Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.STAX_REPORT_CDATA_EVENT) ; if(cdata != null) diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,11 +21,11 @@ package com.sun.org.apache.xerces.internal.impl ; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; -import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.util.*; import com.sun.org.apache.xerces.internal.util.URI; @@ -54,6 +53,7 @@ import java.util.Map; import java.util.Stack; import java.util.StringTokenizer; +import javax.xml.stream.XMLInputFactory; /** @@ -305,6 +305,11 @@ /** Property Manager. This is used from Stax */ protected PropertyManager fPropertyManager ; + /** StAX properties */ + boolean fSupportDTD = true; + boolean fReplaceEntityReferences = true; + boolean fSupportExternalEntities = true; + /** used to restrict external access */ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT; @@ -1136,7 +1141,8 @@ boolean parameter = entityName.startsWith("%"); boolean general = !parameter; if (unparsed || (general && !fExternalGeneralEntities) || - (parameter && !fExternalParameterEntities)) { + (parameter && !fExternalParameterEntities) || + !fSupportDTD || !fSupportExternalEntities) { if (fEntityHandler != null) { fResourceIdentifier.clear(); @@ -1431,6 +1437,10 @@ fStaxEntityResolver = null; } + fSupportDTD = ((Boolean)propertyManager.getProperty(XMLInputFactory.SUPPORT_DTD)).booleanValue(); + fReplaceEntityReferences = ((Boolean)propertyManager.getProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES)).booleanValue(); + fSupportExternalEntities = ((Boolean)propertyManager.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES)).booleanValue(); + // Zephyr feature ignore-external-dtd is the opposite of Xerces' load-external-dtd fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue(); @@ -1502,6 +1512,11 @@ fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); entityExpansionIndex = fSecurityManager.getIndex(Constants.JDK_ENTITY_EXPANSION_LIMIT); + //StAX Property + fSupportDTD = true; + fReplaceEntityReferences = true; + fSupportExternalEntities = true; + // JAXP 1.5 feature XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); if (spm == null) { diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLErrorReporter.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLErrorReporter.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLErrorReporter.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,60 +3,20 @@ * DO NOT REMOVE OR ALTER! */ /* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999-2004 The Apache Software Foundation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * . + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.sun.org.apache.xerces.internal.impl; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -51,6 +52,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; +import java.util.Iterator; /** * The DTD validator. The validator implements a document @@ -334,7 +336,7 @@ // temporary variables /** Temporary element declaration. */ - private XMLElementDecl fTempElementDecl = new XMLElementDecl(); + private final XMLElementDecl fTempElementDecl = new XMLElementDecl(); /** Temporary atribute declaration. */ private final XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl(); @@ -2020,12 +2022,14 @@ // IDREF and IDREFS attr (V_IDREF0) // if (fPerformValidation) { - String value = fValidationState.checkIDRefID(); - if (value != null) { - fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN, - "MSG_ELEMENT_WITH_ID_REQUIRED", - new Object[]{value}, - XMLErrorReporter.SEVERITY_ERROR ); + Iterator invIdRefs = fValidationState.checkIDRefID(); + if (invIdRefs != null) { + while (invIdRefs.hasNext()) { + fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN, + "MSG_ELEMENT_WITH_ID_REQUIRED", + new Object[]{invIdRefs.next()}, + XMLErrorReporter.SEVERITY_ERROR ); + } } } return; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/models/CMNode.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/models/CMNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/models/CMNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,62 +1,21 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. */ /* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999-2002 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * . + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.sun.org.apache.xerces.internal.impl.dtd.models; @@ -125,6 +84,14 @@ fMaxStates = maxStates; } + public boolean isCompactedForUPA() { + return fCompactedForUPA; + } + + public void setIsCompactUPAModel(boolean value) { + fCompactedForUPA = value; + } + /** * Allows the user to set arbitrary data on this content model * node. This is used by the a{n,m} optimization that runs @@ -181,10 +148,16 @@ // init to to -1 so it will cause an error if its used without // being initialized. // ------------------------------------------------------------------- - private int fType; - private CMStateSet fFirstPos = null; - private CMStateSet fFollowPos = null; - private CMStateSet fLastPos = null; - private int fMaxStates = -1; + private final int fType; + private CMStateSet fFirstPos = null; + private CMStateSet fFollowPos = null; + private CMStateSet fLastPos = null; + private int fMaxStates = -1; private Object fUserData = null; + /* + * This boolean is true if the model represented by the CMNode does not represent + * the true model from the schema, but has had its min/maxOccurs modified for a + * more compact representation (for purposes of UPA). + */ + private boolean fCompactedForUPA = false; }; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,3 +1,7 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -17,8 +21,13 @@ package com.sun.org.apache.xerces.internal.impl.dv; +import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl; +import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; import com.sun.org.apache.xerces.internal.xs.ShortList; import com.sun.org.apache.xerces.internal.xs.XSConstants; +import com.sun.org.apache.xerces.internal.xs.XSObjectList; +import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; +import com.sun.org.apache.xerces.internal.xs.XSValue; /** * Class to get the information back after content is validated. This info @@ -29,7 +38,7 @@ * @author Neeraj Bajaj, Sun Microsystems, inc. * */ -public class ValidatedInfo { +public class ValidatedInfo implements XSValue { /** * The normalized value of a string value @@ -51,6 +60,11 @@ public short actualValueType; /** + * The declared type of the value. + */ + public XSSimpleType actualType; + + /** * If the type is a union type, then the member type which * actually validated the string value. */ @@ -79,8 +93,11 @@ public void reset() { this.normalizedValue = null; this.actualValue = null; + this.actualValueType = XSConstants.UNAVAILABLE_DT; + this.actualType = null; this.memberType = null; this.memberTypes = null; + this.itemValueTypes = null; } /** @@ -88,10 +105,12 @@ * value, use toString; otherwise, use the normalized value. */ public String stringValue() { - if (actualValue == null) + if (actualValue == null) { return normalizedValue; - else + } + else { return actualValue.toString(); + } } /** @@ -149,4 +168,72 @@ /** Other types. */ return valueType; } + + // XSValue methods + + public Object getActualValue() { + return actualValue; + } + + public short getActualValueType() { + return actualValueType; + } + + public ShortList getListValueTypes() { + return itemValueTypes == null ? ShortListImpl.EMPTY_LIST : itemValueTypes; + } + + public XSObjectList getMemberTypeDefinitions() { + if (memberTypes == null) { + return XSObjectListImpl.EMPTY_LIST; + } + return new XSObjectListImpl(memberTypes, memberTypes.length); + } + + public String getNormalizedValue() { + return normalizedValue; + } + + public XSSimpleTypeDefinition getTypeDefinition() { + return actualType; + } + + public XSSimpleTypeDefinition getMemberTypeDefinition() { + return memberType; + } + + public void copyFrom(XSValue o) { + if (o == null) { + reset(); + } + else if (o instanceof ValidatedInfo) { + ValidatedInfo other = (ValidatedInfo)o; + normalizedValue = other.normalizedValue; + actualValue = other.actualValue; + actualValueType = other.actualValueType; + actualType = other.actualType; + memberType = other.memberType; + memberTypes = other.memberTypes; + itemValueTypes = other.itemValueTypes; + } + else { + normalizedValue = o.getNormalizedValue(); + actualValue = o.getActualValue(); + actualValueType = o.getActualValueType(); + actualType = (XSSimpleType)o.getTypeDefinition(); + memberType = (XSSimpleType)o.getMemberTypeDefinition(); + XSSimpleType realType = memberType == null ? actualType : memberType; + if (realType != null && realType.getBuiltInKind() == XSConstants.LISTOFUNION_DT) { + XSObjectList members = o.getMemberTypeDefinitions(); + memberTypes = new XSSimpleType[members.getLength()]; + for (int i = 0; i < members.getLength(); i++) { + memberTypes[i] = (XSSimpleType)members.get(i); + } + } + else { + memberTypes = null; + } + itemValueTypes = o.getListValueTypes(); + } + } } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/util/ByteListImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/util/ByteListImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/util/ByteListImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.impl.dv.util; import java.util.AbstractList; @@ -102,4 +104,10 @@ public int size() { return getLength(); } + + public byte[] toByteArray() { + byte[] ret = new byte[data.length]; + System.arraycopy(data, 0, ret, 0, data.length); + return ret; + } } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,11 +21,6 @@ package com.sun.org.apache.xerces.internal.impl.dv.xs; -import java.util.AbstractList; -import java.util.Locale; -import java.util.StringTokenizer; -import java.util.Vector; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.dv.DatatypeException; import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException; @@ -33,9 +29,10 @@ import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext; import com.sun.org.apache.xerces.internal.impl.dv.XSFacets; import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; +import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException; import com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression; -import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException; import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; +import com.sun.org.apache.xerces.internal.impl.xs.util.ObjectListImpl; import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl; import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; @@ -48,10 +45,16 @@ import com.sun.org.apache.xerces.internal.xs.XSFacet; import com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet; import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; +import com.sun.org.apache.xerces.internal.xs.XSObject; import com.sun.org.apache.xerces.internal.xs.XSObjectList; import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList; +import java.math.BigInteger; +import java.util.AbstractList; +import java.util.Locale; +import java.util.StringTokenizer; +import java.util.Vector; import org.w3c.dom.TypeInfo; /** @@ -267,9 +270,8 @@ private int fFractionDigits = -1; private Vector fPattern; private Vector fPatternStr; - private Vector fEnumeration; - private short[] fEnumerationType; - private ShortList[] fEnumerationItemType; // used in case fenumerationType value is LIST or LISTOFUNION + private ValidatedInfo[] fEnumeration; + private int fEnumerationSize; private ShortList fEnumerationTypeList; private ObjectList fEnumerationItemTypeList; private StringList fLexicalPattern; @@ -387,8 +389,7 @@ fPattern = fBase.fPattern; fPatternStr = fBase.fPatternStr; fEnumeration = fBase.fEnumeration; - fEnumerationType = fBase.fEnumerationType; - fEnumerationItemType = fBase.fEnumerationItemType; + fEnumerationSize = fBase.fEnumerationSize; fWhiteSpace = fBase.fWhiteSpace; fMaxExclusive = fBase.fMaxExclusive; fMaxInclusive = fBase.fMaxInclusive; @@ -508,8 +509,7 @@ fPattern = fBase.fPattern; fPatternStr = fBase.fPatternStr; fEnumeration = fBase.fEnumeration; - fEnumerationType = fBase.fEnumerationType; - fEnumerationItemType = fBase.fEnumerationItemType; + fEnumerationSize = fBase.fEnumerationSize; fWhiteSpace = fBase.fWhiteSpace; fMaxExclusive = fBase.fMaxExclusive; fMaxInclusive = fBase.fMaxInclusive; @@ -873,22 +873,20 @@ if ((allowedFacet & FACET_ENUMERATION) == 0) { reportError("cos-applicable-facets", new Object[]{"enumeration", fTypeName}); } else { - fEnumeration = new Vector(); Vector enumVals = facets.enumeration; - fEnumerationType = new short[enumVals.size()]; - fEnumerationItemType = new ShortList[enumVals.size()]; + int size = enumVals.size(); + fEnumeration = new ValidatedInfo[size]; Vector enumNSDecls = facets.enumNSDecls; ValidationContextImpl ctx = new ValidationContextImpl(context); enumerationAnnotations = facets.enumAnnotations; - for (int i = 0; i < enumVals.size(); i++) { + fEnumerationSize = 0; + for (int i = 0; i < size; i++) { if (enumNSDecls != null) ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i)); try { - ValidatedInfo info = getActualEnumValue((String)enumVals.elementAt(i), ctx, tempInfo); + ValidatedInfo info = getActualEnumValue((String)enumVals.elementAt(i), ctx, null); // check 4.3.5.c0 must: enumeration values from the value space of base - fEnumeration.addElement(info.actualValue); - fEnumerationType[i] = info.actualValueType; - fEnumerationItemType[i] = info.itemValueTypes; + fEnumeration[fEnumerationSize++] = info; } catch (InvalidDatatypeValueException ide) { reportError("enumeration-valid-restriction", new Object[]{enumVals.elementAt(i), this.getBaseType().getName()}); } @@ -1478,6 +1476,7 @@ if ((fFacetsDefined & FACET_ENUMERATION) == 0 && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) { fFacetsDefined |= FACET_ENUMERATION; fEnumeration = fBase.fEnumeration; + fEnumerationSize = fBase.fEnumerationSize; enumerationAnnotations = fBase.enumerationAnnotations; } // inherit maxExclusive @@ -1673,16 +1672,16 @@ //enumeration if ( ((fFacetsDefined & FACET_ENUMERATION) != 0 ) ) { boolean present = false; - final int enumSize = fEnumeration.size(); + final int enumSize = fEnumerationSize; final short primitiveType1 = convertToPrimitiveKind(type); for (int i = 0; i < enumSize; i++) { - final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]); + final short primitiveType2 = convertToPrimitiveKind(fEnumeration[i].actualValueType); if ((primitiveType1 == primitiveType2 || primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT || primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT) - && fEnumeration.elementAt(i).equals(ob)) { + && fEnumeration[i].actualValue.equals(ob)) { if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) { - ShortList enumItemType = fEnumerationItemType[i]; + ShortList enumItemType = fEnumeration[i].itemValueTypes; final int typeList1Length = itemType != null ? itemType.getLength() : 0; final int typeList2Length = enumItemType != null ? enumItemType.getLength() : 0; if (typeList1Length == typeList2Length) { @@ -1711,8 +1710,10 @@ } } if(!present){ + StringBuffer sb = new StringBuffer(); + appendEnumString(sb); throw new InvalidDatatypeValueException("cvc-enumeration-valid", - new Object [] {content, fEnumeration.toString()}); + new Object [] {content, sb.toString()}); } } @@ -1827,12 +1828,6 @@ nvalue = content.toString(); } if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) { - if (fPattern.size()==0 && nvalue.length()>0) { - throw new InvalidDatatypeValueException("cvc-pattern-valid", - new Object[]{content, - "(empty string)", - fTypeName}); - } RegularExpression regex; for (int idx = fPattern.size()-1; idx >= 0; idx--) { regex = (RegularExpression)fPattern.elementAt(idx); @@ -1840,6 +1835,7 @@ throw new InvalidDatatypeValueException("cvc-pattern-valid", new Object[]{content, fPatternStr.elementAt(idx), + fTypeName}); } } @@ -1873,6 +1869,7 @@ Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context); validatedInfo.actualValue = avalue; validatedInfo.actualValueType = fBuiltInKind; + validatedInfo.actualType = this; return avalue; @@ -1910,6 +1907,8 @@ validatedInfo.memberTypes = memberTypes; validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length); validatedInfo.normalizedValue = nvalue; + // Need to set it here or it will become the item type + validatedInfo.actualType = this; return v; @@ -1929,6 +1928,8 @@ fMemberTypes[i].checkFacets(validatedInfo); } validatedInfo.memberType = fMemberTypes[i]; + // Need to set it here or it will become the member type + validatedInfo.actualType = this; return aValue; } catch(InvalidDatatypeValueException invalidValue) { } @@ -1946,14 +1947,8 @@ } typesBuffer.append(decl.fTypeName); if(decl.fEnumeration != null) { - Vector v = decl.fEnumeration; - typesBuffer.append(" : ["); - for(int j = 0;j < v.size(); j++) { - if(j != 0) - typesBuffer.append(','); - typesBuffer.append(v.elementAt(j)); - } - typesBuffer.append(']'); + typesBuffer.append(" : "); + decl.appendEnumString(typesBuffer); } } throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", @@ -2245,10 +2240,10 @@ if (fLexicalEnumeration == null){ if (fEnumeration == null) return StringListImpl.EMPTY_LIST; - int size = fEnumeration.size(); + int size = fEnumerationSize; String[] strs = new String[size]; for (int i = 0; i < size; i++) - strs[i] = fEnumeration.elementAt(i).toString(); + strs[i] = fEnumeration[i].normalizedValue; fLexicalEnumeration = new StringListImpl(strs, size); } return fLexicalEnumeration; @@ -2262,16 +2257,24 @@ if (fActualEnumeration == null) { fActualEnumeration = new AbstractObjectList() { public int getLength() { - return (fEnumeration != null) ? fEnumeration.size() : 0; + return (fEnumeration != null) ? fEnumerationSize : 0; } public boolean contains(Object item) { - return (fEnumeration != null && fEnumeration.contains(item)); + if (fEnumeration == null) { + return false; + } + for (int i = 0; i < fEnumerationSize; i++) { + if (fEnumeration[i].getActualValue().equals(item)) { + return true; + } + } + return false; } public Object item(int index) { if (index < 0 || index >= getLength()) { return null; } - return fEnumeration.elementAt(index); + return fEnumeration[index].getActualValue(); } }; } @@ -2284,17 +2287,18 @@ */ public ObjectList getEnumerationItemTypeList() { if (fEnumerationItemTypeList == null) { - if(fEnumerationItemType == null) + if (fEnumeration == null) { return null; + } fEnumerationItemTypeList = new AbstractObjectList() { public int getLength() { - return (fEnumerationItemType != null) ? fEnumerationItemType.length : 0; + return (fEnumeration != null) ? fEnumerationSize : 0; } public boolean contains(Object item) { - if(fEnumerationItemType == null || !(item instanceof ShortList)) + if (fEnumeration == null || !(item instanceof ShortList)) return false; - for(int i = 0;i < fEnumerationItemType.length; i++) - if(fEnumerationItemType[i] == item) + for (int i = 0;i < fEnumerationSize; i++) + if (fEnumeration[i].itemValueTypes == item) return true; return false; } @@ -2302,7 +2306,7 @@ if (index < 0 || index >= getLength()) { return null; } - return fEnumerationItemType[index]; + return fEnumeration[index].itemValueTypes; } }; } @@ -2311,10 +2315,14 @@ public ShortList getEnumerationTypeList() { if (fEnumerationTypeList == null) { - if (fEnumerationType == null) { + if (fEnumeration == null) { return ShortListImpl.EMPTY_LIST; } - fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length); + short[] list = new short[fEnumerationSize]; + for (int i = 0; i < fEnumerationSize; i++) { + list[i] = fEnumeration[i].actualValueType; + } + fEnumerationTypeList = new ShortListImpl(list, fEnumerationSize); } return fEnumerationTypeList; } @@ -2978,10 +2986,11 @@ fPattern = null; fPatternStr = null; fEnumeration = null; - fEnumerationType = null; - fEnumerationItemType = null; fLexicalPattern = null; fLexicalEnumeration = null; + fActualEnumeration = null; + fEnumerationTypeList = null; + fEnumerationItemTypeList = null; fMaxInclusive = null; fMaxExclusive = null; fMinExclusive = null; @@ -3043,6 +3052,8 @@ new XSFacetImpl( FACET_WHITESPACE, WS_FACET_STRING[fWhiteSpace], + 0, + null, (fFixedFacet & FACET_WHITESPACE) != 0, whiteSpaceAnnotation); count++; @@ -3052,6 +3063,8 @@ new XSFacetImpl( FACET_LENGTH, Integer.toString(fLength), + fLength, + null, (fFixedFacet & FACET_LENGTH) != 0, lengthAnnotation); count++; @@ -3061,6 +3074,8 @@ new XSFacetImpl( FACET_MINLENGTH, Integer.toString(fMinLength), + fMinLength, + null, (fFixedFacet & FACET_MINLENGTH) != 0, minLengthAnnotation); count++; @@ -3070,6 +3085,8 @@ new XSFacetImpl( FACET_MAXLENGTH, Integer.toString(fMaxLength), + fMaxLength, + null, (fFixedFacet & FACET_MAXLENGTH) != 0, maxLengthAnnotation); count++; @@ -3079,6 +3096,8 @@ new XSFacetImpl( FACET_TOTALDIGITS, Integer.toString(fTotalDigits), + fTotalDigits, + null, (fFixedFacet & FACET_TOTALDIGITS) != 0, totalDigitsAnnotation); count++; @@ -3088,6 +3107,8 @@ new XSFacetImpl( FACET_FRACTIONDIGITS, "0", + 0, + null, true, fractionDigitsAnnotation); count++; @@ -3097,6 +3118,8 @@ new XSFacetImpl( FACET_FRACTIONDIGITS, Integer.toString(fFractionDigits), + fFractionDigits, + null, (fFixedFacet & FACET_FRACTIONDIGITS) != 0, fractionDigitsAnnotation); count++; @@ -3106,6 +3129,8 @@ new XSFacetImpl( FACET_MAXINCLUSIVE, fMaxInclusive.toString(), + 0, + fMaxInclusive, (fFixedFacet & FACET_MAXINCLUSIVE) != 0, maxInclusiveAnnotation); count++; @@ -3115,6 +3140,8 @@ new XSFacetImpl( FACET_MAXEXCLUSIVE, fMaxExclusive.toString(), + 0, + fMaxExclusive, (fFixedFacet & FACET_MAXEXCLUSIVE) != 0, maxExclusiveAnnotation); count++; @@ -3124,6 +3151,8 @@ new XSFacetImpl( FACET_MINEXCLUSIVE, fMinExclusive.toString(), + 0, + fMinExclusive, (fFixedFacet & FACET_MINEXCLUSIVE) != 0, minExclusiveAnnotation); count++; @@ -3133,6 +3162,8 @@ new XSFacetImpl( FACET_MININCLUSIVE, fMinInclusive.toString(), + 0, + fMinInclusive, (fFixedFacet & FACET_MININCLUSIVE) != 0, minInclusiveAnnotation); count++; @@ -3142,6 +3173,28 @@ return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST; } + public XSObject getFacet(int facetType) { + if (facetType == FACET_ENUMERATION || facetType == FACET_PATTERN) { + XSObjectList list = getMultiValueFacets(); + for (int i = 0; i < list.getLength(); i++) { + XSMultiValueFacet f = (XSMultiValueFacet)list.item(i); + if (f.getFacetKind() == facetType) { + return f; + } + } + } + else { + XSObjectList list = getFacets(); + for (int i = 0; i < list.getLength(); i++) { + XSFacet f = (XSFacet)list.item(i); + if (f.getFacetKind() == facetType) { + return f; + } + } + } + return null; + } + /** * A list of enumeration and pattern constraining facets if it exists, * otherwise an empty XSObjectList. @@ -3162,6 +3215,7 @@ new XSMVFacetImpl( FACET_PATTERN, this.getLexicalPattern(), + null, patternAnnotations); count++; } @@ -3170,6 +3224,7 @@ new XSMVFacetImpl( FACET_ENUMERATION, this.getLexicalEnumeration(), + new ObjectListImpl(fEnumeration, fEnumerationSize), enumerationAnnotations); count++; } @@ -3201,13 +3256,17 @@ private static final class XSFacetImpl implements XSFacet { final short kind; - final String value; + final String svalue; + final int ivalue; + Object avalue; final boolean fixed; final XSObjectList annotations; - public XSFacetImpl(short kind, String value, boolean fixed, XSAnnotation annotation) { + public XSFacetImpl(short kind, String svalue, int ivalue, Object avalue, boolean fixed, XSAnnotation annotation) { this.kind = kind; - this.value = value; + this.svalue = svalue; + this.ivalue = ivalue; + this.avalue = avalue; this.fixed = fixed; if (annotation != null) { @@ -3254,7 +3313,24 @@ * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getLexicalFacetValue() */ public String getLexicalFacetValue() { - return value; + return svalue; + } + + public Object getActualFacetValue() { + if (avalue == null) { + if (kind == FACET_WHITESPACE) { + avalue = svalue; + } + else { + // Must a facet with an integer value. Use BigInteger. + avalue = BigInteger.valueOf(ivalue); + } + } + return avalue; + } + + public int getIntFacetValue() { + return ivalue; } /* (non-Javadoc) @@ -3298,11 +3374,13 @@ private static final class XSMVFacetImpl implements XSMultiValueFacet { final short kind; final XSObjectList annotations; - final StringList values; - - public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) { + final StringList svalues; + final ObjectList avalues; + + public XSMVFacetImpl(short kind, StringList svalues, ObjectList avalues, XSObjectList annotations) { this.kind = kind; - this.values = values; + this.svalues = svalues; + this.avalues = avalues; this.annotations = (annotations != null) ? annotations : XSObjectListImpl.EMPTY_LIST; } @@ -3324,7 +3402,11 @@ * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getLexicalFacetValues() */ public StringList getLexicalFacetValues() { - return values; + return svalues; + } + + public ObjectList getEnumerationValues() { + return avalues; } /* (non-Javadoc) @@ -3394,4 +3476,14 @@ return valueType; } + private void appendEnumString(StringBuffer sb) { + sb.append('['); + for (int i = 0; i < fEnumerationSize; i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(fEnumeration[i].actualValue); + } + sb.append(']'); + } } // class XSSimpleTypeDecl diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDelegate.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDelegate.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDelegate.java Wed Jul 05 20:04:43 2017 +0200 @@ -30,6 +30,7 @@ import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; import com.sun.org.apache.xerces.internal.xs.StringList; import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; +import com.sun.org.apache.xerces.internal.xs.XSObject; import com.sun.org.apache.xerces.internal.xs.XSObjectList; import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; @@ -76,6 +77,10 @@ return type.getFacets(); } + public XSObject getFacet(int facetType) { + return type.getFacet(facetType); + } + public boolean getFinite() { return type.getFinite(); } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Wed Jul 05 20:04:43 2017 +0200 @@ -41,7 +41,13 @@ cvc-complex-type.2.4.b = cvc-complex-type.2.4.b: The content of element ''{0}'' is not complete. One of ''{1}'' is expected. cvc-complex-type.2.4.c = cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ''{0}''. cvc-complex-type.2.4.d = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element is expected at this point. - cvc-complex-type.2.4.e = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element ''{1}'' is expected at this point. + cvc-complex-type.2.4.d.1 = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element ''{1}'' is expected at this point. + cvc-complex-type.2.4.e = cvc-complex-type.2.4.e: ''{0}'' can occur a maximum of ''{2}'' times in the current sequence. This limit was exceeded. At this point one of ''{1}'' is expected. + cvc-complex-type.2.4.f = cvc-complex-type.2.4.f: ''{0}'' can occur a maximum of ''{1}'' times in the current sequence. This limit was exceeded. No child element is expected at this point. + cvc-complex-type.2.4.g = cvc-complex-type.2.4.g: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. One more instance is required to satisfy this constraint. + cvc-complex-type.2.4.h = cvc-complex-type.2.4.h: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. ''{3}'' more instances are required to satisfy this constraint. + cvc-complex-type.2.4.i = cvc-complex-type.2.4.i: The content of element ''{0}'' is not complete. ''{1}'' is expected to occur a minimum of ''{2}'' times. One more instance is required to satisfy this constraint. + cvc-complex-type.2.4.j = cvc-complex-type.2.4.j: The content of element ''{0}'' is not complete. ''{1}'' is expected to occur a minimum of ''{2}'' times. ''{3}'' more instances are required to satisfy this constraint. cvc-complex-type.3.1 = cvc-complex-type.3.1: Value ''{2}'' of attribute ''{1}'' of element ''{0}'' is not valid with respect to the corresponding attribute use. Attribute ''{1}'' has a fixed value of ''{3}''. cvc-complex-type.3.2.1 = cvc-complex-type.3.2.1: Element ''{0}'' does not have an attribute wildcard for attribute ''{1}''. cvc-complex-type.3.2.2 = cvc-complex-type.3.2.2: Attribute ''{1}'' is not allowed to appear in element ''{0}''. @@ -51,7 +57,8 @@ cvc-datatype-valid.1.2.1 = cvc-datatype-valid.1.2.1: ''{0}'' is not a valid value for ''{1}''. cvc-datatype-valid.1.2.2 = cvc-datatype-valid.1.2.2: ''{0}'' is not a valid value of list type ''{1}''. cvc-datatype-valid.1.2.3 = cvc-datatype-valid.1.2.3: ''{0}'' is not a valid value of union type ''{1}''. - cvc-elt.1 = cvc-elt.1: Cannot find the declaration of element ''{0}''. + cvc-elt.1.a = cvc-elt.1.a: Cannot find the declaration of element ''{0}''. + cvc-elt.1.b = cvc-elt.1.b: The name of the element does not match the name of the element declaration. Saw ''{0}''. Expected ''{1}''. cvc-elt.2 = cvc-elt.2: The value of '{'abstract'}' in the element declaration for ''{0}'' must be false. cvc-elt.3.1 = cvc-elt.3.1: Attribute ''{1}'' must not appear on element ''{0}'', because the '{'nillable'}' property of ''{0}'' is false. cvc-elt.3.2.1 = cvc-elt.3.2.1: Element ''{0}'' cannot have character or element information [children], because ''{1}'' is specified. @@ -289,3 +296,10 @@ TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''. UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared. UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared. + + +# JAXP 1.2 schema source property errors + + jaxp12-schema-source-type.1 = The ''http://java.sun.com/xml/jaxp/properties/schemaSource'' property cannot have a value of type ''{0}''. Possible types of the value supported are String, File, InputStream, InputSource or an array of these types. + jaxp12-schema-source-type.2 = The ''http://java.sun.com/xml/jaxp/properties/schemaSource'' property cannot have an array value of type ''{0}''. Possible types of the array supported are Object, String, File, InputStream and InputSource. + jaxp12-schema-source-ns = When using an array of Objects as the value of the 'http://java.sun.com/xml/jaxp/properties/schemaSource' property, it is illegal to have two schemas that share the same target namespace. diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/validation/ConfigurableValidationState.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/validation/ConfigurableValidationState.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/validation/ConfigurableValidationState.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,9 +1,14 @@ /* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,6 +21,8 @@ package com.sun.org.apache.xerces.internal.impl.validation; +import java.util.Iterator; + /** *

An extension of ValidationState which can be configured to turn * off checking for ID/IDREF errors and unparsed entity errors.

@@ -49,7 +56,7 @@ /** * Turns checking for ID/IDREF errors on and off. - * @param setting: true to turn on error checking + * @param setting true to turn on error checking, * false to turn off error checking */ public void setIdIdrefChecking(boolean setting) { @@ -58,7 +65,7 @@ /** * Turns checking for unparsed entity errors on and off. - * @param setting: true to turn on error checking + * @param setting true to turn on error checking, * false to turn off error checking */ public void setUnparsedEntityChecking(boolean setting) { @@ -70,7 +77,7 @@ * @return null, if ID/IDREF checking is turned off * otherwise, returns the value of the super implementation */ - public String checkIDRefID() { + public Iterator checkIDRefID() { return (fIdIdrefChecking) ? super.checkIDRefID() : null; } @@ -103,7 +110,7 @@ /** * Adds the ID, if ID/IDREF checking is enabled. - * @param the ID to add + * @param name the ID to add */ public void addId(String name) { if (fIdIdrefChecking) { @@ -113,7 +120,7 @@ /** * Adds the IDREF, if ID/IDREF checking is enabled. - * @param the IDREF to add + * @param name the IDREF to add */ public void addIdRef(String name) { if (fIdIdrefChecking) { diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/validation/ValidationState.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/validation/ValidationState.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/validation/ValidationState.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001, 2002,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,11 +21,12 @@ package com.sun.org.apache.xerces.internal.impl.validation; +import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext; - import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; import java.util.Locale; /** @@ -86,25 +88,24 @@ /** * return null if all IDREF values have a corresponding ID value; - * otherwise return the first IDREF value without a matching ID value. + * otherwise return an iterator for all the IDREF values without + * a matching ID value. */ - public String checkIDRefID () { - if (fIdList == null) { - if (fIdRefList != null) { - return fIdRefList.get(0); - } - } - + public Iterator checkIDRefID () { + HashSet missingIDs = null; if (fIdRefList != null) { String key; for (int i = 0; i < fIdRefList.size(); i++) { key = fIdRefList.get(i); - if (!fIdList.contains(key)) { - return key; + if (fIdList == null || !fIdList.contains(key)) { + if (missingIDs == null) { + missingIDs = new HashSet(); + } + missingIDs.add(key); } } } - return null; + return (missingIDs != null) ? missingIDs.iterator() : null; } public void reset () { diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/AttributePSVImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/AttributePSVImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/AttributePSVImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2000-2002,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,14 +21,17 @@ package com.sun.org.apache.xerces.internal.impl.xs; +import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; +import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; +import com.sun.org.apache.xerces.internal.xs.AttributePSVI; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; import com.sun.org.apache.xerces.internal.xs.ShortList; import com.sun.org.apache.xerces.internal.xs.StringList; import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration; +import com.sun.org.apache.xerces.internal.xs.XSConstants; import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; -import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; -import com.sun.org.apache.xerces.internal.xs.AttributePSVI; -import com.sun.org.apache.xerces.internal.xs.XSConstants; +import com.sun.org.apache.xerces.internal.xs.XSValue; /** * Attribute PSV infoset augmentations implementation. @@ -49,20 +53,8 @@ * value in the original document, this is false; otherwise, it is true */ protected boolean fSpecified = false; - /** schema normalized value property */ - protected String fNormalizedValue = null; - - /** schema actual value */ - protected Object fActualValue = null; - - /** schema actual value type */ - protected short fActualValueType = XSConstants.UNAVAILABLE_DT; - - /** actual value types if the value is a list */ - protected ShortList fItemValueTypes = null; - - /** member type definition against which attribute was validated */ - protected XSSimpleTypeDefinition fMemberType = null; + /** Schema value */ + protected ValidatedInfo fValue = new ValidatedInfo(); /** validation attempted: none, partial, full */ protected short fValidationAttempted = AttributePSVI.VALIDATION_NONE; @@ -70,16 +62,67 @@ /** validity: valid, invalid, unknown */ protected short fValidity = AttributePSVI.VALIDITY_NOTKNOWN; - /** error codes */ - protected String[] fErrorCodes = null; + /** error codes and error messages */ + protected String[] fErrors = null; /** validation context: could be QName or XPath expression*/ protected String fValidationContext = null; + /** true if this object is immutable **/ + protected boolean fIsConstant; + + public AttributePSVImpl() {} + + public AttributePSVImpl(boolean isConstant, AttributePSVI attrPSVI) { + fDeclaration = attrPSVI.getAttributeDeclaration(); + fTypeDecl = attrPSVI.getTypeDefinition(); + fSpecified = attrPSVI.getIsSchemaSpecified(); + fValue.copyFrom(attrPSVI.getSchemaValue()); + fValidationAttempted = attrPSVI.getValidationAttempted(); + fValidity = attrPSVI.getValidity(); + if (attrPSVI instanceof AttributePSVImpl) { + final AttributePSVImpl attrPSVIImpl = (AttributePSVImpl) attrPSVI; + fErrors = (attrPSVIImpl.fErrors != null) ? + (String[]) attrPSVIImpl.fErrors.clone() : null; + } + else { + final StringList errorCodes = attrPSVI.getErrorCodes(); + final int length = errorCodes.getLength(); + if (length > 0) { + final StringList errorMessages = attrPSVI.getErrorMessages(); + final String[] errors = new String[length << 1]; + for (int i = 0, j = 0; i < length; ++i) { + errors[j++] = errorCodes.item(i); + errors[j++] = errorMessages.item(i); + } + fErrors = errors; + } + } + fValidationContext = attrPSVI.getValidationContext(); + fIsConstant = isConstant; + } + // // AttributePSVI methods // + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#constant() + */ + public ItemPSVI constant() { + if (isConstant()) { + return this; + } + return new AttributePSVImpl(true, this); + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#isConstant() + */ + public boolean isConstant() { + return fIsConstant; + } + /** * [schema default] * @@ -98,7 +141,7 @@ * @return the normalized value of this item after validation */ public String getSchemaNormalizedValue() { - return fNormalizedValue; + return fValue.getNormalizedValue(); } /** @@ -139,9 +182,23 @@ * @return list of error codes */ public StringList getErrorCodes() { - if (fErrorCodes == null) - return null; - return new StringListImpl(fErrorCodes, fErrorCodes.length); + if (fErrors == null || fErrors.length == 0) { + return StringListImpl.EMPTY_LIST; + } + return new PSVIErrorList(fErrors, true); + } + + /** + * A list of error messages generated from the validation attempt or + * an empty StringList if no errors occurred during the + * validation attempt. The indices of error messages in this list are + * aligned with those in the [schema error code] list. + */ + public StringList getErrorMessages() { + if (fErrors == null || fErrors.length == 0) { + return StringListImpl.EMPTY_LIST; + } + return new PSVIErrorList(fErrors, false); } // This is the only information we can provide in a pipeline. @@ -168,7 +225,7 @@ * @return a simple type declaration */ public XSSimpleTypeDefinition getMemberTypeDefinition() { - return fMemberType; + return fValue.getMemberTypeDefinition(); } /** @@ -185,38 +242,41 @@ * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue() */ public Object getActualNormalizedValue() { - return this.fActualValue; + return fValue.getActualValue(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType() */ public short getActualNormalizedValueType() { - return this.fActualValueType; + return fValue.getActualValueType(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes() */ public ShortList getItemValueTypes() { - return this.fItemValueTypes; + return fValue.getListValueTypes(); + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getSchemaValue() + */ + public XSValue getSchemaValue() { + return fValue; } /** * Reset() */ public void reset() { - fNormalizedValue = null; - fActualValue = null; - fActualValueType = XSConstants.UNAVAILABLE_DT; - fItemValueTypes = null; + fValue.reset(); fDeclaration = null; fTypeDecl = null; fSpecified = false; - fMemberType = null; fValidationAttempted = AttributePSVI.VALIDATION_NONE; fValidity = AttributePSVI.VALIDITY_NOTKNOWN; - fErrorCodes = null; + fErrors = null; fValidationContext = null; } } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/ElementPSVImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/ElementPSVImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/ElementPSVImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2000-2002,2004,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,16 +21,19 @@ package com.sun.org.apache.xerces.internal.impl.xs; +import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; +import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; +import com.sun.org.apache.xerces.internal.xs.ElementPSVI; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; import com.sun.org.apache.xerces.internal.xs.ShortList; import com.sun.org.apache.xerces.internal.xs.StringList; +import com.sun.org.apache.xerces.internal.xs.XSConstants; import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; import com.sun.org.apache.xerces.internal.xs.XSModel; import com.sun.org.apache.xerces.internal.xs.XSNotationDeclaration; import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; -import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; -import com.sun.org.apache.xerces.internal.xs.ElementPSVI; -import com.sun.org.apache.xerces.internal.xs.XSConstants; +import com.sun.org.apache.xerces.internal.xs.XSValue; /** * Element PSV infoset augmentations implementation. @@ -61,32 +65,20 @@ */ protected boolean fSpecified = false; - /** schema normalized value property */ - protected String fNormalizedValue = null; - - /** schema actual value */ - protected Object fActualValue = null; - - /** schema actual value type */ - protected short fActualValueType = XSConstants.UNAVAILABLE_DT; - - /** actual value types if the value is a list */ - protected ShortList fItemValueTypes = null; + /** Schema value */ + protected ValidatedInfo fValue = new ValidatedInfo(); /** http://www.w3.org/TR/xmlschema-1/#e-notation*/ protected XSNotationDeclaration fNotation = null; - /** member type definition against which element was validated */ - protected XSSimpleTypeDefinition fMemberType = null; - /** validation attempted: none, partial, full */ protected short fValidationAttempted = ElementPSVI.VALIDATION_NONE; /** validity: valid, invalid, unknown */ protected short fValidity = ElementPSVI.VALIDITY_NOTKNOWN; - /** error codes */ - protected String[] fErrorCodes = null; + /** error codes and error messages */ + protected String[] fErrors = null; /** validation context: could be QName or XPath expression*/ protected String fValidationContext = null; @@ -97,10 +89,65 @@ /** the schema information property */ protected XSModel fSchemaInformation = null; + /** true if this object is immutable **/ + protected boolean fIsConstant; + + public ElementPSVImpl() {} + + public ElementPSVImpl(boolean isConstant, ElementPSVI elementPSVI) { + fDeclaration = elementPSVI.getElementDeclaration(); + fTypeDecl = elementPSVI.getTypeDefinition(); + fNil = elementPSVI.getNil(); + fSpecified = elementPSVI.getIsSchemaSpecified(); + fValue.copyFrom(elementPSVI.getSchemaValue()); + fNotation = elementPSVI.getNotation(); + fValidationAttempted = elementPSVI.getValidationAttempted(); + fValidity = elementPSVI.getValidity(); + fValidationContext = elementPSVI.getValidationContext(); + if (elementPSVI instanceof ElementPSVImpl) { + final ElementPSVImpl elementPSVIImpl = (ElementPSVImpl) elementPSVI; + fErrors = (elementPSVIImpl.fErrors != null) ? + (String[]) elementPSVIImpl.fErrors.clone() : null; + elementPSVIImpl.copySchemaInformationTo(this); + } + else { + final StringList errorCodes = elementPSVI.getErrorCodes(); + final int length = errorCodes.getLength(); + if (length > 0) { + final StringList errorMessages = elementPSVI.getErrorMessages(); + final String[] errors = new String[length << 1]; + for (int i = 0, j = 0; i < length; ++i) { + errors[j++] = errorCodes.item(i); + errors[j++] = errorMessages.item(i); + } + fErrors = errors; + } + fSchemaInformation = elementPSVI.getSchemaInformation(); + } + fIsConstant = isConstant; + } + // // ElementPSVI methods // + /* (non-Javadoc) + * @see org.apache.xerces.xs.ItemPSVI#constant() + */ + public ItemPSVI constant() { + if (isConstant()) { + return this; + } + return new ElementPSVImpl(true, this); + } + + /* (non-Javadoc) + * @see org.apache.xerces.xs.ItemPSVI#isConstant() + */ + public boolean isConstant() { + return fIsConstant; + } + /** * [schema default] * @@ -119,7 +166,7 @@ * @return the normalized value of this item after validation */ public String getSchemaNormalizedValue() { - return fNormalizedValue; + return fValue.getNormalizedValue(); } /** @@ -159,11 +206,24 @@ * @return Array of error codes */ public StringList getErrorCodes() { - if (fErrorCodes == null) - return null; - return new StringListImpl(fErrorCodes, fErrorCodes.length); + if (fErrors == null || fErrors.length == 0) { + return StringListImpl.EMPTY_LIST; + } + return new PSVIErrorList(fErrors, true); } + /** + * A list of error messages generated from the validation attempt or + * an empty StringList if no errors occurred during the + * validation attempt. The indices of error messages in this list are + * aligned with those in the [schema error code] list. + */ + public StringList getErrorMessages() { + if (fErrors == null || fErrors.length == 0) { + return StringListImpl.EMPTY_LIST; + } + return new PSVIErrorList(fErrors, false); + } // This is the only information we can provide in a pipeline. public String getValidationContext() { @@ -207,7 +267,7 @@ * @return a simple type declaration */ public XSSimpleTypeDefinition getMemberTypeDefinition() { - return fMemberType; + return fValue.getMemberTypeDefinition(); } /** @@ -237,21 +297,28 @@ * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue() */ public Object getActualNormalizedValue() { - return this.fActualValue; + return fValue.getActualValue(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType() */ public short getActualNormalizedValueType() { - return this.fActualValueType; + return fValue.getActualValueType(); } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes() */ public ShortList getItemValueTypes() { - return this.fItemValueTypes; + return fValue.getListValueTypes(); + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getSchemaValue() + */ + public XSValue getSchemaValue() { + return fValue; } /** @@ -263,15 +330,15 @@ fNil = false; fSpecified = false; fNotation = null; - fMemberType = null; fValidationAttempted = ElementPSVI.VALIDATION_NONE; fValidity = ElementPSVI.VALIDITY_NOTKNOWN; - fErrorCodes = null; + fErrors = null; fValidationContext = null; - fNormalizedValue = null; - fActualValue = null; - fActualValueType = XSConstants.UNAVAILABLE_DT; - fItemValueTypes = null; + fValue.reset(); } + public void copySchemaInformationTo(ElementPSVImpl target) { + target.fGrammars = fGrammars; + target.fSchemaInformation = fSchemaInformation; + } } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/PSVIErrorList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/PSVIErrorList.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,92 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.impl.xs; + +import java.util.AbstractList; + +import com.sun.org.apache.xerces.internal.xs.StringList; + +/** + * StringList implementation for schema error codes and error messages. + * + * @xerces.internal + * + * @author Michael Glavassevich, IBM + * + */ +final class PSVIErrorList extends AbstractList implements StringList { + + private final String[] fArray; + private final int fLength; + private final int fOffset; + + public PSVIErrorList(String[] array, boolean even) { + fArray = array; + fLength = (fArray.length >> 1); + fOffset = even ? 0 : 1; + } + + public boolean contains(String item) { + if (item == null) { + for (int i = 0; i < fLength; ++i) { + if (fArray[(i << 1) + fOffset] == null) { + return true; + } + } + } + else { + for (int i = 0; i < fLength; ++i) { + if (item.equals(fArray[(i << 1) + fOffset])) { + return true; + } + } + } + return false; + } + + public int getLength() { + return fLength; + } + + public String item(int index) { + if (index < 0 || index >= fLength) { + return null; + } + return fArray[(index << 1) + fOffset]; + } + + /* + * List methods + */ + + public Object get(int index) { + if (index >= 0 && index < fLength) { + return fArray[(index << 1) + fOffset]; + } + throw new IndexOutOfBoundsException("Index: " + index); + } + + public int size() { + return getLength(); + } + +} // class PSVIErrorList diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SchemaGrammar.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SchemaGrammar.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SchemaGrammar.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,9 +21,6 @@ package com.sun.org.apache.xerces.internal.impl.xs; -import java.lang.ref.SoftReference; -import java.util.Vector; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory; import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; @@ -49,6 +47,7 @@ import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition; import com.sun.org.apache.xerces.internal.xs.XSConstants; import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; +import com.sun.org.apache.xerces.internal.xs.XSIDCDefinition; import com.sun.org.apache.xerces.internal.xs.XSModel; import com.sun.org.apache.xerces.internal.xs.XSModelGroupDefinition; import com.sun.org.apache.xerces.internal.xs.XSNamedMap; @@ -59,6 +58,8 @@ import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; import com.sun.org.apache.xerces.internal.xs.XSWildcard; import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList; +import java.lang.ref.SoftReference; +import java.util.Vector; import org.xml.sax.SAXException; /** @@ -135,7 +136,7 @@ * Default constructor. * * @param targetNamespace - * @param grammarDesc the XMLGrammarDescription corresponding to this objec + * @param grammarDesc the XMLGrammarDescription corresponding to this object * at the least a systemId should always be known. * @param symbolTable needed for annotation support */ @@ -145,35 +146,39 @@ fGrammarDescription = grammarDesc; fSymbolTable = symbolTable; - // REVISIT: do we know the numbers of the following global decls - // when creating this grammar? If so, we can pass the numbers in, - // and use that number to initialize the following hashtables. - fGlobalAttrDecls = new SymbolHash(); - fGlobalAttrGrpDecls = new SymbolHash(); - fGlobalElemDecls = new SymbolHash(); - fGlobalGroupDecls = new SymbolHash(); - fGlobalNotationDecls = new SymbolHash(); - fGlobalIDConstraintDecls = new SymbolHash(); + // REVISIT: the initial sizes being chosen for each SymbolHash + // may not be ideal and could still be tuned. They were chosen + // somewhat arbitrarily to reduce the initial footprint of + // SymbolHash buckets from 1,515 to 177 (about 12% of the + // default size). + fGlobalAttrDecls = new SymbolHash(12); + fGlobalAttrGrpDecls = new SymbolHash(5); + fGlobalElemDecls = new SymbolHash(25); + fGlobalGroupDecls = new SymbolHash(5); + fGlobalNotationDecls = new SymbolHash(1); + fGlobalIDConstraintDecls = new SymbolHash(3); // Extended tables - fGlobalAttrDeclsExt = new SymbolHash(); - fGlobalAttrGrpDeclsExt = new SymbolHash(); - fGlobalElemDeclsExt = new SymbolHash(); - fGlobalGroupDeclsExt = new SymbolHash(); - fGlobalNotationDeclsExt = new SymbolHash(); - fGlobalIDConstraintDeclsExt = new SymbolHash(); - fGlobalTypeDeclsExt = new SymbolHash(); + fGlobalAttrDeclsExt = new SymbolHash(12); + fGlobalAttrGrpDeclsExt = new SymbolHash(5); + fGlobalElemDeclsExt = new SymbolHash(25); + fGlobalGroupDeclsExt = new SymbolHash(5); + fGlobalNotationDeclsExt = new SymbolHash(1); + fGlobalIDConstraintDeclsExt = new SymbolHash(3); + fGlobalTypeDeclsExt = new SymbolHash(25); // All global elements table - fAllGlobalElemDecls = new SymbolHash(); + fAllGlobalElemDecls = new SymbolHash(25); // if we are parsing S4S, put built-in types in first // they might get overwritten by the types from S4S, but that's // considered what the application wants to do. - if (fTargetNamespace == SchemaSymbols.URI_SCHEMAFORSCHEMA) + if (fTargetNamespace == SchemaSymbols.URI_SCHEMAFORSCHEMA) { fGlobalTypeDecls = SG_SchemaNS.fGlobalTypeDecls.makeClone(); - else - fGlobalTypeDecls = new SymbolHash(); + } + else { + fGlobalTypeDecls = new SymbolHash(25); + } } // (String, XSDDescription) // Clone an existing schema grammar @@ -232,7 +237,7 @@ fRedefinedGroupDecls = new XSGroupDecl[grammar.fRedefinedGroupDecls.length]; fRGLocators = new SimpleLocator[grammar.fRGLocators.length]; System.arraycopy(grammar.fRedefinedGroupDecls, 0, fRedefinedGroupDecls, 0, fRGCount); - System.arraycopy(grammar.fRGLocators, 0, fRGLocators, 0, fRGCount); + System.arraycopy(grammar.fRGLocators, 0, fRGLocators, 0, fRGCount/2); } // List of imported grammars @@ -626,19 +631,19 @@ // fill complex types annotationType.setValues("#AnonType_" + SchemaSymbols.ELT_ANNOTATION, fTargetNamespace, SchemaGrammar.fAnyType, XSConstants.DERIVATION_RESTRICTION, XSConstants.DERIVATION_NONE, (short) (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION), - XSComplexTypeDecl.CONTENTTYPE_ELEMENT, false, annotationAttrs, null, annotationParticle, new XSObjectListImpl(null, 0)); + XSComplexTypeDecl.CONTENTTYPE_ELEMENT, false, annotationAttrs, null, annotationParticle, XSObjectListImpl.EMPTY_LIST); annotationType.setName("#AnonType_" + SchemaSymbols.ELT_ANNOTATION); annotationType.setIsAnonymous(); documentationType.setValues("#AnonType_" + SchemaSymbols.ELT_DOCUMENTATION, fTargetNamespace, SchemaGrammar.fAnyType, XSConstants.DERIVATION_RESTRICTION, XSConstants.DERIVATION_NONE, (short) (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION), - XSComplexTypeDecl.CONTENTTYPE_MIXED, false, documentationAttrs, null, anyWCSequenceParticle, new XSObjectListImpl(null, 0)); + XSComplexTypeDecl.CONTENTTYPE_MIXED, false, documentationAttrs, null, anyWCSequenceParticle, XSObjectListImpl.EMPTY_LIST); documentationType.setName("#AnonType_" + SchemaSymbols.ELT_DOCUMENTATION); documentationType.setIsAnonymous(); appinfoType.setValues("#AnonType_" + SchemaSymbols.ELT_APPINFO, fTargetNamespace, SchemaGrammar.fAnyType, XSConstants.DERIVATION_RESTRICTION, XSConstants.DERIVATION_NONE, (short) (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION), - XSComplexTypeDecl.CONTENTTYPE_MIXED, false, appinfoAttrs, null, anyWCSequenceParticle, new XSObjectListImpl(null, 0)); + XSComplexTypeDecl.CONTENTTYPE_MIXED, false, appinfoAttrs, null, anyWCSequenceParticle, XSObjectListImpl.EMPTY_LIST); appinfoType.setName("#AnonType_" + SchemaSymbols.ELT_APPINFO); appinfoType.setIsAnonymous(); @@ -1178,8 +1183,8 @@ fDerivedBy = XSConstants.DERIVATION_RESTRICTION; fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED; - fParticle = null; - fAttrGrp = null; + fParticle = createParticle(); + fAttrGrp = createAttrGrp(); } // overridden methods @@ -1211,11 +1216,15 @@ // null implementation } - public XSObjectList getAttributeUses() { + public XSObjectList getAnnotations() { return XSObjectListImpl.EMPTY_LIST; } - public XSAttributeGroupDecl getAttrGrp() { + public XSNamespaceItem getNamespaceItem() { + return SG_SchemaNS; + } + + private XSAttributeGroupDecl createAttrGrp() { XSWildcardDecl wildcard = new XSWildcardDecl(); wildcard.fProcessContents = XSWildcardDecl.PC_LAX; XSAttributeGroupDecl attrGrp = new XSAttributeGroupDecl(); @@ -1223,13 +1232,7 @@ return attrGrp; } - public XSWildcard getAttributeWildcard() { - XSWildcardDecl wildcard = new XSWildcardDecl(); - wildcard.fProcessContents = XSWildcardDecl.PC_LAX; - return wildcard; - } - - public XSParticle getParticle() { + private XSParticleDecl createParticle() { // the wildcard used in anyType (content and attribute) // the spec will change strict to skip for anyType XSWildcardDecl wildcard = new XSWildcardDecl(); @@ -1253,14 +1256,6 @@ return particleG; } - - public XSObjectList getAnnotations() { - return XSObjectListImpl.EMPTY_LIST; - } - - public XSNamespaceItem getNamespaceItem() { - return SG_SchemaNS; - } } private static class BuiltinAttrDecl extends XSAttributeDecl { public BuiltinAttrDecl(String name, String tns, @@ -1347,7 +1342,7 @@ false, // model group false, // particle false, // wildcard - false, // idc + true, // idc true, // notation false, // annotation false, // facet @@ -1484,6 +1479,9 @@ case XSConstants.NOTATION_DECLARATION: table = fGlobalNotationDecls; break; + case XSConstants.IDENTITY_CONSTRAINT: + table = this.fGlobalIDConstraintDecls; + break; } // for complex/simple types, create a special implementation, @@ -1533,6 +1531,9 @@ case XSConstants.NOTATION_DECLARATION: table = fGlobalNotationDeclsExt; break; + case XSConstants.IDENTITY_CONSTRAINT: + table = this.fGlobalIDConstraintDeclsExt; + break; } Object[] entries = table.getEntries(); @@ -1610,6 +1611,10 @@ return getGlobalNotationDecl(name); } + public XSIDCDefinition getIDCDefinition(String name) { + return getIDConstraintDecl(name); + } + /** * [document location] diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SubstitutionGroupHandler.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SubstitutionGroupHandler.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SubstitutionGroupHandler.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -40,14 +41,14 @@ private static final XSElementDecl[] EMPTY_GROUP = new XSElementDecl[0]; - // grammar resolver - XSGrammarBucket fGrammarBucket; + // global element declaration resolver + private final XSElementDeclHelper fXSElementDeclHelper; /** * Default constructor */ - public SubstitutionGroupHandler(XSGrammarBucket grammarBucket) { - fGrammarBucket = grammarBucket; + public SubstitutionGroupHandler(XSElementDeclHelper elementDeclHelper) { + fXSElementDeclHelper = elementDeclHelper; } // 3.9.4 Element Sequence Locally Valid (Particle) 2.3.3 @@ -60,26 +61,25 @@ // if the exemplar is not a global element decl, then it's not possible // to be substituted by another element. - if (exemplar.fScope != XSConstants.SCOPE_GLOBAL) + if (exemplar.fScope != XSConstants.SCOPE_GLOBAL) { return null; + } // if the decl blocks substitution, return false - if ((exemplar.fBlock & XSConstants.DERIVATION_SUBSTITUTION) != 0) + if ((exemplar.fBlock & XSConstants.DERIVATION_SUBSTITUTION) != 0) { return null; - - // get grammar of the element - SchemaGrammar sGrammar = fGrammarBucket.getGrammar(element.uri); - if (sGrammar == null) - return null; + } // get the decl for the element - XSElementDecl eDecl = sGrammar.getGlobalElementDecl(element.localpart); - if (eDecl == null) + XSElementDecl eDecl = fXSElementDeclHelper.getGlobalElementDecl(element); + if (eDecl == null) { return null; + } // and check by using substitutionGroup information - if (substitutionGroupOK(eDecl, exemplar, exemplar.fBlock)) + if (substitutionGroupOK(eDecl, exemplar, exemplar.fBlock)) { return eDecl; + } return null; } @@ -89,13 +89,15 @@ protected boolean substitutionGroupOK(XSElementDecl element, XSElementDecl exemplar, short blockingConstraint) { // For an element declaration (call it D) to be validly substitutable for another element declaration (call it C) subject to a blocking constraint (a subset of {substitution, extension, restriction}, the value of a {disallowed substitutions}) one of the following must be true: // 1. D and C are the same element declaration. - if (element == exemplar) + if (element == exemplar) { return true; + } // 2 All of the following must be true: // 2.1 The blocking constraint does not contain substitution. - if ((blockingConstraint & XSConstants.DERIVATION_SUBSTITUTION) != 0) + if ((blockingConstraint & XSConstants.DERIVATION_SUBSTITUTION) != 0) { return false; + } // 2.2 There is a chain of {substitution group affiliation}s from D to C, that is, either D's {substitution group affiliation} is C, or D's {substitution group affiliation}'s {substitution group affiliation} is C, or . . . XSElementDecl subGroup = element.fSubGroup; @@ -103,14 +105,16 @@ subGroup = subGroup.fSubGroup; } - if (subGroup == null) + if (subGroup == null) { return false; + } // 2.3 The set of all {derivation method}s involved in the derivation of D's {type definition} from C's {type definition} does not intersect with the union of the blocking constraint, C's {prohibited substitutions} (if C is complex, otherwise the empty set) and the {prohibited substitutions} (respectively the empty set) of any intermediate {type definition}s in the derivation of D's {type definition} from C's {type definition}. // prepare the combination of {derivation method} and // {disallowed substitution} return typeDerivationOK(element.fType, exemplar.fType, blockingConstraint); } + private boolean typeDerivationOK(XSTypeDefinition derived, XSTypeDefinition base, short blockingConstraint) { short devMethod = 0, blockConstraint = blockingConstraint; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2000-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,26 +20,12 @@ package com.sun.org.apache.xerces.internal.impl.xs; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.util.Hashtable; -import java.util.Locale; -import java.util.StringTokenizer; -import java.util.Vector; - import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl; import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter; import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; -import com.sun.org.apache.xerces.internal.impl.dv.DVFactoryException; import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException; import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory; import com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl; @@ -49,13 +35,16 @@ import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler; +import com.sun.org.apache.xerces.internal.util.MessageFormatter; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -72,14 +61,26 @@ import com.sun.org.apache.xerces.internal.xs.StringList; import com.sun.org.apache.xerces.internal.xs.XSLoader; import com.sun.org.apache.xerces.internal.xs.XSModel; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Locale; import java.util.Map; +import java.util.StringTokenizer; +import java.util.WeakHashMap; import javax.xml.XMLConstants; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMError; import org.w3c.dom.DOMErrorHandler; +import org.w3c.dom.DOMException; import org.w3c.dom.DOMStringList; -import org.w3c.dom.DOMException; import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.InputSource; @@ -101,7 +102,7 @@ * @author Neil Graham, IBM */ -public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent, +public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent, XSElementDeclHelper, // XML Component API XSLoader, DOMConfiguration { @@ -249,8 +250,7 @@ // Data // features and properties - private ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings(); - private SymbolTable fSymbolTable = null; + private final ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings(); private XMLErrorReporter fErrorReporter = new XMLErrorReporter (); private XMLEntityManager fEntityManager = null; private XMLEntityResolver fUserEntityResolver = null; @@ -276,7 +276,7 @@ private XSDDescription fXSDDescription = new XSDDescription(); private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT; - private Map fJAXPCache; + private WeakHashMap fJAXPCache; private Locale fLocale = Locale.getDefault(); // XSLoader attributes @@ -350,8 +350,8 @@ grammarBucket = new XSGrammarBucket(); } fGrammarBucket = grammarBucket; - if(sHandler == null) { - sHandler = new SubstitutionGroupHandler(fGrammarBucket); + if (sHandler == null) { + sHandler = new SubstitutionGroupHandler(this); } fSubGroupHandler = sHandler; @@ -360,10 +360,7 @@ } fCMBuilder = builder; fSchemaHandler = new XSDHandler(fGrammarBucket); - if (fDeclPool != null) { - fDeclPool.reset(); - } - fJAXPCache = new HashMap(); + fJAXPCache = new WeakHashMap(); fSettingsChanged = true; } @@ -527,8 +524,8 @@ * Returns a Grammar object by parsing the contents of the * entities pointed to by sources. * - * @param source[] the locations of the entity which forms - * the staring point of the grammars to be constructed + * @param source the locations of the entity which forms + * the staring point of the grammars to be constructed * @throws IOException when a problem is encounted reading the entity * @throws XNIException when a condition arises (such as a FatalError) that requires parsing * of the entity be terminated @@ -618,7 +615,8 @@ return grammar; } // loadSchema(XSDDescription, XMLInputSource): SchemaGrammar - /** This method tries to resolve location of the given schema. + /** + * This method tries to resolve location of the given schema. * The loader stores the namespace/location pairs in a hashtable (use "" as the * namespace of absent namespace). When resolving an entity, loader first tries * to find in the hashtable whether there is a value for that namespace, @@ -627,7 +625,7 @@ * @param desc * @param locationPairs * @param entityResolver - * @return + * @return the XMLInputSource * @throws IOException */ public static XMLInputSource resolveDocument(XSDDescription desc, Map locationPairs, @@ -671,7 +669,7 @@ XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION); // validation the string value to get the list of URI's attrDecl.fType.validate(sl, null, null); - if (!tokenizeSchemaLocationStr(sl, locations)) { + if (!tokenizeSchemaLocationStr(sl, locations, null)) { // report warning (odd number of items) er.reportError(XSMessageFormatter.SCHEMA_DOMAIN, "SchemaLocation", @@ -714,7 +712,7 @@ // @param schemaStr The schemaLocation string to tokenize // @param locations HashMap mapping namespaces to LocationArray objects holding lists of locaitons // @return true if no problems; false if string could not be tokenized - public static boolean tokenizeSchemaLocationStr(String schemaStr, Map locations) { + public static boolean tokenizeSchemaLocationStr(String schemaStr, Map locations, String base) { if (schemaStr!= null) { StringTokenizer t = new StringTokenizer(schemaStr, " \n\t\r"); String namespace, location; @@ -729,6 +727,12 @@ la = new LocationArray(); locations.put(namespace, la); } + if (base != null) { + try { + location = XMLEntityManager.expandSystemId(location, base, false); + } catch (MalformedURIException e) { + } + } la.addLocation(location); } } @@ -756,10 +760,10 @@ String sid = null; if (componentType == null) { // Not an array - if(fJAXPSource instanceof InputStream || + if (fJAXPSource instanceof InputStream || fJAXPSource instanceof InputSource) { SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(fJAXPSource); - if(g != null) { + if (g != null) { fGrammarBucket.putGrammar(g); return; } @@ -776,38 +780,40 @@ } SchemaGrammar g = loadSchema(fXSDDescription, xis, locationPairs); // it is possible that we won't be able to resolve JAXP schema-source location - if (g != null){ - if(fJAXPSource instanceof InputStream || + if (g != null) { + if (fJAXPSource instanceof InputStream || fJAXPSource instanceof InputSource) { fJAXPCache.put(fJAXPSource, g); - if(fIsCheckedFully) { + if (fIsCheckedFully) { XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter); } } fGrammarBucket.putGrammar(g); } - return ; - } else if ( (componentType != Object.class) && + return; + } + else if ( (componentType != Object.class) && (componentType != String.class) && - (componentType != File.class) && - (componentType != InputStream.class) && - (componentType != InputSource.class) + !File.class.isAssignableFrom(componentType) && + !InputStream.class.isAssignableFrom(componentType) && + !InputSource.class.isAssignableFrom(componentType) && + !componentType.isInterface() ) { // Not an Object[], String[], File[], InputStream[], InputSource[] + MessageFormatter mf = fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN); throw new XMLConfigurationException( - Status.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+ - "\" property cannot have an array of type {"+componentType.getName()+ - "}. Possible types of the array supported are Object, String, File, "+ - "InputStream, InputSource."); + Status.NOT_SUPPORTED, + mf.formatMessage(fErrorReporter.getLocale(), "jaxp12-schema-source-type.2", + new Object [] {componentType.getName()})); } // JAXP spec. allow []s of type String, File, InputStream, // InputSource also, apart from [] of type Object. Object[] objArr = (Object[]) fJAXPSource; - //make local vector for storing targetn namespaces of schemasources specified in object arrays. - Vector jaxpSchemaSourceNamespaces = new Vector() ; + // make local array for storing target namespaces of schemasources specified in object arrays. + ArrayList jaxpSchemaSourceNamespaces = new ArrayList(); for (int i = 0; i < objArr.length; i++) { - if(objArr[i] instanceof InputStream || + if (objArr[i] instanceof InputStream || objArr[i] instanceof InputSource) { SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(objArr[i]); if (g != null) { @@ -829,18 +835,18 @@ // load schema SchemaGrammar grammar = fSchemaHandler.parseSchema(xis,fXSDDescription, locationPairs); - if(fIsCheckedFully) { + if (fIsCheckedFully) { XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter); } - if(grammar != null){ - targetNamespace = grammar.getTargetNamespace() ; - if(jaxpSchemaSourceNamespaces.contains(targetNamespace)){ - //when an array of objects is passed it is illegal to have two schemas that share same namespace. - throw new java.lang.IllegalArgumentException( - " When using array of Objects as the value of SCHEMA_SOURCE property , " + - "no two Schemas should share the same targetNamespace. " ); + if (grammar != null) { + targetNamespace = grammar.getTargetNamespace(); + if (jaxpSchemaSourceNamespaces.contains(targetNamespace)) { + // when an array of objects is passed it is illegal to have two schemas that share same namespace. + MessageFormatter mf = fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN); + throw new java.lang.IllegalArgumentException(mf.formatMessage(fErrorReporter.getLocale(), + "jaxp12-schema-source-ns", null)); } - else{ + else { jaxpSchemaSourceNamespaces.add(targetNamespace) ; } if(objArr[i] instanceof InputStream || @@ -849,15 +855,13 @@ } fGrammarBucket.putGrammar(grammar); } - else{ + else { //REVISIT: What should be the acutal behavior if grammar can't be loaded as specified in schema source? } } }//processJAXPSchemaSource - private XMLInputSource xsdToXMLInputSource( - Object val) - { + private XMLInputSource xsdToXMLInputSource(Object val) { if (val instanceof String) { // String value is treated as a URI that is passed through the // EntityResolver @@ -867,7 +871,8 @@ XMLInputSource xis = null; try { xis = fEntityManager.resolveEntity(fXSDDescription); - } catch (IOException ex) { + } + catch (IOException ex) { fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, "schema_reference.4", new Object[] { loc }, XMLErrorReporter.SEVERITY_ERROR); @@ -878,12 +883,15 @@ return new XMLInputSource(null, loc, null); } return xis; - } else if (val instanceof InputSource) { + } + else if (val instanceof InputSource) { return saxToXMLInputSource((InputSource) val); - } else if (val instanceof InputStream) { + } + else if (val instanceof InputStream) { return new XMLInputSource(null, null, null, (InputStream) val, null); - } else if (val instanceof File) { + } + else if (val instanceof File) { File file = (File) val; InputStream is = null; try { @@ -893,13 +901,13 @@ "schema_reference.4", new Object[] { file.toString() }, XMLErrorReporter.SEVERITY_ERROR); } - return new XMLInputSource(null, null, null, is, null); + return new XMLInputSource(null, file.toURI().toString(), null, is, null); } + MessageFormatter mf = fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN); throw new XMLConfigurationException( - Status.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+ - "\" property cannot have a value of type {"+val.getClass().getName()+ - "}. Possible types of the value supported are String, File, InputStream, "+ - "InputSource OR an array of these types."); + Status.NOT_SUPPORTED, + mf.formatMessage(fErrorReporter.getLocale(), "jaxp12-schema-source-type.1", + new Object [] {val != null ? val.getClass().getName() : "null"})); } @@ -999,13 +1007,22 @@ fSubGroupHandler.reset(); - boolean parser_settings = componentManager.getFeature(PARSER_SETTINGS, true); + boolean parser_settings = true; + // If the component manager is the loader config don't bother querying it since it doesn't + // recognize the PARSER_SETTINGS feature. Prevents an XMLConfigurationException from being + // thrown. + if (componentManager != fLoaderConfig) { + parser_settings = componentManager.getFeature(PARSER_SETTINGS, true); + } if (!parser_settings || !fSettingsChanged){ // need to reprocess JAXP schema sources fJAXPProcessed = false; // reinitialize grammar bucket initGrammarBucket(); + if (fDeclPool != null) { + fDeclPool.reset(); + } return; } @@ -1028,26 +1045,6 @@ fSchemaHandler.setDVFactory(dvFactory); } - boolean psvi = componentManager.getFeature(AUGMENT_PSVI, false); - - if (!psvi) { - if (fDeclPool != null) { - fDeclPool.reset(); - } - else { - fDeclPool = new XSDeclarationPool(); - } - fCMBuilder.setDeclPool(fDeclPool); - fSchemaHandler.setDeclPool(fDeclPool); - if (dvFactory instanceof SchemaDVFactoryImpl) { - fDeclPool.setDVFactory((SchemaDVFactoryImpl)dvFactory); - ((SchemaDVFactoryImpl)dvFactory).setDeclPool(fDeclPool); - } - } else { - fCMBuilder.setDeclPool(null); - fSchemaHandler.setDeclPool(null); - } - // get schema location properties try { fExternalSchemas = (String) componentManager.getProperty(SCHEMA_LOCATION); @@ -1064,6 +1061,36 @@ // clear grammars, and put the one for schema namespace there fGrammarPool = (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL, null); initGrammarBucket(); + + boolean psvi = componentManager.getFeature(AUGMENT_PSVI, false); + + // Only use the decl pool when there is no chance that the schema + // components will be exposed or cached. + // TODO: when someone calls loadGrammar(XMLInputSource), the schema is + // always exposed even without the use of a grammar pool. + // Disabling the "decl pool" feature for now until we understand when + // it can be safely used. + if (!psvi && fGrammarPool == null && false) { + if (fDeclPool != null) { + fDeclPool.reset(); + } + else { + fDeclPool = new XSDeclarationPool(); + } + fCMBuilder.setDeclPool(fDeclPool); + fSchemaHandler.setDeclPool(fDeclPool); + if (dvFactory instanceof SchemaDVFactoryImpl) { + fDeclPool.setDVFactory((SchemaDVFactoryImpl)dvFactory); + ((SchemaDVFactoryImpl)dvFactory).setDeclPool(fDeclPool); + } + } else { + fCMBuilder.setDeclPool(null); + fSchemaHandler.setDeclPool(null); + if (dvFactory instanceof SchemaDVFactoryImpl) { + ((SchemaDVFactoryImpl)dvFactory).setDeclPool(null); + } + } + // get continue-after-fatal-error feature try { boolean fatalError = componentManager.getFeature(CONTINUE_AFTER_FATAL_ERROR, false); @@ -1083,7 +1110,8 @@ private void initGrammarBucket(){ if(fGrammarPool != null) { Grammar [] initialGrammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA); - for (int i = 0; i < initialGrammars.length; i++) { + final int length = (initialGrammars != null) ? initialGrammars.length : 0; + for (int i = 0; i < length; ++i) { // put this grammar into the bucket, along with grammars // imported by it (directly or indirectly) if (!fGrammarBucket.putGrammar((SchemaGrammar)(initialGrammars[i]), true)) { @@ -1119,7 +1147,7 @@ } /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.DOMInputList) + * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.LSInputList) */ public XSModel loadInputList(LSInputList is) { int length = is.getLength(); @@ -1250,7 +1278,7 @@ */ public DOMStringList getParameterNames() { if (fRecognizedParameters == null){ - Vector v = new Vector(); + ArrayList v = new ArrayList(); v.add(Constants.DOM_VALIDATE); v.add(Constants.DOM_ERROR_HANDLER); v.add(Constants.DOM_RESOURCE_RESOLVER); @@ -1391,4 +1419,13 @@ return xis; } + // Implements XSElementDeclHelper interface + public XSElementDecl getGlobalElementDecl(QName element) { + SchemaGrammar sGrammar = fGrammarBucket.getGrammar(element.uri); + if (sGrammar != null) { + return sGrammar.getGlobalElementDecl(element.localpart); + } + return null; + } + } // XMLGrammarLoader diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,3 +1,6 @@ +/* + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,7 +28,6 @@ import java.util.Map; import java.util.Stack; import java.util.Vector; -import java.util.ArrayList; import javax.xml.XMLConstants; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.RevalidationHandler; @@ -35,6 +37,7 @@ import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException; import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; +import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl; import com.sun.org.apache.xerces.internal.impl.validation.ConfigurableValidationState; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.validation.ValidationState; @@ -49,6 +52,7 @@ import com.sun.org.apache.xerces.internal.impl.xs.models.CMBuilder; import com.sun.org.apache.xerces.internal.impl.xs.models.CMNodeFactory; import com.sun.org.apache.xerces.internal.impl.xs.models.XSCMValidator; +import com.sun.org.apache.xerces.internal.impl.xs.util.XS10TypeHelper; import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; import com.sun.org.apache.xerces.internal.util.IntStack; import com.sun.org.apache.xerces.internal.util.SymbolTable; @@ -107,7 +111,7 @@ * @author Neeraj Bajaj, Sun Microsystems, inc. */ public class XMLSchemaValidator - implements XMLComponent, XMLDocumentFilter, FieldActivator, RevalidationHandler { + implements XMLComponent, XMLDocumentFilter, FieldActivator, RevalidationHandler, XSElementDeclHelper { // // Constants @@ -246,6 +250,10 @@ protected static final String ROOT_TYPE_DEF = Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_TYPE_DEFINITION_PROPERTY; + /** Property identifier: root element declaration. */ + protected static final String ROOT_ELEMENT_DECL = + Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_ELEMENT_DECLARATION_PROPERTY; + /** Property identifier: Schema DV Factory */ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; @@ -279,7 +287,7 @@ NAMESPACE_GROWTH, TOLERATE_DUPLICATES, USE_SERVICE_MECHANISM - }; + }; /** Feature defaults. */ private static final Boolean[] FEATURE_DEFAULTS = { null, @@ -324,19 +332,26 @@ JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, ROOT_TYPE_DEF, + ROOT_ELEMENT_DECL, SCHEMA_DV_FACTORY, XML_SECURITY_PROPERTY_MANAGER - }; + }; /** Property defaults. */ private static final Object[] PROPERTY_DEFAULTS = - { null, null, null, null, null, null, null, null, null, null, null}; + { null, null, null, null, null, null, null, null, null, null, null, null}; // this is the number of valuestores of each kind // we expect an element to have. It's almost // never > 1; so leave it at that. protected static final int ID_CONSTRAINT_NUM = 1; + // xsi:* attribute declarations + static final XSAttributeDecl XSI_TYPE = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_TYPE); + static final XSAttributeDecl XSI_NIL = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NIL); + static final XSAttributeDecl XSI_SCHEMALOCATION = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION); + static final XSAttributeDecl XSI_NONAMESPACESCHEMALOCATION = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION); + // private static final Hashtable EMPTY_TABLE = new Hashtable(); @@ -354,12 +369,6 @@ // clear this before we introduce it into the pipeline. protected final AugmentationsImpl fAugmentations = new AugmentationsImpl(); - /** - * Map which is used to catch instance documents that try - * and match a field several times in the same scope. - */ - protected final HashMap fMayMatchFieldMap = new HashMap(); - // this is included for the convenience of handleEndElement protected XMLString fDefaultValue; @@ -485,9 +494,10 @@ public void reportError(String domain, String key, Object[] arguments, short severity) throws XNIException { - fErrorReporter.reportError(domain, key, arguments, severity); + String message = fErrorReporter.reportError(domain, key, arguments, severity); if (fAugPSVI) { fErrors.addElement(key); + fErrors.addElement(message); } } // reportError(String,String,Object[],short) @@ -498,9 +508,10 @@ Object[] arguments, short severity) throws XNIException { - fErrorReporter.reportError(location, domain, key, arguments, severity); + String message = fErrorReporter.reportError(location, domain, key, arguments, severity); if (fAugPSVI) { fErrors.addElement(key); + fErrors.addElement(message); } } // reportError(XMLLocator,String,String,Object[],short) } @@ -594,7 +605,32 @@ */ public void setProperty(String propertyId, Object value) throws XMLConfigurationException { if (propertyId.equals(ROOT_TYPE_DEF)) { - fRootTypeQName = (javax.xml.namespace.QName)value; + if (value == null) { + fRootTypeQName = null; + fRootTypeDefinition = null; + } + else if (value instanceof javax.xml.namespace.QName) { + fRootTypeQName = (javax.xml.namespace.QName) value; + fRootTypeDefinition = null; + } + else { + fRootTypeDefinition = (XSTypeDefinition) value; + fRootTypeQName = null; + } + } + else if (propertyId.equals(ROOT_ELEMENT_DECL)) { + if (value == null) { + fRootElementDeclQName = null; + fRootElementDeclaration = null; + } + else if (value instanceof javax.xml.namespace.QName) { + fRootElementDeclQName = (javax.xml.namespace.QName) value; + fRootElementDeclaration = null; + } + else { + fRootElementDeclaration = (XSElementDecl) value; + fRootElementDeclQName = null; + } } } // setProperty(String,Object) @@ -868,6 +904,7 @@ * @throws XNIException Thrown by handler to signal an error. */ public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { + handleIgnorableWhitespace(text); // call handlers if (fDocumentHandler != null) { @@ -1160,7 +1197,7 @@ /** Schema grammar resolver. */ private final XSGrammarBucket fGrammarBucket = new XSGrammarBucket(); - private final SubstitutionGroupHandler fSubGroupHandler = new SubstitutionGroupHandler(fGrammarBucket); + private final SubstitutionGroupHandler fSubGroupHandler = new SubstitutionGroupHandler(this); /** the DV usd to convert xsi:type to a QName */ // REVISIT: in new simple type design, make things in DVs static, @@ -1248,7 +1285,7 @@ private boolean[] fStrictAssessStack = new boolean[INITIAL_STACK_SIZE]; /** Temporary string buffers. */ - private final StringBuffer fBuffer = new StringBuffer(); + private final StringBuilder fBuffer = new StringBuilder(); /** Whether need to append characters to fBuffer */ private boolean fAppendBuffer = true; @@ -1268,7 +1305,13 @@ /** temporary qname */ private final QName fTempQName = new QName(); + /** value of the "root-type-definition" property. */ private javax.xml.namespace.QName fRootTypeQName = null; + private XSTypeDefinition fRootTypeDefinition = null; + + /** value of the "root-element-declaration" property. */ + private javax.xml.namespace.QName fRootElementDeclQName = null; + private XSElementDecl fRootElementDeclaration = null; private int fIgnoreXSITypeDepth; @@ -1341,9 +1384,6 @@ // cleanup id table fValidationState.resetIDTables(); - //pass the component manager to the factory.. - nodeFactory.reset(componentManager); - // reset schema loader fSchemaLoader.reset(componentManager); @@ -1364,19 +1404,16 @@ fMatcherStack.clear(); - if (!fMayMatchFieldMap.isEmpty()) { - // should only clear this if the last schema had identity constraints. - fMayMatchFieldMap.clear(); - } - // get error reporter fXSIErrorReporter.reset((XMLErrorReporter) componentManager.getProperty(ERROR_REPORTER)); boolean parser_settings = componentManager.getFeature(PARSER_SETTINGS, true); - if (!parser_settings){ + if (!parser_settings) { // parser settings have not been changed fValidationManager.addValidationState(fValidationState); + // the node limit on the SecurityManager may have changed so need to refresh. + nodeFactory.reset(); // Re-parse external schema location properties. XMLSchemaLoader.processExternalHints( fExternalSchemas, @@ -1386,6 +1423,8 @@ return; } + // pass the component manager to the factory.. + nodeFactory.reset(componentManager); // get symbol table. if it's a new one, add symbols to it. SymbolTable symbolTable = (SymbolTable) componentManager.getProperty(SYMBOL_TABLE); @@ -1413,8 +1452,8 @@ fAugPSVI = componentManager.getFeature(SCHEMA_AUGMENT_PSVI, true); fSchemaType = - (String) componentManager.getProperty( - Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE, null); + (String) componentManager.getProperty( + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE, null); fUseGrammarPoolOnly = componentManager.getFeature(USE_GRAMMAR_POOL_ONLY, false); @@ -1424,13 +1463,48 @@ fValidationManager.addValidationState(fValidationState); fValidationState.setSymbolTable(fSymbolTable); - boolean ignoreXSIType; try { - ignoreXSIType = componentManager.getFeature(IGNORE_XSI_TYPE); + final Object rootType = componentManager.getProperty(ROOT_TYPE_DEF); + if (rootType == null) { + fRootTypeQName = null; + fRootTypeDefinition = null; + } + else if (rootType instanceof javax.xml.namespace.QName) { + fRootTypeQName = (javax.xml.namespace.QName) rootType; + fRootTypeDefinition = null; + } + else { + fRootTypeDefinition = (XSTypeDefinition) rootType; + fRootTypeQName = null; + } } catch (XMLConfigurationException e) { - ignoreXSIType = false; + fRootTypeQName = null; + fRootTypeDefinition = null; } + + try { + final Object rootDecl = componentManager.getProperty(ROOT_ELEMENT_DECL); + if (rootDecl == null) { + fRootElementDeclQName = null; + fRootElementDeclaration = null; + } + else if (rootDecl instanceof javax.xml.namespace.QName) { + fRootElementDeclQName = (javax.xml.namespace.QName) rootDecl; + fRootElementDeclaration = null; + } + else { + fRootElementDeclaration = (XSElementDecl) rootDecl; + fRootElementDeclQName = null; + } + } + catch (XMLConfigurationException e) { + fRootElementDeclQName = null; + fRootElementDeclaration = null; + } + + boolean ignoreXSIType = componentManager.getFeature(IGNORE_XSI_TYPE, false); + // An initial value of -1 means that the root element considers itself // below the depth where xsi:type stopped being ignored (which means that // xsi:type attributes will not be ignored for the entire document) @@ -1515,8 +1589,7 @@ public XPathMatcher activateField(Field field, int initialDepth) { ValueStore valueStore = fValueStoreCache.getValueStoreFor(field.getIdentityConstraint(), initialDepth); - setMayMatch(field, Boolean.TRUE); - XPathMatcher matcher = field.createMatcher(this, valueStore); + XPathMatcher matcher = field.createMatcher(valueStore); fMatcherStack.addMatcher(matcher); matcher.startDocumentFragment(); return matcher; @@ -1535,28 +1608,6 @@ } // endValueScopeFor(IdentityConstraint) - /** - * Sets whether the given field is permitted to match a value. - * This should be used to catch instance documents that try - * and match a field several times in the same scope. - * - * @param field The field that may be permitted to be matched. - * @param state Boolean indiciating whether the field may be matched. - */ - public void setMayMatch(Field field, Boolean state) { - fMayMatchFieldMap.put(field, state); - } // setMayMatch(Field, Boolean) - - /** - * Returns whether the given field is permitted to match a value. - * - * @param field The field that may be permitted to be matched. - * @return Boolean indicating whether the field may be matched. - */ - public Boolean mayMatch(Field field) { - return (Boolean) fMayMatchFieldMap.get(field); - } // mayMatch(Field):Boolean - // a utility method for Identity constraints private void activateSelectorFor(IdentityConstraint ic) { Selector selector = ic.getSelector(); @@ -1568,6 +1619,21 @@ matcher.startDocumentFragment(); } + // Implements XSElementDeclHelper interface + public XSElementDecl getGlobalElementDecl(QName element) { + final SchemaGrammar sGrammar = + findSchemaGrammar( + XSDDescription.CONTEXT_ELEMENT, + element.uri, + null, + element, + null); + if (sGrammar != null) { + return sGrammar.getGlobalElementDecl(element.localpart); + } + return null; + } + // // Protected methods // @@ -1823,16 +1889,17 @@ } // get xsi:schemaLocation and xsi:noNamespaceSchemaLocation attributes, - // parse them to get the grammars - - String sLocation = - attributes.getValue(SchemaSymbols.URI_XSI, SchemaSymbols.XSI_SCHEMALOCATION); - String nsLocation = - attributes.getValue(SchemaSymbols.URI_XSI, SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION); - //store the location hints.. we need to do it so that we can defer the loading of grammar until - //there is a reference to a component from that namespace. To provide location hints to the - //application for a namespace - storeLocations(sLocation, nsLocation); + // parse them to get the grammars. But only do this if the grammar can grow. + if (!fUseGrammarPoolOnly) { + String sLocation = + attributes.getValue(SchemaSymbols.URI_XSI, SchemaSymbols.XSI_SCHEMALOCATION); + String nsLocation = + attributes.getValue(SchemaSymbols.URI_XSI, SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION); + //store the location hints.. we need to do it so that we can defer the loading of grammar until + //there is a reference to a component from that namespace. To provide location hints to the + //application for a namespace + storeLocations(sLocation, nsLocation); + } // if we are in the content of "skip", then just skip this element // REVISIT: is this the correct behaviour for ID constraints? -NG @@ -1843,15 +1910,6 @@ return augs; } - //try to find schema grammar by different means.. - SchemaGrammar sGrammar = - findSchemaGrammar( - XSDDescription.CONTEXT_ELEMENT, - element.uri, - null, - element, - attributes); - // if we are not skipping this element, and there is a content model, // we try to find the corresponding decl object for this element. // the reason we move this part of code here is to make sure the @@ -1864,15 +1922,57 @@ if (fCurrCMState[0] == XSCMValidator.FIRST_ERROR) { XSComplexTypeDecl ctype = (XSComplexTypeDecl) fCurrentType; //REVISIT: is it the only case we will have particle = null? - Vector next; + ArrayList next; if (ctype.fParticle != null && (next = fCurrentCM.whatCanGoHere(fCurrCMState)).size() > 0) { String expected = expectedStr(next); - reportSchemaError( - "cvc-complex-type.2.4.a", - new Object[] { element.rawname, expected }); - } else { - reportSchemaError("cvc-complex-type.2.4.d", new Object[] { element.rawname }); + final int[] occurenceInfo = fCurrentCM.occurenceInfo(fCurrCMState); + String elemExpandedQname = (element.uri != null) ? "{"+'"'+element.uri+'"'+":"+element.localpart+"}" : element.localpart; + if (occurenceInfo != null) { + final int minOccurs = occurenceInfo[0]; + final int maxOccurs = occurenceInfo[1]; + final int count = occurenceInfo[2]; + // Check if this is a violation of minOccurs + if (count < minOccurs) { + final int required = minOccurs - count; + if (required > 1) { + reportSchemaError("cvc-complex-type.2.4.h", new Object[] { element.rawname, + fCurrentCM.getTermName(occurenceInfo[3]), Integer.toString(minOccurs), Integer.toString(required) }); + } + else { + reportSchemaError("cvc-complex-type.2.4.g", new Object[] { element.rawname, + fCurrentCM.getTermName(occurenceInfo[3]), Integer.toString(minOccurs) }); + } + } + // Check if this is a violation of maxOccurs + else if (count >= maxOccurs && maxOccurs != SchemaSymbols.OCCURRENCE_UNBOUNDED) { + reportSchemaError("cvc-complex-type.2.4.e", new Object[] { element.rawname, + expected, Integer.toString(maxOccurs) }); + } + else { + reportSchemaError("cvc-complex-type.2.4.a", new Object[] { elemExpandedQname, expected }); + } + } + else { + reportSchemaError("cvc-complex-type.2.4.a", new Object[] { elemExpandedQname, expected }); + } + } + else { + final int[] occurenceInfo = fCurrentCM.occurenceInfo(fCurrCMState); + if (occurenceInfo != null) { + final int maxOccurs = occurenceInfo[1]; + final int count = occurenceInfo[2]; + // Check if this is a violation of maxOccurs + if (count >= maxOccurs && maxOccurs != SchemaSymbols.OCCURRENCE_UNBOUNDED) { + reportSchemaError("cvc-complex-type.2.4.f", new Object[] { fCurrentCM.getTermName(occurenceInfo[3]), Integer.toString(maxOccurs) }); + } + else { + reportSchemaError("cvc-complex-type.2.4.d", new Object[] { element.rawname }); + } + } + else { + reportSchemaError("cvc-complex-type.2.4.d", new Object[] { element.rawname }); + } } } } @@ -1926,23 +2026,21 @@ return augs; } - // 1.2.1.1 A type definition was stipulated by the processor - if (fElementDepth == 0 && fRootTypeQName != null) { - String rootTypeNamespace = fRootTypeQName.getNamespaceURI(); - if (rootTypeNamespace != null && rootTypeNamespace.equals(XMLConstants.NULL_NS_URI)) { - rootTypeNamespace = null; + if (fElementDepth == 0) { + // 1.1.1.1 An element declaration was stipulated by the processor + if (fRootElementDeclaration != null) { + fCurrentElemDecl = fRootElementDeclaration; + checkElementMatchesRootElementDecl(fCurrentElemDecl, element); } - SchemaGrammar grammarForRootType = - findSchemaGrammar( - XSDDescription.CONTEXT_ELEMENT, rootTypeNamespace, null, null, null); - if (grammarForRootType != null) { - fCurrentType = grammarForRootType.getGlobalTypeDecl(fRootTypeQName.getLocalPart()); + else if (fRootElementDeclQName != null) { + processRootElementDeclQName(fRootElementDeclQName, element); } - if (fCurrentType == null) { - String typeName = (fRootTypeQName.getPrefix().equals(XMLConstants.DEFAULT_NS_PREFIX)) ? - fRootTypeQName.getLocalPart() : - fRootTypeQName.getPrefix()+":"+fRootTypeQName.getLocalPart(); - reportSchemaError("cvc-type.1", new Object[] {typeName}); + // 1.2.1.1 A type definition was stipulated by the processor + else if (fRootTypeDefinition != null) { + fCurrentType = fRootTypeDefinition; + } + else if (fRootTypeQName != null) { + processRootTypeQName(fRootTypeQName); } } @@ -1952,6 +2050,14 @@ // case 1: find declaration for root element // case 2: find declaration for element from another namespace if (fCurrentElemDecl == null) { + // try to find schema grammar by different means.. + SchemaGrammar sGrammar = + findSchemaGrammar( + XSDDescription.CONTEXT_ELEMENT, + element.uri, + null, + element, + attributes); if (sGrammar != null) { fCurrentElemDecl = sGrammar.getGlobalElementDecl(element.localpart); } @@ -1963,7 +2069,6 @@ } } - // check if we should be ignoring xsi:type on this element if (fElementDepth == fIgnoreXSITypeDepth && fCurrentElemDecl == null) { fIgnoreXSITypeDepth++; @@ -2012,7 +2117,7 @@ // of this. - SG fXSIErrorReporter.fErrorReporter.reportError( XSMessageFormatter.SCHEMA_DOMAIN, - "cvc-elt.1", + "cvc-elt.1.a", new Object[] { element.rawname }, XMLErrorReporter.SEVERITY_ERROR); } @@ -2189,6 +2294,8 @@ fCurrentPSVI.fTypeDecl = fCurrentType; // PSVI: add notation attribute fCurrentPSVI.fNotation = fNotation; + // PSVI: add nil + fCurrentPSVI.fNil = fNil; } return augs; @@ -2234,7 +2341,7 @@ // validation attempted, validity, and error codes // check extra schema constraints on root element - if (fElementDepth == -1 && fFullChecking) { + if (fElementDepth == -1 && fFullChecking && !fUseGrammarPoolOnly) { XSConstraints.fullSchemaChecking( fGrammarBucket, fSubGroupHandler, @@ -2258,10 +2365,10 @@ int oldCount = fMatcherStack.getMatcherCount(); for (int i = oldCount - 1; i >= 0; i--) { XPathMatcher matcher = fMatcherStack.getMatcherAt(i); - if (fCurrentElemDecl == null) - matcher.endElement(element, null, false, fValidatedInfo.actualValue, fValidatedInfo.actualValueType, fValidatedInfo.itemValueTypes); - - else + if (fCurrentElemDecl == null) { + matcher.endElement(element, fCurrentType, false, fValidatedInfo.actualValue, fValidatedInfo.actualValueType, fValidatedInfo.itemValueTypes); + } + else { matcher.endElement( element, fCurrentType, @@ -2275,6 +2382,7 @@ fDefaultValue == null ? fValidatedInfo.itemValueTypes : fCurrentElemDecl.fDefault.itemValueTypes); + } } if (fMatcherStack.size() > 0) { @@ -2305,7 +2413,9 @@ && id.getCategory() == IdentityConstraint.IC_KEYREF) { ValueStoreBase values = fValueStoreCache.getValueStoreFor(id, selMatcher.getInitialDepth()); - if (values != null) // nothing to do if nothing matched! + // nothing to do if nothing matched, or if not all + // fields are present. + if (values != null && values.fValuesCount == values.fFieldCount) values.endDocumentFragment(); } } @@ -2324,13 +2434,15 @@ // have we reached the end tag of the validation root? if (fElementDepth == 0) { // 7 If the element information item is the validation root, it must be valid per Validation Root Valid (ID/IDREF) (3.3.4). - String invIdRef = fValidationState.checkIDRefID(); + Iterator invIdRefs = fValidationState.checkIDRefID(); fValidationState.resetIDTables(); - if (invIdRef != null) { - reportSchemaError("cvc-id.1", new Object[] { invIdRef }); + if (invIdRefs != null) { + while (invIdRefs.hasNext()) { + reportSchemaError("cvc-id.1", new Object[] { invIdRefs.next() }); + } } // check extra schema constraints - if (fFullChecking) { + if (fFullChecking && !fUseGrammarPoolOnly) { XSConstraints.fullSchemaChecking( fGrammarBucket, fSubGroupHandler, @@ -2390,11 +2502,12 @@ if (fAugPSVI) { augs = getEmptyAugs(augs); - // the 4 properties sent on startElement calls + // the 5 properties sent on startElement calls fCurrentPSVI.fDeclaration = this.fCurrentElemDecl; fCurrentPSVI.fTypeDecl = this.fCurrentType; fCurrentPSVI.fNotation = this.fNotation; fCurrentPSVI.fValidationContext = this.fValidationRoot; + fCurrentPSVI.fNil = this.fNil; // PSVI: validation attempted // nothing below or at the same level has none or partial // (which means this level is strictly assessed, and all chidren @@ -2423,12 +2536,7 @@ if (fDefaultValue != null) fCurrentPSVI.fSpecified = true; - fCurrentPSVI.fNil = fNil; - fCurrentPSVI.fMemberType = fValidatedInfo.memberType; - fCurrentPSVI.fNormalizedValue = fValidatedInfo.normalizedValue; - fCurrentPSVI.fActualValue = fValidatedInfo.actualValue; - fCurrentPSVI.fActualValueType = fValidatedInfo.actualValueType; - fCurrentPSVI.fItemValueTypes = fValidatedInfo.itemValueTypes; + fCurrentPSVI.fValue.copyFrom(fValidatedInfo); if (fStrictAssess) { // get all errors for the current element, its attribute, @@ -2438,7 +2546,7 @@ String[] errors = fXSIErrorReporter.mergeContext(); // PSVI: error codes - fCurrentPSVI.fErrorCodes = errors; + fCurrentPSVI.fErrors = errors; // PSVI: validity fCurrentPSVI.fValidity = (errors == null) ? ElementPSVI.VALIDITY_VALID : ElementPSVI.VALIDITY_INVALID; @@ -2475,7 +2583,7 @@ void storeLocations(String sLocation, String nsLocation) { if (sLocation != null) { - if (!XMLSchemaLoader.tokenizeSchemaLocationStr(sLocation, fLocationPairs)) { + if (!XMLSchemaLoader.tokenizeSchemaLocationStr(sLocation, fLocationPairs, fLocator == null ? null : fLocator.getExpandedSystemId())) { // error! fXSIErrorReporter.reportError( XSMessageFormatter.SCHEMA_DOMAIN, @@ -2491,6 +2599,12 @@ la = new XMLSchemaLoader.LocationArray(); fLocationPairs.put(XMLSymbols.EMPTY_STRING, la); } + if (fLocator != null) { + try { + nsLocation = XMLEntityManager.expandSystemId(nsLocation, fLocator.getExpandedSystemId(), false); + } catch (MalformedURIException e) { + } + } la.addLocation(nsLocation); } @@ -2503,7 +2617,7 @@ short contextType, String namespace, QName enclosingElement, - QName triggeringComponet, + QName triggeringComponent, XMLAttributes attributes) { SchemaGrammar grammar = null; //get the grammar from local pool... @@ -2530,12 +2644,14 @@ } } } - if ((grammar == null && !fUseGrammarPoolOnly) || fNamespaceGrowth) { + + if (!fUseGrammarPoolOnly && (grammar == null || + (fNamespaceGrowth && !hasSchemaComponent(grammar, contextType, triggeringComponent)))) { fXSDDescription.reset(); fXSDDescription.fContextType = contextType; fXSDDescription.setNamespace(namespace); fXSDDescription.fEnclosedElementName = enclosingElement; - fXSDDescription.fTriggeringComponent = triggeringComponet; + fXSDDescription.fTriggeringComponent = triggeringComponent; fXSDDescription.fAttributes = attributes; if (fLocator != null) { fXSDDescription.setBaseSystemId(fLocator.getExpandedSystemId()); @@ -2579,13 +2695,14 @@ if (toParseSchema) { grammar = fSchemaLoader.loadSchema(fXSDDescription, xis, fLocationPairs); } - } catch (IOException ex) { + } + catch (IOException ex) { final String [] locationHints = fXSDDescription.getLocationHints(); fXSIErrorReporter.fErrorReporter.reportError( XSMessageFormatter.SCHEMA_DOMAIN, "schema_reference.4", new Object[] { locationHints != null ? locationHints[0] : XMLSymbols.EMPTY_STRING }, - XMLErrorReporter.SEVERITY_WARNING); + XMLErrorReporter.SEVERITY_WARNING, ex); } } } @@ -2593,6 +2710,24 @@ return grammar; } //findSchemaGrammar + + private boolean hasSchemaComponent(SchemaGrammar grammar, short contextType, QName triggeringComponent) { + if (grammar != null && triggeringComponent != null) { + String localName = triggeringComponent.localpart; + if (localName != null && localName.length() > 0) { + switch (contextType) { + case XSDDescription.CONTEXT_ELEMENT: + return grammar.getElementDeclaration(localName) != null; + case XSDDescription.CONTEXT_ATTRIBUTE: + return grammar.getAttributeDeclaration(localName) != null; + case XSDDescription.CONTEXT_XSITYPE: + return grammar.getTypeDefinition(localName) != null; + } + } + } + return false; + } + private void setLocationHints(XSDDescription desc, String[] locations, SchemaGrammar grammar) { int length = locations.length; if (grammar == null) { @@ -2610,13 +2745,8 @@ int counter = 0; for (int i=0; i= 0 && !fCurrentCM.endContentModel(fCurrCMState)) { String expected = expectedStr(fCurrentCM.whatCanGoHere(fCurrCMState)); - reportSchemaError( - "cvc-complex-type.2.4.b", - new Object[] { element.rawname, expected }); + final int[] occurenceInfo = fCurrentCM.occurenceInfo(fCurrCMState); + if (occurenceInfo != null) { + final int minOccurs = occurenceInfo[0]; + final int count = occurenceInfo[2]; + // Check if this is a violation of minOccurs + if (count < minOccurs) { + final int required = minOccurs - count; + if (required > 1) { + reportSchemaError("cvc-complex-type.2.4.j", new Object[] { element.rawname, + fCurrentCM.getTermName(occurenceInfo[3]), Integer.toString(minOccurs), Integer.toString(required) }); + } + else { + reportSchemaError("cvc-complex-type.2.4.i", new Object[] { element.rawname, + fCurrentCM.getTermName(occurenceInfo[3]), Integer.toString(minOccurs) }); + } + } + else { + reportSchemaError("cvc-complex-type.2.4.b", new Object[] { element.rawname, expected }); + } + } + else { + reportSchemaError("cvc-complex-type.2.4.b", new Object[] { element.rawname, expected }); + } } else { // Constant space algorithm for a{n,m} for n > 1 and m <= unbounded // After the DFA has completed, check minOccurs and maxOccurs @@ -3363,11 +3505,70 @@ } } } - } + } } return actualValue; } // elementLocallyValidComplexType + void processRootTypeQName(final javax.xml.namespace.QName rootTypeQName) { + String rootTypeNamespace = rootTypeQName.getNamespaceURI(); + // Add namespace to symbol table, to make sure it's interned. + // This namespace may be later compared with other values using ==. + rootTypeNamespace = fSymbolTable.addSymbol(rootTypeNamespace); + if (rootTypeNamespace != null && rootTypeNamespace.equals(XMLConstants.NULL_NS_URI)) { + rootTypeNamespace = null; + } + if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(rootTypeNamespace)) { + fCurrentType = SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(rootTypeQName.getLocalPart()); + } + else { + final SchemaGrammar grammarForRootType = findSchemaGrammar( + XSDDescription.CONTEXT_ELEMENT, rootTypeNamespace, null, null, null); + if (grammarForRootType != null) { + fCurrentType = grammarForRootType.getGlobalTypeDecl(rootTypeQName.getLocalPart()); + } + } + if (fCurrentType == null) { + String typeName = (rootTypeQName.getPrefix().equals(XMLConstants.DEFAULT_NS_PREFIX)) ? + rootTypeQName.getLocalPart() : + rootTypeQName.getPrefix()+":"+rootTypeQName.getLocalPart(); + reportSchemaError("cvc-type.1", new Object[] {typeName}); + } + } // processRootTypeQName + + void processRootElementDeclQName(final javax.xml.namespace.QName rootElementDeclQName, final QName element) { + String rootElementDeclNamespace = rootElementDeclQName.getNamespaceURI(); + // Add namespace to symbol table, to make sure it's interned. + // This namespace may be later compared with other values using ==. + rootElementDeclNamespace = fSymbolTable.addSymbol(rootElementDeclNamespace); + if (rootElementDeclNamespace != null && rootElementDeclNamespace.equals(XMLConstants.NULL_NS_URI)) { + rootElementDeclNamespace = null; + } + final SchemaGrammar grammarForRootElement = findSchemaGrammar( + XSDDescription.CONTEXT_ELEMENT, rootElementDeclNamespace, null, null, null); + if (grammarForRootElement != null) { + fCurrentElemDecl = grammarForRootElement.getGlobalElementDecl(rootElementDeclQName.getLocalPart()); + } + if (fCurrentElemDecl == null) { + String declName = (rootElementDeclQName.getPrefix().equals(XMLConstants.DEFAULT_NS_PREFIX)) ? + rootElementDeclQName.getLocalPart() : + rootElementDeclQName.getPrefix()+":"+rootElementDeclQName.getLocalPart(); + reportSchemaError("cvc-elt.1.a", new Object[] {declName}); + } + else { + checkElementMatchesRootElementDecl(fCurrentElemDecl, element); + } + } // processRootElementDeclQName + + void checkElementMatchesRootElementDecl(final XSElementDecl rootElementDecl, final QName element) { + // Report an error if the name of the element does + // not match the name of the specified element declaration. + if (element.localpart != rootElementDecl.fName || + element.uri != rootElementDecl.fTargetNamespace) { + reportSchemaError("cvc-elt.1.b", new Object[] {element.rawname, rootElementDecl.fName}); + } + } // checkElementMatchesRootElementDecl + void reportSchemaError(String key, Object[] arguments) { if (fDoValidation) fXSIErrorReporter.reportError( @@ -3377,14 +3578,13 @@ XMLErrorReporter.SEVERITY_ERROR); } - - private String expectedStr(Vector expected) { - StringBuffer ret = new StringBuffer("{"); + private String expectedStr(ArrayList expected) { + StringBuilder ret = new StringBuilder("{"); int size = expected.size(); for (int i = 0; i < size; i++) { if (i > 0) ret.append(", "); - ret.append(expected.elementAt(i).toString()); + ret.append(expected.get(i).toString()); } ret.append('}'); return ret.toString(); @@ -3520,7 +3720,7 @@ private ShortList fItemValueType = null; /** buffer for error messages */ - final StringBuffer fTempBuffer = new StringBuffer(); + final StringBuilder fTempBuffer = new StringBuilder(); // // Constructors @@ -3645,9 +3845,12 @@ * @param field The field associated to the value. This reference * is used to ensure that each field only adds a value * once within a selection scope. + * @param mayMatch a flag indiciating whether the field may be matched. * @param actualValue The value to add. + * @param valueType Type of the value to add. + * @param itemValueType If the value is a list, a list of types for each of the values in the list. */ - public void addValue(Field field, Object actualValue, short valueType, ShortList itemValueType) { + public void addValue(Field field, boolean mayMatch, Object actualValue, short valueType, ShortList itemValueType) { int i; for (i = fFieldCount - 1; i > -1; i--) { if (fFields[i] == field) { @@ -3662,11 +3865,12 @@ reportSchemaError(code, new Object[] { field.toString(), eName, cName }); return; } - if (Boolean.TRUE != mayMatch(field)) { + if (!mayMatch) { String code = "FieldMultipleMatch"; String cName = fIdentityConstraint.getIdentityConstraintName(); reportSchemaError(code, new Object[] { field.toString(), cName }); - } else { + } + else { fValuesCount++; } fLocalValues[i] = actualValue; @@ -3815,7 +4019,7 @@ } // construct value string - StringBuffer str = new StringBuffer(); + StringBuilder str = new StringBuilder(); for (int i = 0; i < length; i++) { if (i > 0) { str.append(','); @@ -4075,7 +4279,7 @@ // values stores /** stores all global Values stores. */ - protected final Vector fValueStores = new Vector(); + protected final ArrayList fValueStores = new ArrayList(); /** * Values stores associated to specific identity constraints. @@ -4086,7 +4290,7 @@ * descendant-or-self axes occur on recursively-defined * elements. */ - protected final Hashtable fIdentityConstraint2ValueStoreMap = new Hashtable(); + protected final HashMap fIdentityConstraint2ValueStoreMap = new HashMap(); // sketch of algorithm: // - when a constraint is first encountered, its @@ -4108,7 +4312,7 @@ // the fGlobalIDConstraintMap contains descendants+self. // keyrefs can only match descendants+self. protected final Stack fGlobalMapStack = new Stack(); - protected final Hashtable fGlobalIDConstraintMap = new Hashtable(); + protected final HashMap fGlobalIDConstraintMap = new HashMap(); // // Constructors @@ -4124,7 +4328,7 @@ /** Resets the identity constraint cache. */ public void startDocument() { - fValueStores.removeAllElements(); + fValueStores.clear(); fIdentityConstraint2ValueStoreMap.clear(); fGlobalIDConstraintMap.clear(); fGlobalMapStack.removeAllElements(); @@ -4133,7 +4337,7 @@ // startElement: pushes the current fGlobalIDConstraintMap // onto fGlobalMapStack and clears fGlobalIDConstraint map. public void startElement() { - // only clone the hashtable when there are elements + // only clone the map when there are elements if (fGlobalIDConstraintMap.size() > 0) fGlobalMapStack.push(fGlobalIDConstraintMap.clone()); else @@ -4148,7 +4352,7 @@ if (fGlobalMapStack.isEmpty()) { return; // must be an invalid doc! } - Hashtable oldMap = (Hashtable) fGlobalMapStack.pop(); + HashMap oldMap = (HashMap) fGlobalMapStack.pop(); // return if there is no element if (oldMap == null) { return; @@ -4193,7 +4397,7 @@ } else { uniqueValueStore.clear(); } - fValueStores.addElement(uniqueValueStore); + fValueStores.add(uniqueValueStore); activateSelectorFor(icArray[i]); break; case (IdentityConstraint.IC_KEY) : @@ -4208,7 +4412,7 @@ } else { keyValueStore.clear(); } - fValueStores.addElement(keyValueStore); + fValueStores.add(keyValueStore); activateSelectorFor(icArray[i]); break; case (IdentityConstraint.IC_KEYREF) : @@ -4223,7 +4427,7 @@ } else { keyRefValueStore.clear(); } - fValueStores.addElement(keyRefValueStore); + fValueStores.add(keyRefValueStore); activateSelectorFor(icArray[i]); break; } @@ -4267,7 +4471,7 @@ int count = fValueStores.size(); for (int i = 0; i < count; i++) { - ValueStoreBase valueStore = (ValueStoreBase) fValueStores.elementAt(i); + ValueStoreBase valueStore = (ValueStoreBase) fValueStores.get(i); valueStore.endDocument(); } @@ -4295,7 +4499,7 @@ // the purpose of this class is to enable IdentityConstraint,int // pairs to be used easily as keys in Hashtables. - protected class LocalIDKey { + protected static final class LocalIDKey { public IdentityConstraint fId; public int fDepth; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSAttributeDecl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSAttributeDecl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSAttributeDecl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -32,6 +33,7 @@ import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; import com.sun.org.apache.xerces.internal.xs.XSObjectList; import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; +import com.sun.org.apache.xerces.internal.xs.XSValue; /** * The XML representation for an attribute declaration @@ -211,4 +213,8 @@ fDefault.itemValueTypes; } + public XSValue getValueConstraintValue() { + return fDefault; + } + } // class XSAttributeDecl diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSAttributeUseImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSAttributeUseImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSAttributeUseImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2002,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -28,6 +29,7 @@ import com.sun.org.apache.xerces.internal.xs.XSConstants; import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; import com.sun.org.apache.xerces.internal.xs.XSObjectList; +import com.sun.org.apache.xerces.internal.xs.XSValue; /** * The XML representation for an attribute use @@ -142,6 +144,10 @@ fDefault.itemValueTypes; } + public XSValue getValueConstraintValue() { + return fDefault; + } + /** * Optional. Annotations. */ diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSComplexTypeDecl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSComplexTypeDecl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSComplexTypeDecl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -77,7 +78,7 @@ volatile XSCMValidator fCMValidator = null; // the content model that's sufficient for computing UPA - XSCMValidator fUPACMValidator = null; + volatile XSCMValidator fUPACMValidator = null; // list of annotations affiliated with this type XSObjectListImpl fAnnotations = null; @@ -165,12 +166,28 @@ fContentType == XSComplexTypeDecl.CONTENTTYPE_EMPTY) { return null; } - if (fCMValidator == null) - synchronized (this) { - if (fCMValidator == null) { - fCMValidator = cmBuilder.getContentModel(this); + if (fCMValidator == null) { + fCMValidator = getContentModel(cmBuilder, false); + } + return fCMValidator; + } + + public synchronized XSCMValidator getContentModel(CMBuilder cmBuilder, boolean forUPA) { + if (fCMValidator == null) { + if (forUPA) { + if (fUPACMValidator == null) { + fUPACMValidator = cmBuilder.getContentModel(this, true); + + if (fUPACMValidator != null && !fUPACMValidator.isCompactedForUPA()) { + fCMValidator = fUPACMValidator; + } } + return fUPACMValidator; } + else { + fCMValidator = cmBuilder.getContentModel(this, false); + } + } return fCMValidator; } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSConstraints.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSConstraints.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSConstraints.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -488,7 +489,7 @@ } // 3. UPA // get the content model and check UPA - XSCMValidator cm = types[j].getContentModel(cmBuilder); + XSCMValidator cm = types[j].getContentModel(cmBuilder, true); further = false; if (cm != null) { try { diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSElementDecl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSElementDecl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSElementDecl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -34,6 +35,7 @@ import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; import com.sun.org.apache.xerces.internal.xs.XSObjectList; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; +import com.sun.org.apache.xerces.internal.xs.XSValue; /** * The XML representation for an element declaration @@ -384,4 +386,8 @@ fDefault.itemValueTypes; } + public XSValue getValueConstraintValue() { + return fDefault; + } + } // class XSElementDecl diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSElementDeclHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSElementDeclHelper.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,34 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.impl.xs; + +import com.sun.org.apache.xerces.internal.xni.QName; + +/** + * @xerces.internal + * + * @version $Id$ + */ +public interface XSElementDeclHelper { + + public XSElementDecl getGlobalElementDecl(QName element); +} diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSModelImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSModelImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XSModelImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2002-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,13 +21,6 @@ package com.sun.org.apache.xerces.internal.impl.xs; -import java.lang.reflect.Array; -import java.util.AbstractList; -import java.util.Iterator; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.Vector; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMap4Types; @@ -39,6 +33,7 @@ import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition; import com.sun.org.apache.xerces.internal.xs.XSConstants; import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; +import com.sun.org.apache.xerces.internal.xs.XSIDCDefinition; import com.sun.org.apache.xerces.internal.xs.XSModel; import com.sun.org.apache.xerces.internal.xs.XSModelGroupDefinition; import com.sun.org.apache.xerces.internal.xs.XSNamedMap; @@ -48,6 +43,12 @@ import com.sun.org.apache.xerces.internal.xs.XSObject; import com.sun.org.apache.xerces.internal.xs.XSObjectList; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; +import java.lang.reflect.Array; +import java.util.AbstractList; +import java.util.Iterator; +import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.Vector; /** * Implements XSModel: a read-only interface that represents an XML Schema, @@ -72,7 +73,7 @@ false, // model group false, // particle false, // wildcard - false, // idc + true, // idc true, // notation false, // annotation false, // facet @@ -326,6 +327,9 @@ case XSConstants.NOTATION_DECLARATION: tables[i] = fGrammarList[i].fGlobalNotationDecls; break; + case XSConstants.IDENTITY_CONSTRAINT: + tables[i] = fGrammarList[i].fGlobalIDConstraintDecls; + break; } } // for complex/simple types, create a special implementation, @@ -405,6 +409,9 @@ case XSConstants.NOTATION_DECLARATION: table = fGrammarList[i].fGlobalNotationDecls; break; + case XSConstants.IDENTITY_CONSTRAINT: + table = fGrammarList[i].fGlobalIDConstraintDecls; + break; } // for complex/simple types, create a special implementation, @@ -595,6 +602,40 @@ return sg.getGlobalGroupDecl(name, loc); } + /** + * Convenience method. Returns a top-level model group definition. + * + * @param name The name of the definition. + * @param namespace The namespace of the definition, otherwise null. + * @return A top-level model group definition definition or null if such + * definition does not exist. + */ + public XSIDCDefinition getIDCDefinition(String name, String namespace) { + SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); + if (sg == null) { + return null; + } + return (XSIDCDefinition)sg.fGlobalIDConstraintDecls.get(name); + } + + /** + * Convenience method. Returns a top-level model group definition. + * + * @param name The name of the definition. + * @param namespace The namespace of the definition, otherwise null. + * @param loc The schema location where the component was defined + * @return A top-level model group definition definition or null if such + * definition does not exist. + */ + public XSIDCDefinition getIDCDefinition(String name, String namespace, + String loc) { + SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); + if (sg == null) { + return null; + } + return sg.getIDConstraintDecl(name, loc); + } + /** * @see org.apache.xerces.xs.XSModel#getNotationDeclaration(String, String) diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -23,6 +24,7 @@ import com.sun.org.apache.xerces.internal.impl.xpath.XPathException; import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xs.ShortList; import com.sun.org.apache.xerces.internal.xs.XSComplexTypeDefinition; @@ -43,11 +45,11 @@ // /** Field XPath. */ - protected Field.XPath fXPath; + protected final Field.XPath fXPath; /** Identity constraint. */ - protected IdentityConstraint fIdentityConstraint; + protected final IdentityConstraint fIdentityConstraint; // // Constructors @@ -67,7 +69,7 @@ /** Returns the field XPath. */ public com.sun.org.apache.xerces.internal.impl.xpath.XPath getXPath() { return fXPath; - } // getXPath():com.sun.org.apache.xerces.internal.impl.v1.schema.identity.XPath + } // getXPath():org.apache.xerces.impl.v1.schema.identity.XPath /** Returns the identity constraint. */ public IdentityConstraint getIdentityConstraint() { @@ -77,8 +79,8 @@ // factory method /** Creates a field matcher. */ - public XPathMatcher createMatcher(FieldActivator activator, ValueStore store) { - return new Field.Matcher(fXPath, activator, store); + public XPathMatcher createMatcher(ValueStore store) { + return new Field.Matcher(fXPath, store); } // createMatcher(ValueStore):XPathMatcher // @@ -110,15 +112,7 @@ public XPath(String xpath, SymbolTable symbolTable, NamespaceContext context) throws XPathException { - // NOTE: We have to prefix the field XPath with "./" in - // order to handle selectors such as "@attr" that - // select the attribute because the fields could be - // relative to the selector element. -Ac - // Unless xpath starts with a descendant node -Achille Fokoue - // ... or a / or a . - NG - super(((xpath.trim().startsWith("/") ||xpath.trim().startsWith("."))? - xpath:"./"+xpath), - symbolTable, context); + super(fixupXPath(xpath), symbolTable, context); // verify that only one attribute is selected per branch for (int i=0;i(String,SymbolTable,NamespacesContext) + /** Fixup XPath expression. Avoid creating a new String if possible. */ + private static String fixupXPath(String xpath) { + + final int end = xpath.length(); + int offset = 0; + boolean whitespace = true; + char c; + + // NOTE: We have to prefix the field XPath with "./" in + // order to handle selectors such as "@attr" that + // select the attribute because the fields could be + // relative to the selector element. -Ac + // Unless xpath starts with a descendant node -Achille Fokoue + // ... or a / or a . - NG + for (; offset < end; ++offset) { + c = xpath.charAt(offset); + if (whitespace) { + if (!XMLChar.isSpace(c)) { + if (c == '.' || c == '/') { + whitespace = false; + } + else if (c != '|') { + return fixupXPath2(xpath, offset, end); + } + } + } + else if (c == '|') { + whitespace = true; + } + } + return xpath; + + } // fixupXPath(String):String + + private static String fixupXPath2(String xpath, int offset, final int end) { + + StringBuffer buffer = new StringBuffer(end + 2); + for (int i = 0; i < offset; ++i) { + buffer.append(xpath.charAt(i)); + } + buffer.append("./"); + + boolean whitespace = false; + char c; + + for (; offset < end; ++offset) { + c = xpath.charAt(offset); + if (whitespace) { + if (!XMLChar.isSpace(c)) { + if (c == '.' || c == '/') { + whitespace = false; + } + else if (c != '|') { + buffer.append("./"); + whitespace = false; + } + } + } + else if (c == '|') { + whitespace = true; + } + buffer.append(c); + } + return buffer.toString(); + + } // fixupXPath2(String, int, int):String + } // class XPath /** @@ -147,20 +208,19 @@ // Data // - /** Field activator. */ - protected FieldActivator fFieldActivator; + /** Value store for data values. */ + protected final ValueStore fStore; - /** Value store for data values. */ - protected ValueStore fStore; + /** A flag indicating whether the field is allowed to match a value. */ + protected boolean fMayMatch = true; // // Constructors // /** Constructs a field matcher. */ - public Matcher(Field.XPath xpath, FieldActivator activator, ValueStore store) { + public Matcher(Field.XPath xpath, ValueStore store) { super(xpath); - fFieldActivator = activator; fStore = store; } // (Field.XPath,ValueStore) @@ -179,11 +239,11 @@ fStore.reportError(code, new Object[]{fIdentityConstraint.getElementName(), fIdentityConstraint.getIdentityConstraintName()}); } - fStore.addValue(Field.this, actualValue, convertToPrimitiveKind(valueType), convertToPrimitiveKind(itemValueType)); + fStore.addValue(Field.this, fMayMatch, actualValue, convertToPrimitiveKind(valueType), convertToPrimitiveKind(itemValueType)); // once we've stored the value for this field, we set the mayMatch - // member to false so that, in the same scope, we don't match any more + // member to false so that in the same scope, we don't match any more // values (and throw an error instead). - fFieldActivator.setMayMatch(Field.this, Boolean.FALSE); + fMayMatch = false; } // matched(String) private short convertToPrimitiveKind(short valueType) { diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/FieldActivator.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/FieldActivator.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/FieldActivator.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001,2002,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -51,8 +52,6 @@ /** * Request to activate the specified field. This method returns the * matcher for the field. - * It's also important for the implementor to ensure that it marks whether a Field - * is permitted to match a value--that is, to call the setMayMatch(Field, Boolean) method. * * @param field The field to activate. * @param initialDepth the 0-indexed depth in the instance document at which the Selector began to match. @@ -60,24 +59,6 @@ public XPathMatcher activateField(Field field, int initialDepth); /** - * Sets whether the given field is permitted to match a value. - * This should be used to catch instance documents that try - * and match a field several times in the same scope. - * - * @param field The field that may be permitted to be matched. - * @param state Boolean indiciating whether the field may be matched. - */ - public void setMayMatch(Field field, Boolean state); - - /** - * Returns whether the given field is permitted to match a value. - * - * @param field The field that may be permitted to be matched. - * @return Boolean indicating whether the field may be matched. - */ - public Boolean mayMatch(Field field); - - /** * Ends the value scope for the specified identity constraint. * * @param identityConstraint The identity constraint. diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/ValueStore.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/ValueStore.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/ValueStore.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001, 2002,2004,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -54,9 +55,12 @@ * @param field The field associated to the value. This reference * is used to ensure that each field only adds a value * once within a selection scope. + * @param mayMatch a flag indiciating whether the field may be matched. * @param actualValue The value to add. + * @param valueType Type of the value to add. + * @param itemValueType If the value is a list, a list of types for each of the values in the list. */ - public void addValue(Field field, Object actualValue, short valueType, ShortList itemValueType); + public void addValue(Field field, boolean mayMatch, Object actualValue, short valueType, ShortList itemValueType); /** * Since the valueStore will have access to an error reporter, this diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/CMBuilder.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/CMBuilder.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/CMBuilder.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -65,9 +65,10 @@ * Get content model for the a given type * * @param typeDecl get content model for which complex type + * @param forUPA a flag indicating whether it is for UPA * @return a content model validator */ - public XSCMValidator getContentModel(XSComplexTypeDecl typeDecl) { + public XSCMValidator getContentModel(XSComplexTypeDecl typeDecl, boolean forUPA) { // for complex type with empty or simple content, // there is no content model validator @@ -92,7 +93,7 @@ cmValidator = createAllCM(particle); } else { - cmValidator = createDFACM(particle); + cmValidator = createDFACM(particle, forUPA); } //now we are throught building content model and have passed sucessfully of the nodecount check @@ -124,11 +125,11 @@ return allContent; } - XSCMValidator createDFACM(XSParticleDecl particle) { + XSCMValidator createDFACM(XSParticleDecl particle, boolean forUPA) { fLeafCount = 0; fParticleCount = 0; // convert particle tree to CM tree - CMNode node = useRepeatingLeafNodes(particle) ? buildCompactSyntaxTree(particle) : buildSyntaxTree(particle, true); + CMNode node = useRepeatingLeafNodes(particle) ? buildCompactSyntaxTree(particle) : buildSyntaxTree(particle, forUPA, true); if (node == null) return null; // build DFA content model from the CM tree @@ -141,10 +142,31 @@ // 3. convert model groups (a, b, c, ...) or (a | b | c | ...) to // binary tree: (((a,b),c),...) or (((a|b)|c)|...) // 4. make sure each leaf node (XSCMLeaf) has a distinct position - private CMNode buildSyntaxTree(XSParticleDecl particle, boolean optimize) { + private CMNode buildSyntaxTree(XSParticleDecl particle, boolean forUPA, boolean optimize) { int maxOccurs = particle.fMaxOccurs; int minOccurs = particle.fMinOccurs; + + boolean compactedForUPA = false; + if (forUPA) { + // When doing UPA, we reduce the size of the minOccurs/maxOccurs values to make + // processing the DFA faster. For UPA the exact values don't matter. + if (minOccurs > 1) { + if (maxOccurs > minOccurs || particle.getMaxOccursUnbounded()) { + minOccurs = 1; + compactedForUPA = true; + } + else { // maxOccurs == minOccurs + minOccurs = 2; + compactedForUPA = true; + } + } + if (maxOccurs > 1) { + maxOccurs = 2; + compactedForUPA = true; + } + } + short type = particle.fType; CMNode nodeRet = null; @@ -159,6 +181,9 @@ nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue, fParticleCount++, fLeafCount++); // (task 2) expand occurrence values nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs, optimize); + if (nodeRet != null) { + nodeRet.setIsCompactUPAModel(compactedForUPA); + } } else if (type == XSParticleDecl.PARTICLE_MODELGROUP) { // (task 1,3) convert model groups to binary trees @@ -178,12 +203,14 @@ for (int i = 0; i < group.fParticleCount; i++) { // first convert each child to a CM tree temp = buildSyntaxTree(group.fParticles[i], + forUPA, optimize && minOccurs == 1 && maxOccurs == 1 && (group.fCompositor == XSModelGroupImpl.MODELGROUP_SEQUENCE || group.fParticleCount == 1)); // then combine them using binary operation if (temp != null) { + compactedForUPA |= temp.isCompactedForUPA(); if (nodeRet == null) { nodeRet = temp; } @@ -205,6 +232,7 @@ nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, nodeRet); } nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs, false); + nodeRet.setIsCompactUPAModel(compactedForUPA); } } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 2003-2004 The Apache Software Foundation. @@ -73,14 +72,11 @@ public CMNodeFactory() { } - public void reset(XMLComponentManager componentManager){ + public void reset(XMLComponentManager componentManager) { fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); try { fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER); - //we are setting the limit of number of nodes to 3times the maxOccur value.. - if(fSecurityManager != null){ - maxNodeLimit = fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY ; - } + reset(); } catch (XMLConfigurationException e) { fSecurityManager = null; @@ -88,6 +84,13 @@ }//reset() + public void reset() { + // we are setting the limit of number of nodes to 3 times the maxOccurs value. + if (fSecurityManager != null) { + maxNodeLimit = fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY ; + } + } + public CMNode getCMLeafNode(int type, Object leaf, int id, int position) { return new XSCMLeaf(type, leaf, id, position) ; } diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSAllCM.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSAllCM.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSAllCM.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -25,8 +25,6 @@ import com.sun.org.apache.xerces.internal.impl.xs.SubstitutionGroupHandler; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException; import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints; - -import java.util.Vector; import java.util.ArrayList; /** @@ -202,16 +200,17 @@ * have been seen. * * @param state the current state - * @return a Vector whose entries are instances of + * @return a list whose entries are instances of * either XSWildcardDecl or XSElementDecl. */ - public Vector whatCanGoHere(int[] state) { - Vector ret = new Vector(); + public ArrayList whatCanGoHere(int[] state) { + ArrayList ret = new ArrayList(); for (int i = 0; i < fNumElements; i++) { // we only try to look for a matching decl if we have not seen // this element yet. - if (state[i+1] == STATE_START) - ret.addElement(fAllElements[i]); + if (state[i+1] == STATE_START) { + ret.add(fAllElements[i]); + } } return ret; } @@ -220,4 +219,15 @@ return null; } + public int [] occurenceInfo(int[] state) { + return null; + } + + public String getTermName(int termId) { + return null; + } + + public boolean isCompactedForUPA() { + return false; + } } // class XSAllCM diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSCMValidator.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSCMValidator.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSCMValidator.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -23,8 +23,6 @@ import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.impl.xs.SubstitutionGroupHandler; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException; - -import java.util.Vector; import java.util.ArrayList; /** @@ -87,24 +85,60 @@ * have been seen. * * @param state the current state - * @return a Vector whose entries are instances of + * @return a list whose entries are instances of * either XSWildcardDecl or XSElementDecl. */ - public Vector whatCanGoHere(int[] state); + public ArrayList whatCanGoHere(int[] state); /** * Used by constant space algorithm for a{n,m} for n > 1 and * m <= unbounded. Called by a validator if validation of * countent model succeeds after subsuming a{n,m} to a* * (or a+) to check the n and m bounds. - * Returns null if validation of bounds is + * + * @return null if validation of bounds is * successful. Returns a list of strings with error info * if not. Even entries in list returned are error codes * (used to look up properties) and odd entries are parameters * to be passed when formatting error message. Each parameter - * is associated with the error code that preceeds it in + * is associated with the error code that proceeds it in * the list. */ public ArrayList checkMinMaxBounds(); + /** + *

Returns an array containing information about the current repeating term + * or null if no occurrence counting was being performed at the + * current state.

+ * + *

If an array is returned it will have a length == 4 and will contain: + *

    + *
  • a[0] :: min occurs
  • + *
  • a[1] :: max occurs
  • + *
  • a[2] :: current value of the counter
  • + *
  • a[3] :: identifier for the repeating term
  • + *
+ *

+ * + * @param state the current state + * @return an array containing information about the current repeating term + */ + public int [] occurenceInfo(int[] state); + + /** + * Returns the name of the term (element or wildcard) for the given identifier. + * + * @param termId identifier for the element declaration or wildcard + * @return the name of the element declaration or wildcard + */ + public String getTermName(int termId); + + /** + * Checks if this content model has had its min/maxOccurs values reduced for + * purposes of speeding up UPA. If so, this content model should not be used + * for any purpose other than checking unique particle attribution + * + * @return a boolean that says whether this content has been compacted for UPA + */ + public boolean isCompactedForUPA(); } // XSCMValidator diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -31,8 +31,6 @@ import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException; import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints; - -import java.util.Vector; import java.util.ArrayList; import java.util.HashMap; @@ -166,6 +164,8 @@ */ private int fTransTableSize = 0; + private boolean fIsCompactedForUPA; + /** * Array of counters for all the for elements (or wildcards) * of the form a{n,m} where n > 1 and m <= unbounded. Used @@ -1165,10 +1165,10 @@ * have been seen. * * @param state the current state - * @return a Vector whose entries are instances of + * @return a list whose entries are instances of * either XSWildcardDecl or XSElementDecl. */ - public Vector whatCanGoHere(int[] state) { + public ArrayList whatCanGoHere(int[] state) { int curState = state[0]; if (curState < 0) curState = state[1]; @@ -1176,7 +1176,7 @@ fCountingStates[curState] : null; int count = state[2]; - Vector ret = new Vector(); + ArrayList ret = new ArrayList(); for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { int nextState = fTransTable[curState][elemIndex]; if (nextState != -1) { @@ -1196,7 +1196,7 @@ continue; } } - ret.addElement(fElemMap[elemIndex]); + ret.add(fElemMap[elemIndex]); } } return ret; @@ -1231,11 +1231,38 @@ } if (maxOccurs != -1 && count > maxOccurs) { if (result == null) result = new ArrayList(); - result.add("cvc-complex-type.2.4.e"); + result.add("cvc-complex-type.2.4.d.1"); result.add("{" + fElemMap[elemIndex] + "}"); } } return result; } + public int [] occurenceInfo(int[] state) { + if (fCountingStates != null) { + int curState = state[0]; + if (curState < 0) { + curState = state[1]; + } + Occurence o = fCountingStates[curState]; + if (o != null) { + int [] occurenceInfo = new int[4]; + occurenceInfo[0] = o.minOccurs; + occurenceInfo[1] = o.maxOccurs; + occurenceInfo[2] = state[2]; + occurenceInfo[3] = o.elemIndex; + return occurenceInfo; + } + } + return null; + } + + public String getTermName(int termId) { + Object term = fElemMap[termId]; + return (term != null) ? term.toString() : null; + } + + public boolean isCompactedForUPA() { + return fIsCompactedForUPA; + } } // class DFAContentModel diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSEmptyCM.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSEmptyCM.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSEmptyCM.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -18,13 +18,12 @@ * limitations under the License. */ + package com.sun.org.apache.xerces.internal.impl.xs.models; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.impl.xs.SubstitutionGroupHandler; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException; - -import java.util.Vector; import java.util.ArrayList; /** @@ -47,7 +46,7 @@ // start the content model: did not see any children private static final short STATE_START = 0; - private static final Vector EMPTY = new Vector(0); + private static final ArrayList EMPTY = new ArrayList(0); // // Data @@ -126,10 +125,10 @@ * have been seen. * * @param state the current state - * @return a Vector whose entries are instances of + * @return a list whose entries are instances of * either XSWildcardDecl or XSElementDecl. */ - public Vector whatCanGoHere(int[] state) { + public ArrayList whatCanGoHere(int[] state) { return EMPTY; } @@ -137,4 +136,15 @@ return null; } + public int [] occurenceInfo(int[] state) { + return null; + } + + public String getTermName(int termId) { + return null; + } + + public boolean isCompactedForUPA() { + return false; + } } // class XSEmptyCM diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDSimpleTypeTraverser.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDSimpleTypeTraverser.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDSimpleTypeTraverser.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -24,9 +25,7 @@ import java.util.Vector; import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException; -import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory; import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; -import com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl; import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl; import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/util/XS10TypeHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/util/XS10TypeHelper.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,65 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.impl.xs.util; + +import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl; +import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl; +import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; +import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; + +/** + * Class defining utility/helper methods to support XML Schema 1.0 implementation. + * + * @xerces.internal + * + * @author Mukul Gandhi, IBM + */ +public class XS10TypeHelper { + + /* + * Class constructor. + */ + private XS10TypeHelper() { + // a private constructor, to prohibit instantiating this class from an outside class/application. + // this is a good practice, since all methods of this class are "static". + } + + /* + * Get name of an XSD type definition as a string value (which will typically be the value of "name" attribute of a + * type definition, or an internal name determined by the validator for anonymous types). + */ + public static String getSchemaTypeName(XSTypeDefinition typeDefn) { + + String typeNameStr; + if (typeDefn instanceof XSSimpleTypeDefinition) { + typeNameStr = ((XSSimpleTypeDecl) typeDefn).getTypeName(); + } + else { + typeNameStr = ((XSComplexTypeDecl) typeDefn).getTypeName(); + } + + return typeNameStr; + + } // getSchemaTypeName + + +} // class XS10TypeHelper diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,3 +1,6 @@ +/* + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -529,6 +532,7 @@ fComponents.put(LOCALE, null); // Restore initial security manager + fInitSecurityManager.setSecureProcessing(true); fComponents.put(SECURITY_MANAGER, fInitSecurityManager); // Set the Locale back to null. diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/DOMParserImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/DOMParserImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/DOMParserImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2000-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,12 +20,6 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.StringReader; -import java.util.Locale; -import java.util.Stack; -import java.util.StringTokenizer; -import java.util.Vector; - import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl; import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter; import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl; @@ -55,7 +49,11 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; -import com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Locale; +import java.util.Stack; +import java.util.StringTokenizer; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMError; import org.w3c.dom.DOMErrorHandler; @@ -152,7 +150,6 @@ protected final static boolean DEBUG = false; - private Vector fSchemaLocations = new Vector (); private String fSchemaLocation = null; private DOMStringList fRecognizedParameters; @@ -286,17 +283,17 @@ * @throws SAXException Thrown on initialization error. */ public void reset () { - super.reset (); + super.reset(); // get state of namespace-declarations parameter. fNamespaceDeclarations = fConfiguration.getFeature(Constants.DOM_NAMESPACE_DECLARATIONS); // DOM Filter - if (fSkippedElemStack!=null) { - fSkippedElemStack.removeAllElements (); + if (fSkippedElemStack != null) { + fSkippedElemStack.removeAllElements(); } - fSchemaLocations.clear (); + fRejectedElementDepth = 0; fFilterReject = false; fSchemaType = null; @@ -521,15 +518,15 @@ // map DOM schema-location to JAXP schemaSource property // tokenize location string StringTokenizer t = new StringTokenizer (fSchemaLocation, " \n\t\r"); - if (t.hasMoreTokens ()){ - fSchemaLocations.clear (); - fSchemaLocations.add (t.nextToken ()); - while (t.hasMoreTokens ()) { - fSchemaLocations.add (t.nextToken ()); + if (t.hasMoreTokens()) { + ArrayList locations = new ArrayList(); + locations.add (t.nextToken()); + while (t.hasMoreTokens()) { + locations.add (t.nextToken()); } fConfiguration.setProperty ( Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE, - fSchemaLocations.toArray ()); + locations.toArray()); } else { fConfiguration.setProperty ( @@ -865,7 +862,7 @@ */ public DOMStringList getParameterNames () { if (fRecognizedParameters == null){ - Vector parameters = new Vector(); + ArrayList parameters = new ArrayList(); // REVISIT: add Xerces recognized properties/features parameters.add(Constants.DOM_NAMESPACES); @@ -1116,7 +1113,7 @@ } /** - * @see org.w3c.dom.ls.DOMParser#abort() + * @see org.w3c.dom.ls.LSParser#abort() */ public void abort () { // If parse operation is in progress then reset it diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/StandardParserConfiguration.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/StandardParserConfiguration.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/StandardParserConfiguration.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,3 +1,6 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -152,6 +155,10 @@ protected static final String ROOT_TYPE_DEF = Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_TYPE_DEFINITION_PROPERTY; + /** Property identifier: root element declaration. */ + protected static final String ROOT_ELEMENT_DECL = + Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_ELEMENT_DECLARATION_PROPERTY; + // // Data // @@ -259,6 +266,7 @@ SCHEMA_LOCATION, SCHEMA_NONS_LOCATION, ROOT_TYPE_DEF, + ROOT_ELEMENT_DECL, SCHEMA_DV_FACTORY, }; diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,3 +1,6 @@ +/* + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -282,6 +285,10 @@ protected static final String ROOT_TYPE_DEF = Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_TYPE_DEFINITION_PROPERTY; + /** Property identifier: root element declaration. */ + protected static final String ROOT_ELEMENT_DECL = + Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_ELEMENT_DECLARATION_PROPERTY; + /** Property identifier: locale. */ protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; @@ -553,6 +560,7 @@ SCHEMA_LOCATION, SCHEMA_NONS_LOCATION, ROOT_TYPE_DEF, + ROOT_ELEMENT_DECL, LOCALE, SCHEMA_DV_FACTORY, SECURITY_MANAGER, diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,60 +3,20 @@ * DO NOT REMOVE OR ALTER! */ /* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 2000-2002 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * . + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.sun.org.apache.xerces.internal.util; @@ -222,7 +182,7 @@ int index; if (fLength < SIZE_LIMIT) { - index = name.uri != null && !name.uri.equals("") + index = name.uri != null && name.uri.length() != 0 ? getIndexFast(name.uri, name.localpart) : getIndexFast(name.rawname); @@ -1097,29 +1057,6 @@ } // getURI(int,QName) // Implementation methods - public void setSchemaId(int attrIndex, boolean schemaId) { - fAttributes[attrIndex].schemaId = schemaId; - } - - public boolean getSchemaId(int index) { - if (index < 0 || index >= fLength) { - return false; - } - return fAttributes[index].schemaId; - } - - public boolean getSchemaId(String qname) { - int index = getIndex(qname); - return index != -1 ? fAttributes[index].schemaId : false; - } // getType(String):String - - public boolean getSchemaId(String uri, String localName) { - if (!fNamespaces) { - return false; - } - int index = getIndex(uri, localName); - return index != -1 ? fAttributes[index].schemaId : false; - } // getType(String,String):String //XMLBufferListener methods /** @@ -1154,7 +1091,7 @@ // basic info /** Name. */ - public QName name = new QName(); + public final QName name = new QName(); /** Type. */ public String type; @@ -1171,8 +1108,6 @@ /** Specified. */ public boolean specified; - /** Schema ID type. */ - public boolean schemaId; /** * Augmentations information for this attribute. diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/ItemPSVI.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/ItemPSVI.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/ItemPSVI.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -31,19 +32,19 @@ */ public static final short VALIDITY_NOTKNOWN = 0; /** - * Validity value indicating that validation has been strictly assessed + * Validity value indicating that validation has been strictly assessed * and the item in question is invalid according to the rules of schema * validation. */ public static final short VALIDITY_INVALID = 1; /** - * Validation status indicating that schema validation has been performed + * Validation status indicating that schema validation has been performed * and the item in question is valid according to the rules of schema * validation. */ public static final short VALIDITY_VALID = 2; /** - * Validation status indicating that schema validation has been performed + * Validation status indicating that schema validation has been performed * and the item in question has specifically been skipped. */ public static final short VALIDATION_NONE = 0; @@ -53,12 +54,25 @@ */ public static final short VALIDATION_PARTIAL = 1; /** - * Validation status indicating that full schema validation has been + * Validation status indicating that full schema validation has been * performed on the item. */ public static final short VALIDATION_FULL = 2; + /** - * The nearest ancestor element information item with a + * Returns a reference to an immutable instance with the same data + * that this instance of ItemPSVI currently has. + */ + public ItemPSVI constant(); + + /** + * Returns true if this specific instance of + * ItemPSVI is immutable, otherwise false. + */ + public boolean isConstant(); + + /** + * The nearest ancestor element information item with a * [schema information] property (or this element item * itself if it has such a property). For more information refer to * element validation context and attribute validation context . @@ -66,7 +80,7 @@ public String getValidationContext(); /** - * [validity]: determines the validity of the schema item + * [validity]: determines the validity of the schema item * with respect to the validation being attempted. The value will be one * of the constants: VALIDITY_NOTKNOWN, * VALIDITY_INVALID or VALIDITY_VALID. @@ -74,7 +88,7 @@ public short getValidity(); /** - * [validation attempted]: determines the extent to which + * [validation attempted]: determines the extent to which * the schema item has been validated. The value will be one of the * constants: VALIDATION_NONE, * VALIDATION_PARTIAL or VALIDATION_FULL. @@ -82,15 +96,25 @@ public short getValidationAttempted(); /** - * [schema error code]: a list of error codes generated from + * [schema error code]: a list of error codes generated from * the validation attempt or an empty StringList if no * errors occurred during the validation attempt. */ public StringList getErrorCodes(); /** + * A list of error messages generated from the validation attempt or + * an empty StringList if no errors occurred during the + * validation attempt. The indices of error messages in this list are + * aligned with those in the [schema error code] list. + */ + public StringList getErrorMessages(); + + /** * [schema normalized value]: the normalized value of this * item after validation. + * + * @deprecated Use getSchemaValue().getNormalizedValue() instead */ public String getSchemaNormalizedValue(); @@ -100,6 +124,8 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getSchemaValue().getActualValue() instead */ public Object getActualNormalizedValue() throws XSException; @@ -113,11 +139,12 @@ * method returns LISTOFUNION_DT. To query the actual value * of the list or list of union type definitions use * itemValueTypes. If the actualNormalizedValue - * is null, this method returns UNAVAILABLE_DT - * . + * is null, this method returns UNAVAILABLE_DT. * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getSchemaValue().getActualValueType() instead */ public short getActualNormalizedValueType() throws XSException; @@ -152,12 +179,22 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getSchemaValue().getListValueTypes() instead */ public ShortList getItemValueTypes() throws XSException; /** - * [type definition]: an item isomorphic to the type + * If this item has a simple type definition or a complex type with simple + * content, then return the value with respect to the simple type. If + * this item doesn't have a simple-typed value, the behavior of this method + * is not specified. + */ + public XSValue getSchemaValue(); + + /** + * [type definition]: an item isomorphic to the type * definition used to validate the schema item. */ public XSTypeDefinition getTypeDefinition(); diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSAttributeDeclaration.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSAttributeDeclaration.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSAttributeDeclaration.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -51,6 +52,8 @@ /** * Value constraint: The constraint value with respect to the [type * definition], otherwise null. + * + * @deprecated Use getValueConstraintValue().getNormalizedValue() instead */ public String getConstraintValue(); @@ -61,6 +64,8 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getActualValue() instead */ public Object getActualVC() throws XSException; @@ -78,6 +83,8 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getActualValueType() instead */ public short getActualVCType() throws XSException; @@ -94,11 +101,18 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getListValueTypes() instead */ public ShortList getItemValueTypes() throws XSException; /** + * The actual value of the default or fixed value constraint. + */ + public XSValue getValueConstraintValue(); + + /** * An annotation if it exists, otherwise null. * If not null then the first [annotation] from the sequence of annotations. */ diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSAttributeUse.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSAttributeUse.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSAttributeUse.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -38,12 +39,14 @@ public XSAttributeDeclaration getAttrDeclaration(); /** - * Value Constraint: one of default, fixed. + * Value Constraint: one of default, fixed, or none. */ public short getConstraintType(); /** * Value Constraint: The constraint value, otherwise null. + * + * @deprecated Use getValueConstraintValue().getNormalizedValue() instead */ public String getConstraintValue(); @@ -54,6 +57,8 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getActualValue() instead */ public Object getActualVC() throws XSException; @@ -67,11 +72,12 @@ * method returns LISTOFUNION_DT. To query the actual * constraint value of the list or list of union type definitions use * itemValueTypes. If the actualNormalizedValue - * is null, this method returns UNAVAILABLE_DT - * . + * is null, this method returns UNAVAILABLE_DT. * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getActualValueType() instead */ public short getActualVCType() throws XSException; @@ -88,11 +94,18 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getListValueTypes() instead */ public ShortList getItemValueTypes() throws XSException; /** + * The actual value of the default or fixed value constraint. + */ + public XSValue getValueConstraintValue(); + + /** * A sequence of [annotations] or an empty XSObjectList. */ public XSObjectList getAnnotations(); diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSElementDeclaration.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSElementDeclaration.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSElementDeclaration.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -52,6 +53,8 @@ /** * [Value constraint]: the constraint value with respect to the [type * definition], otherwise null. + * + * @deprecated Use getValueConstraintValue().getNormalizedValue() instead */ public String getConstraintValue(); @@ -62,6 +65,8 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getActualValue() instead */ public Object getActualVC() throws XSException; @@ -75,11 +80,12 @@ * method returns LISTOFUNION_DT. To query the actual * constraint value of the list or list of union type definitions use * itemValueTypes. If the actualNormalizedValue - * is null, this method returns UNAVAILABLE_DT - * . + * is null, this method returns UNAVAILABLE_DT. * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getActualValueType() instead */ public short getActualVCType() throws XSException; @@ -96,11 +102,18 @@ * @exception XSException * NOT_SUPPORTED_ERR: Raised if the implementation does not support this * method. + * + * @deprecated Use getValueConstraintValue().getListValueTypes() instead */ public ShortList getItemValueTypes() throws XSException; /** + * The actual value of the default or fixed value constraint. + */ + public XSValue getValueConstraintValue(); + + /** * If nillable is true, then an element may also be valid if it carries * the namespace qualified attribute with local name nil * from namespace http://www.w3.org/2001/XMLSchema-instance diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSFacet.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSFacet.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSFacet.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -37,6 +38,24 @@ public String getLexicalFacetValue(); /** + * If this facet is length, minLength, maxLength, totalDigits, or + * fractionDigits, and if the value can fit in "int", then return the value + * of the facet as an int. If the value can't fit, return -1. Use + * getActualFacetValue() to get the BigInteger representation. For all other + * facets, return 0. + */ + public int getIntFacetValue(); + + /** + * If this facet is minInclusive, maxInclusive, minExclusive, or + * maxExclusive, then return the actual value of the facet. If this facet + * is length, minLength, maxLength, totalDigits, or fractionDigits, then + * return a BigInteger representation of the value. If this facet is + * whiteSpace, then return the String representation of the facet. + */ + public Object getActualFacetValue(); + + /** * [Facets]: check whether a facet is fixed. */ public boolean getFixed(); diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSModel.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSModel.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSModel.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -44,7 +45,9 @@ /** * Returns a list of top-level components, i.e. element declarations, - * attribute declarations, etc. + * attribute declarations, etc. Identity-constraint definitions are also + * considered top-level. + * * @param objectType The type of the declaration, i.e. * ELEMENT_DECLARATION. Note that * XSTypeDefinition.SIMPLE_TYPE and @@ -60,7 +63,9 @@ /** * Convenience method. Returns a list of top-level component declarations * that are defined within the specified namespace, i.e. element - * declarations, attribute declarations, etc. + * declarations, attribute declarations, etc. Identity-constraint + * definitions are also considered top-level. + * * @param objectType The type of the declaration, i.e. * ELEMENT_DECLARATION. * @param namespace The namespace to which the declaration belongs or @@ -146,6 +151,17 @@ String namespace); /** + * Convenience method. Returns an identity-constraint definition. + * @param name The name of the definition. + * @param namespace The namespace of the definition, otherwise + * null. + * @return An identity-constraint definition or null if such + * a declaration does not exist. + */ + public XSIDCDefinition getIDCDefinition(String name, + String namespace); + + /** * Convenience method. Returns a list containing the members of the * substitution group for the given XSElementDeclaration * or an empty XSObjectList if the substitution group diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSMultiValueFacet.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSMultiValueFacet.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSMultiValueFacet.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,6 +21,8 @@ package com.sun.org.apache.xerces.internal.xs; +import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList; + /** * Describes a multi-value constraining facets: pattern and enumeration. */ @@ -36,6 +39,11 @@ public StringList getLexicalFacetValues(); /** + * A list of XSValue objects. The actual enumeration values. + */ + public ObjectList getEnumerationValues(); + + /** * A sequence of [annotations] or an empty XSObjectList. */ public XSObjectList getAnnotations(); diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSNamespaceItem.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSNamespaceItem.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSNamespaceItem.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -33,7 +34,9 @@ /** * [schema components]: a list of top-level components, i.e. element - * declarations, attribute declarations, etc. + * declarations, attribute declarations, etc. Identity-constraint + * definitions are also considered top-level. + * * @param objectType The type of the declaration, i.e. * ELEMENT_DECLARATION. Note that * XSTypeDefinition.SIMPLE_TYPE and @@ -102,6 +105,14 @@ public XSNotationDeclaration getNotationDeclaration(String name); /** + * Convenience method. Returns an identity-constraint definition. + * @param name The name of the definition. + * @return An identity-constraint definition or null if such + * a declaration does not exist. + */ + public XSIDCDefinition getIDCDefinition(String name); + + /** * [document location] - a list of location URIs for the documents that * contributed to the XSModel. */ diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSSimpleTypeDefinition.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSSimpleTypeDefinition.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSSimpleTypeDefinition.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -235,6 +236,11 @@ public XSObjectList getMultiValueFacets(); /** + * A constraining facet object. An instance of XSFacet or XSMultiValueFacet. + */ + public XSObject getFacet(int facetType); + + /** * A sequence of [annotations] or an empty XSObjectList. */ public XSObjectList getAnnotations(); diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/XSValue.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,108 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.xs; + +/** + * Represents an actual value of a simple type. + */ +public interface XSValue { + + /** + * The schema normalized value. + * @return The normalized value. + */ + public String getNormalizedValue(); + + /** + * The actual value. null if the value is in error. + * @return The actual value. + */ + public Object getActualValue(); + + /** + * The declared simple type definition used to validate this value. + * It can be a union type. + * @return The declared simple type definition + */ + public XSSimpleTypeDefinition getTypeDefinition(); + + /** + * If the declared simple type definition is a union, return the member + * type actually used to validate the value. Otherwise null. + * @return The member type + */ + public XSSimpleTypeDefinition getMemberTypeDefinition(); + + /** + * If getTypeDefinition() returns a list type whose item type + * is a union type, then this method returns a list with the same length + * as the value list, for simple types that actually validated + * the corresponding item in the value. + * @return A list of type definitions + */ + public XSObjectList getMemberTypeDefinitions(); + + /** + * The actual value built-in datatype, e.g. + * STRING_DT, SHORT_DT. If the type definition of this + * value is a list type definition, this method returns + * LIST_DT. If the type definition of this value is a list + * type definition whose item type is a union type definition, this + * method returns LISTOFUNION_DT. To query the actual value + * of the list or list of union type definitions use + * itemValueTypes(). + * @return The actual value type + */ + public short getActualValueType(); + + /** + * In the case the actual value represents a list, i.e. the + * actualNormalizedValueType is LIST_DT, the + * returned array consists of one type kind which represents the itemType + * . For example: + *
 <simpleType name="listtype"> <list
+     * itemType="positiveInteger"/> </simpleType> <element
+     * name="list" type="listtype"/> ... <list>1 2 3</list> 
+ * + * The schemaNormalizedValue value is "1 2 3", the + * actualNormalizedValueType value is LIST_DT, + * and the itemValueTypes is an array of size 1 with the + * value POSITIVEINTEGER_DT. + *
If the actual value represents a list type definition whose item + * type is a union type definition, i.e. LISTOFUNION_DT, + * for each actual value in the list the array contains the + * corresponding memberType kind. For example: + *
 <simpleType
+     * name='union_type' memberTypes="integer string"/> <simpleType
+     * name='listOfUnion'> <list itemType='union_type'/>
+     * </simpleType> <element name="list" type="listOfUnion"/>
+     * ... <list>1 2 foo</list> 
+ * The + * schemaNormalizedValue value is "1 2 foo", the + * actualNormalizedValueType is LISTOFUNION_DT + * , and the itemValueTypes is an array of size 3 with the + * following values: INTEGER_DT, INTEGER_DT, STRING_DT. + * @return The list value types + */ + public ShortList getListValueTypes(); + +} diff -r d1480cb49283 -r 98b357b2e8a6 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/datatypes/ByteList.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/datatypes/ByteList.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xs/datatypes/ByteList.java Wed Jul 05 20:04:43 2017 +0200 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2004,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.xs.datatypes; import java.util.List; @@ -60,4 +62,8 @@ */ public byte item(int index) throws XSException; + /** + * Construct and return a byte array for bytes contained in this list. + */ + public byte[] toByteArray(); } diff -r d1480cb49283 -r 98b357b2e8a6 jaxws/.hgtags --- a/jaxws/.hgtags Thu Oct 16 14:55:17 2014 -0700 +++ b/jaxws/.hgtags Wed Jul 05 20:04:43 2017 +0200 @@ -280,3 +280,4 @@ 838a2f693e51b869e7bc26a20afffdde1300394e jdk9-b32 77a45995dd3b6e57805475ae3111ac6f7db7749e jdk9-b33 28ea43d925f1e5250976097a2977dd3e66e11f0b jdk9-b34 +afe0c89e2edbdfb1a7ceff3d9b3ff46c4186202f jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 jdk/.hgtags --- a/jdk/.hgtags Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/.hgtags Wed Jul 05 20:04:43 2017 +0200 @@ -277,3 +277,4 @@ 8bdf7083b5bd02aa330ba622895e586dd3378d37 jdk9-b32 60fe681c30bc3821545a2506d4d3c2e04073f67c jdk9-b33 21568031434d7a9dbb0cc6516cc3183d349c2253 jdk9-b34 +e549291a0227031310fa91c574891f892d27f959 jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-java.base.gmk --- a/jdk/make/gensrc/Gensrc-java.base.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-java.base.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -25,10 +25,6 @@ include GensrcCommon.gmk -# TODO: maybe split into separate modules? -include GensrcProperties.gmk -GENSRC_JAVA_BASE += $(GENSRC_PROPERTIES) - include GensrcLocaleData.gmk include GensrcCharacterData.gmk include GensrcMisc.gmk @@ -37,6 +33,34 @@ include GensrcBuffer.gmk include GensrcExceptions.gmk +################################################################################ + +include GensrcProperties.gmk + +$(eval $(call SetupCompileProperties,LIST_RESOURCE_BUNDLE, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/launcher/resources)), \ + ListResourceBundle)) + +$(eval $(call SetupCompileProperties,SUN_UTIL, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/resources)), \ + sun.util.resources.LocaleNamesBundle)) + +GENSRC_JAVA_BASE += $(LIST_RESOURCE_BUNDLE) $(SUN_UTIL) + +# Some resources bundles are already present as java files but still need to be +# copied to zh_HK locale. +$(eval $(call SetupCopy-zh_HK,COPY_ZH_HK, \ + $(addprefix $(JDK_TOPDIR)/src/java.base/share/classes/, \ + sun/misc/resources/Messages_zh_TW.java \ + sun/security/util/AuthResources_zh_TW.java \ + sun/security/util/Resources_zh_TW.java))) + +GENSRC_JAVA_BASE += $(COPY_ZH_HK) + +################################################################################ + java.base: $(GENSRC_JAVA_BASE) all: java.base diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-java.desktop.gmk --- a/jdk/make/gensrc/Gensrc-java.desktop.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-java.desktop.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -38,6 +38,48 @@ include GensrcSwing.gmk +################################################################################ + +include GensrcProperties.gmk + +PROP_SRC_DIRS := \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/sun/awt/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/accessibility/internal/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/swing/internal/plaf/metal/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/swing/internal/plaf/synth/resources \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/sun/print/resources \ + # + +ifeq ($(OPENJDK_TARGET_OS), macosx) + PROP_SRC_DIRS += \ + $(JDK_TOPDIR)/src/java.desktop/macosx/classes/com/apple/laf/resources \ + $(JDK_TOPDIR)/src/java.desktop/macosx/classes/sun/awt/resources \ + # +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/windows/classes/sun/awt/windows +else + PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources +endif + +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ + $(filter %.properties, $(call CacheFind, $(PROP_SRC_DIRS))), ListResourceBundle)) + +GENSRC_JAVA_DESKTOP += $(COMPILE_PROPERTIES) + +# Some resources bundles are already present as java files but still need to be +# copied to zh_HK locale. +$(eval $(call SetupCopy-zh_HK,COPY_ZH_HK, \ + $(JDK_TOPDIR)/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_zh_TW.java)) + +GENSRC_JAVA_DESKTOP += $(COPY_ZH_HK) + +################################################################################ + java.desktop: $(GENSRC_JAVA_DESKTOP) all: java.desktop diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-java.logging.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/gensrc/Gensrc-java.logging.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,43 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include GensrcCommon.gmk + +################################################################################ + +include GensrcProperties.gmk + +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/java.logging/share/classes/sun/util/logging/resources)), \ + ListResourceBundle)) + +TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ + +all: $(TARGETS) + +.PHONY: all diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-java.management.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/gensrc/Gensrc-java.management.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,43 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include GensrcCommon.gmk + +################################################################################ + +include GensrcProperties.gmk + +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources)), \ + ListResourceBundle)) + +TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ + +all: $(TARGETS) + +.PHONY: all diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-jdk.dev.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/gensrc/Gensrc-jdk.dev.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,43 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include GensrcCommon.gmk + +################################################################################ + +include GensrcProperties.gmk + +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/jdk.dev/share/classes/sun/tools/jar/resources)), \ + ListResourceBundle)) + +TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ + +all: $(TARGETS) + +.PHONY: all diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-jdk.jdi.gmk --- a/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -69,6 +69,17 @@ ################################################################################ +include GensrcProperties.gmk + +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/jdk.jdi/share/classes/com/sun/tools/jdi/resources)), \ + ListResourceBundle)) + +GENSRC_JDK_JDI += $(COMPILE_PROPERTIES) + +################################################################################ + jdk.jdi: $(GENSRC_JDK_JDI) all: jdk.jdi diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/Gensrc-jdk.localedata.gmk --- a/jdk/make/gensrc/Gensrc-jdk.localedata.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-jdk.localedata.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -31,6 +31,20 @@ include GensrcLocaleData.gmk include GensrcCLDR.gmk +################################################################################ + +include GensrcProperties.gmk + +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ + $(filter %.properties, \ + $(call CacheFind, $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/resources)), \ + sun.util.resources.LocaleNamesBundle)) + +# Skip generating zh_HK from zh_TW for this module. +GENSRC_JDK_LOCALEDATA += $(filter-out %_zh_HK.java, $(COMPILE_PROPERTIES)) + +################################################################################ + jdk.localedata: $(GENSRC_JDK_LOCALEDATA) all: jdk.localedata diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/gensrc/GensrcProperties.gmk --- a/jdk/make/gensrc/GensrcProperties.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/gensrc/GensrcProperties.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -23,132 +23,81 @@ # questions. # -# All .properties files to be compiled are appended to this variable. -ALL_COMPILED_PROPSOURCES := -# All generated .java files from compilation are appended to this variable. -ALL_COMPILED_PROPJAVAS := -# The (very long) command line for compilation, stored in a file, prior to use. -COMPILE_PROPCMDLINE := +# This file defines macros that sets up rules for generating java classes +# from resource bundle properties files. -define add_properties_to_compile - # $1 is the name of the properties group - # $2 is the files belonging to this group - # $3 is the super class for the generated java file. +################################################################################ +# Helper macro for SetupCopy-zh_HK. +define SetupOneCopy-zh_HK + $1_$2_TARGET := $$(patsubst $(JDK_TOPDIR)/src/$(MODULE)/share/classes/%, \ + $(JDK_OUTPUTDIR)/gensrc/$(MODULE)/%, \ + $$(subst _zh_TW,_zh_HK, $2)) - # Convert /jdk/src//share/classes/sun/util/resources/CurrencyNames_sv.properties - # to /jdk/gensrc/ $$@ + + $1 += $$($1_$2_TARGET) +endef - # Accumulate all found properties files. - ALL_COMPILED_PROPSOURCES += $2 - - # Generate the list of to be created java files. - ALL_COMPILED_PROPJAVAS += $$($1_PROPJAVAS) - - # Now generate a sequence of - # "-compile ...CurrencyNames_sv.properties ...CurrencyNames_sv.java ListResourceBundle" - # suitable to be fed into the CompileProperties command. - COMPILE_PROPCMDLINE += $$(subst _SPACE_,$(SPACE),$$(join $$(addprefix -compile_SPACE_, $2), \ - $$(addsuffix _SPACE_$(strip $3), \ - $$(addprefix _SPACE_, $$($1_PROPJAVAS))))) +################################################################################ +# Creates rules for copying zh_TW resources to zh_HK. +# Param 1 - Variable to add targets to +# Param 2 - Files to copy from +define SetupCopy-zh_HK + $$(foreach f, $2, $$(eval $$(call SetupOneCopy-zh_HK,$1,$$f))) endef ################################################################################ -# Some packages have properties that need to be converted to java source files. -COMPILE_PROP_SRC_FILES := \ - $(filter %.properties, $(call CacheFind, \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/accessibility/internal/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/swing/internal/plaf/metal/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/swing/internal/plaf/synth/resources \ - $(JDK_TOPDIR)/src/jdk.jdi/share/classes/com/sun/tools/jdi/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/sun/awt/resources \ - $(JDK_TOPDIR)/src/java.base/share/classes/sun/launcher/resources \ - $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/sun/print/resources \ - $(JDK_TOPDIR)/src/jdk.dev/share/classes/sun/tools/jar/resources \ - $(JDK_TOPDIR)/src/java.logging/share/classes/sun/util/logging/resources)) \ - # +# Creates a rule that runs CompileProperties on a set of properties files. +# Param 1 - Variable to add targets to, must not contain space +# Param 2 - Properties files to process +# Param 3 - The super class for the generated classes +define SetupCompileProperties + $1_SRCS := $2 + $1_CLASS := $3 + + # Convert .../src//share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties + # to .../langtools/gensrc//com/sun/tools/javac/resources/javac_zh_CN.java + # Strip away prefix and suffix, leaving for example only: + # "/share/classes/com/sun/tools/javac/resources/javac_zh_CN" + $1_JAVAS := $$(patsubst $(JDK_TOPDIR)/src/%, \ + $(JDK_OUTPUTDIR)/gensrc/%, \ + $$(patsubst %.properties, %.java, \ + $$(subst /share/classes,, $$($1_SRCS)))) + + # Generate the package dirs for the to be generated java files. Sort to remove + # duplicates. + $1_DIRS := $$(sort $$(dir $$($1_JAVAS))) -ifeq ($(OPENJDK_TARGET_OS), macosx) - COMPILE_PROP_SRC_FILES += \ - $(filter %.properties, $(call CacheFind, \ - $(JDK_TOPDIR)/src/java.desktop/macosx/classes/com/apple/laf/resources \ - $(JDK_TOPDIR)/src/java.desktop/macosx/classes/sun/awt/resources)) \ - # -endif + # Now generate a sequence of: + # "-compile ...javac_zh_CN.properties ...javac_zh_CN.java java.util.ListResourceBundle" + # suitable to be fed into the CompileProperties command. + $1_CMDLINE := $$(subst _SPACE_, $(SPACE), \ + $$(join $$(addprefix -compile_SPACE_, $$($1_SRCS)), \ + $$(addsuffix _SPACE_$$($1_CLASS), \ + $$(addprefix _SPACE_, $$($1_JAVAS))))) + + $1_TARGET := $(JDK_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.done + $1_CMDLINE_FILE := $(JDK_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.cmdline -ifeq ($(OPENJDK_TARGET_OS), windows) - COMPILE_PROP_SRC_FILES += \ - $(filter %.properties, $(call CacheFind, \ - $(JDK_TOPDIR)/src/java.desktop/windows/classes/sun/awt/windows)) \ - # -else # ! windows - COMPILE_PROP_SRC_FILES += \ - $(filter %.properties, $(call CacheFind, \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources)) \ - # -endif + # Now setup the rule for the generation of the resource bundles. + $$($1_TARGET): $$($1_SRCS) $$($1_JAVAS) $(BUILD_TOOLS_JDK) + $(MKDIR) -p $$(@D) $$($1_DIRS) + $(ECHO) Compiling $$(words $$($1_SRCS)) properties into resource bundles for $(MODULE) + $(RM) $$($1_CMDLINE_FILE) + $$(call ListPathsSafely,$1_CMDLINE,\n, >> $$($1_CMDLINE_FILE)) + $(TOOL_COMPILEPROPERTIES) -quiet @$$($1_CMDLINE_FILE) + $(TOUCH) $$@ -$(eval $(call add_properties_to_compile,LIST_RESOURCE_BUNDLE, \ - $(COMPILE_PROP_SRC_FILES), ListResourceBundle)) + $$($1_JAVAS): $$($1_SRCS) -# sun/util/resources -$(eval $(call add_properties_to_compile,SUN_UTIL, \ - $(filter %.properties, \ - $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/resources) \ - $(call CacheFind, $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/resources)), \ - sun.util.resources.LocaleNamesBundle)) + # Create zh_HK versions of all zh_TW files created above + $$(eval $$(call SetupCopy-zh_HK,$1_HK,$$(filter %_zh_TW.java, $$($1_JAVAS)))) + # The zh_HK copy must wait for the compile properties tool to run + $$($1_HK): $$($1_TARGET) + + $1 += $$($1_JAVAS) $$($1_TARGET) $$($1_HK) +endef ################################################################################ -# Now setup the rule for the generation of the resource bundles. -$(JDK_OUTPUTDIR)/gensrc/_the.compiled_properties: $(ALL_COMPILED_PROPSOURCES) $(BUILD_TOOLS_JDK) - # Generate all output directories in advance since the build tool does not do that... - $(MKDIR) -p $(sort $(dir $(ALL_COMPILED_PROPJAVAS))) - $(ECHO) Compiling $(words $(ALL_COMPILED_PROPSOURCES)) properties into resource bundles - $(call ListPathsSafely,COMPILE_PROPCMDLINE,\n, >> $(JDK_OUTPUTDIR)/gensrc/_the.cmdline) - $(TOOL_COMPILEPROPERTIES) -quiet @$(JDK_OUTPUTDIR)/gensrc/_the.cmdline - $(TOUCH) $@ - -$(ALL_COMPILED_PROPJAVAS): $(JDK_OUTPUTDIR)/gensrc/_the.compiled_properties - -################################################################################ -# Some zh_HK resources are just copies of zh_TW - -define convert_tw_to_hk - $(MKDIR) -p $(@D) - $(CAT) $< | $(SED) -e '/class/s/_zh_TW/_zh_HK/' > $@ -endef - -# Some are copies of existing sources -$(JDK_OUTPUTDIR)/gensrc/java.desktop/%_zh_HK.java: \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/%_zh_TW.java - $(call convert_tw_to_hk) - -$(JDK_OUTPUTDIR)/gensrc/java.base/%_zh_HK.java: \ - $(JDK_TOPDIR)/src/java.base/share/classes/%_zh_TW.java - $(call convert_tw_to_hk) - -# Others are copies of sources generated by this makefile -$(JDK_OUTPUTDIR)/gensrc/%_zh_HK.java: $(JDK_OUTPUTDIR)/gensrc/%_zh_TW.java - $(call convert_tw_to_hk) - -# The existing sources -ZH_HK_JAVA := java.desktop/sun/applet/resources/MsgAppletViewer_zh_HK.java \ - java.base/sun/misc/resources/Messages_zh_HK.java \ - java.base/sun/security/util/AuthResources_zh_HK.java \ - java.base/sun/security/util/Resources_zh_HK.java - -ZH_HK_JAVA_FILES := $(addprefix $(JDK_OUTPUTDIR)/gensrc/, $(ZH_HK_JAVA)) \ - $(filter-out $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/zh/%, \ - $(subst _zh_TW,_zh_HK,$(filter %_zh_TW.java, $(ALL_COMPILED_PROPJAVAS)))) - -################################################################################ - -GENSRC_PROPERTIES := $(ALL_COMPILED_PROPJAVAS) $(ZH_HK_JAVA_FILES) diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/lib/CoreLibraries.gmk --- a/jdk/make/lib/CoreLibraries.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/lib/CoreLibraries.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -224,7 +224,7 @@ $(call SET_SHARED_LIBRARY_ORIGIN) \ $(EXPORT_ZIP_FUNCS), \ LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \ - -export:ZIP_ReadEntry -export:ZIP_GetNextEntry jvm.lib \ + -export:ZIP_ReadEntry -export:ZIP_GetNextEntry -export:ZIP_CRC32 jvm.lib \ $(WIN_JAVA_LIB), \ LDFLAGS_SUFFIX_linux := -ljvm -ljava $(LIBZ), \ LDFLAGS_SUFFIX_solaris := -ljvm -ljava $(LIBZ) -lc, \ diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/mapfiles/libjfr/mapfile-vers --- a/jdk/make/mapfiles/libjfr/mapfile-vers Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/mapfiles/libjfr/mapfile-vers Wed Jul 05 20:04:43 2017 +0200 @@ -10,8 +10,13 @@ Java_oracle_jrockit_jfr_Process_getpid; Java_oracle_jrockit_jfr_Timing_counterTime; Java_oracle_jrockit_jfr_Timing_init; - Java_oracle_jrockit_jfr_NativeLogger_output0; - Java_oracle_jrockit_jfr_VMJFR_isEnabled; + Java_oracle_jrockit_jfr_Logger_output0; + Java_oracle_jrockit_jfr_JFR_isCommercialFeaturesUnlocked; + Java_oracle_jrockit_jfr_JFR_isStarted; + Java_oracle_jrockit_jfr_JFR_isSupportedInVM; + Java_oracle_jrockit_jfr_JFR_startFlightRecorder; + Java_oracle_jrockit_jfr_JFR_isDisabledOnCommandLine; + Java_oracle_jrockit_jfr_JFR_isEnabled; Java_oracle_jrockit_jfr_VMJFR_options; Java_oracle_jrockit_jfr_VMJFR_init; Java_oracle_jrockit_jfr_VMJFR_addConstPool; @@ -33,7 +38,6 @@ Java_oracle_jrockit_jfr_VMJFR_setPeriod; Java_oracle_jrockit_jfr_VMJFR_getPeriod; Java_oracle_jrockit_jfr_VMJFR_descriptors; - Java_oracle_jrockit_jfr_VMJFR_redefineClass0; Java_oracle_jrockit_jfr_VMJFR_retransformClasses0; JNI_OnLoad; local: diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/mapfiles/libnet/mapfile-vers --- a/jdk/make/mapfiles/libnet/mapfile-vers Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/mapfiles/libnet/mapfile-vers Wed Jul 05 20:04:43 2017 +0200 @@ -28,6 +28,8 @@ SUNWprivate_1.1 { global: JNI_OnLoad; + Java_java_net_AbstractPlainDatagramSocketImpl_init; + Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable; Java_java_net_PlainSocketImpl_socketListen; Java_java_net_PlainDatagramSocketImpl_getTTL; Java_java_net_PlainDatagramSocketImpl_init; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/make/src/classes/build/tools/module/GenModulesList.java --- a/jdk/make/src/classes/build/tools/module/GenModulesList.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/make/src/classes/build/tools/module/GenModulesList.java Wed Jul 05 20:04:43 2017 +0200 @@ -112,8 +112,7 @@ } static final List AGGREGATORS = Arrays.asList(new String[] { - "java.se", "java.compact1", "java.compact2", - "java.compact3", "jdk.compact3"}); + "java.se", "java.compact1", "java.compact2", "java.compact3"}); class TopoSorter { final Deque result = new LinkedList<>(); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/lang/Class.java --- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 20:04:43 2017 +0200 @@ -262,8 +262,8 @@ @CallerSensitive public static Class forName(String className) throws ClassNotFoundException { - return forName0(className, true, - ClassLoader.getClassLoader(Reflection.getCallerClass())); + Class caller = Reflection.getCallerClass(); + return forName0(className, true, ClassLoader.getClassLoader(caller), caller); } @@ -333,22 +333,27 @@ ClassLoader loader) throws ClassNotFoundException { - if (sun.misc.VM.isSystemDomainLoader(loader)) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass()); + Class caller = null; + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + // Reflective call to get caller class is only needed if a security manager + // is present. Avoid the overhead of making this call otherwise. + caller = Reflection.getCallerClass(); + if (sun.misc.VM.isSystemDomainLoader(loader)) { + ClassLoader ccl = ClassLoader.getClassLoader(caller); if (!sun.misc.VM.isSystemDomainLoader(ccl)) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); } } } - return forName0(name, initialize, loader); + return forName0(name, initialize, loader, caller); } - /** Called after security checks have been made. */ + /** Called after security check for system loader access checks have been made. */ private static native Class forName0(String name, boolean initialize, - ClassLoader loader) + ClassLoader loader, + Class caller) throws ClassNotFoundException; /** diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/lang/String.java --- a/jdk/src/java.base/share/classes/java/lang/String.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/String.java Wed Jul 05 20:04:43 2017 +0200 @@ -1045,8 +1045,9 @@ } } // Argument is a String - if (cs.equals(this)) - return true; + if (cs instanceof String) { + return equals(cs); + } // Argument is a generic CharSequence char v1[] = value; int n = v1.length; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -594,6 +594,9 @@ static class Lazy { private static final Class MHI = MethodHandleImpl.class; + private static final MethodHandle[] ARRAYS; + private static final MethodHandle[] FILL_ARRAYS; + static final NamedFunction NF_checkSpreadArgument; static final NamedFunction NF_guardWithCatch; static final NamedFunction NF_throwException; @@ -606,6 +609,9 @@ static final MethodHandle MH_arrayIdentity; static { + ARRAYS = makeArrays(); + FILL_ARRAYS = makeFillArrays(); + try { NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); NF_guardWithCatch = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class, @@ -1268,7 +1274,6 @@ assert(mhs.size() == 11); // current number of methods return mhs.toArray(new MethodHandle[MAX_ARITY+1]); } - private static final MethodHandle[] ARRAYS = makeArrays(); // filling versions of the above: // using Integer len instead of int len and no varargs to avoid bootstrapping problems @@ -1315,6 +1320,9 @@ Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; } + + private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods + private static MethodHandle[] makeFillArrays() { ArrayList mhs = new ArrayList<>(); mhs.add(null); // there is no empty fill; at least a0 is required @@ -1323,10 +1331,9 @@ if (mh == null) break; mhs.add(mh); } - assert(mhs.size() == 11); // current number of methods + assert(mhs.size() == FILL_ARRAYS_COUNT); return mhs.toArray(new MethodHandle[0]); } - private static final MethodHandle[] FILL_ARRAYS = makeFillArrays(); private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) { Object a = w.makeArray(boxes.length); @@ -1338,15 +1345,15 @@ * arguments and returns an Object array of them, as if for varargs. */ static MethodHandle varargsArray(int nargs) { - MethodHandle mh = ARRAYS[nargs]; + MethodHandle mh = Lazy.ARRAYS[nargs]; if (mh != null) return mh; mh = findCollector("array", nargs, Object[].class); if (mh != null) mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY); - if (mh != null) return ARRAYS[nargs] = mh; + if (mh != null) return Lazy.ARRAYS[nargs] = mh; mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs); assert(assertCorrectArity(mh, nargs)); mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY); - return ARRAYS[nargs] = mh; + return Lazy.ARRAYS[nargs] = mh; } private static boolean assertCorrectArity(MethodHandle mh, int arity) { @@ -1382,7 +1389,7 @@ return mh; } - private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1); + private static final int LEFT_ARGS = FILL_ARRAYS_COUNT - 1; private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1]; /** fill_array_to_right(N).invoke(a, argL..arg[N-1]) * fills a[L]..a[N-1] with corresponding arguments, @@ -1413,7 +1420,7 @@ if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS); assert(rightLen > 0); MethodHandle midFill = fillToRight(midLen); // recursive fill - MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1] + MethodHandle rightFill = Lazy.FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1] assert(midFill.type().parameterCount() == 1 + midLen - LEFT_ARGS); assert(rightFill.type().parameterCount() == 1 + rightLen); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Jul 05 20:04:43 2017 +0200 @@ -727,7 +727,7 @@ * @return the parameter types (as an immutable list) */ public List> parameterList() { - return Collections.unmodifiableList(Arrays.asList(ptypes)); + return Collections.unmodifiableList(Arrays.asList(ptypes.clone())); } /*non-public*/ Class lastParameterType() { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java --- a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -68,6 +68,7 @@ return null; } }); + init(); } /** @@ -362,4 +363,7 @@ protected boolean nativeConnectDisabled() { return connectDisabled; } + + native int dataAvailable(); + private static native void init(); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/net/DatagramSocket.java --- a/jdk/src/java.base/share/classes/java/net/DatagramSocket.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/net/DatagramSocket.java Wed Jul 05 20:04:43 2017 +0200 @@ -85,6 +85,17 @@ */ boolean oldImpl = false; + /** + * Set when a socket is ST_CONNECTED until we are certain + * that any packets which might have been received prior + * to calling connect() but not read by the application + * have been read. During this time we check the source + * address of all packets received to be sure they are from + * the connected destination. Other packets are read but + * silently dropped. + */ + private boolean explicitFilter = false; + private int bytesLeftToFilter; /* * Connection state: * ST_NOT_CONNECTED = socket not connected @@ -144,6 +155,15 @@ // socket is now connected by the impl connectState = ST_CONNECTED; + // Do we need to filter some packets? + int avail = getImpl().dataAvailable(); + if (avail == -1) { + throw new SocketException(); + } + explicitFilter = avail > 0; + if (explicitFilter) { + bytesLeftToFilter = getReceiveBufferSize(); + } } catch (SocketException se) { // connection will be emulated by DatagramSocket @@ -492,6 +512,7 @@ connectedAddress = null; connectedPort = -1; connectState = ST_NOT_CONNECTED; + explicitFilter = false; } } @@ -750,10 +771,12 @@ } // end of while } } - if (connectState == ST_CONNECTED_NO_IMPL) { + if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { // We have to do the filtering the old fashioned way since // the native impl doesn't support connect or the connect - // via the impl failed. + // via the impl failed, or .. "explicitFilter" may be set when + // a socket is connected via the impl, for a period of time + // when packets from other sources might be queued on socket. boolean stop = false; while (!stop) { InetAddress peekAddress = null; @@ -772,8 +795,12 @@ if ((!connectedAddress.equals(peekAddress)) || (connectedPort != peekPort)) { // throw the packet away and silently continue - DatagramPacket tmp = new DatagramPacket(new byte[1], 1); + DatagramPacket tmp = new DatagramPacket( + new byte[1024], 1024); getImpl().receive(tmp); + if (explicitFilter) { + bytesLeftToFilter -= tmp.getLength(); + } } else { stop = true; } @@ -782,6 +809,15 @@ // If the security check succeeds, or the datagram is // connected then receive the packet getImpl().receive(p); + if (explicitFilter) { + bytesLeftToFilter -= p.getLength(); + if (bytesLeftToFilter <= 0) { + explicitFilter = false; + } else { + // break out of filter, if there is no more data queued + explicitFilter = getImpl().dataAvailable() > 0; + } + } } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java --- a/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -63,6 +63,12 @@ return socket; } + int dataAvailable() { + // default impl returns zero, which disables the calling + // functionality + return 0; + } + /** * Creates a datagram socket. * @exception SocketException if there is an error in the diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/security/Signature.java --- a/jdk/src/java.base/share/classes/java/security/Signature.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/security/Signature.java Wed Jul 05 20:04:43 2017 +0200 @@ -604,9 +604,13 @@ * @return the number of bytes placed into {@code outbuf}. * * @exception SignatureException if this signature object is not - * initialized properly, if this signature algorithm is unable to - * process the input data provided, or if {@code len} is less - * than the actual signature length. + * initialized properly, if this signature algorithm is unable to + * process the input data provided, or if {@code len} is less + * than the actual signature length. + * @exception IllegalArgumentException if {@code outbuf} is {@code null}, + * or {@code offset} or {@code len} is less than 0, or the sum of + * {@code offset} and {@code len} is greater than the length of + * {@code outbuf}. * * @since 1.2 */ @@ -615,6 +619,9 @@ if (outbuf == null) { throw new IllegalArgumentException("No output buffer given"); } + if (offset < 0 || len < 0) { + throw new IllegalArgumentException("offset or len is less than 0"); + } if (outbuf.length - offset < len) { throw new IllegalArgumentException ("Output buffer too small for specified offset and length"); @@ -683,9 +690,16 @@ public final boolean verify(byte[] signature, int offset, int length) throws SignatureException { if (state == VERIFY) { - if ((signature == null) || (offset < 0) || (length < 0) || - (length > signature.length - offset)) { - throw new IllegalArgumentException("Bad arguments"); + if (signature == null) { + throw new IllegalArgumentException("signature is null"); + } + if (offset < 0 || length < 0) { + throw new IllegalArgumentException + ("offset or length is less than 0"); + } + if (signature.length - offset < length) { + throw new IllegalArgumentException + ("signature too small for specified offset and length"); } return engineVerify(signature, offset, length); @@ -733,11 +747,25 @@ * @param len the number of bytes to use, starting at offset. * * @exception SignatureException if this signature object is not - * initialized properly. + * initialized properly. + * @exception IllegalArgumentException if {@code data} is {@code null}, + * or {@code off} or {@code len} is less than 0, or the sum of + * {@code off} and {@code len} is greater than the length of + * {@code data}. */ public final void update(byte[] data, int off, int len) throws SignatureException { if (state == SIGN || state == VERIFY) { + if (data == null) { + throw new IllegalArgumentException("data is null"); + } + if (off < 0 || len < 0) { + throw new IllegalArgumentException("off or len is less than 0"); + } + if (data.length - off < len) { + throw new IllegalArgumentException + ("data too small for specified offset and length"); + } engineUpdate(data, off, len); } else { throw new SignatureException("object not initialized for " diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java --- a/jdk/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,6 +84,8 @@ * @throws NullPointerException if {@code revocationDate}, * {@code reason}, {@code authority}, or * {@code extensions} is {@code null} + * @throws ClassCastException if {@code extensions} contains an incorrectly + * typed key or value */ public CertificateRevokedException(Date revocationDate, CRLReason reason, X500Principal authority, Map extensions) { @@ -94,7 +96,10 @@ this.revocationDate = new Date(revocationDate.getTime()); this.reason = reason; this.authority = authority; - this.extensions = new HashMap(extensions); + // make sure Map only contains correct types + this.extensions = Collections.checkedMap(new HashMap<>(), + String.class, Extension.class); + this.extensions.putAll(extensions); } /** @@ -172,7 +177,8 @@ public String getMessage() { return "Certificate has been revoked, reason: " + reason + ", revocation date: " + revocationDate - + ", authority: " + authority + ", extensions: " + extensions; + + ", authority: " + authority + ", extension OIDs: " + + extensions.keySet(); } /** diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/text/DigitList.java --- a/jdk/src/java.base/share/classes/java/text/DigitList.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/text/DigitList.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -290,25 +290,26 @@ FloatingDecimal.BinaryToASCIIConverter fdConverter = FloatingDecimal.getBinaryToASCIIConverter(source); boolean hasBeenRoundedUp = fdConverter.digitsRoundedUp(); - boolean allDecimalDigits = fdConverter.decimalDigitsExact(); + boolean valueExactAsDecimal = fdConverter.decimalDigitsExact(); assert !fdConverter.isExceptional(); String digitsString = fdConverter.toJavaFormatString(); set(isNegative, digitsString, - hasBeenRoundedUp, allDecimalDigits, + hasBeenRoundedUp, valueExactAsDecimal, maximumDigits, fixedPoint); } /** * Generate a representation of the form DDDDD, DDDDD.DDDDD, or * DDDDDE+/-DDDDD. - * @param roundedUp Boolean value indicating if the s digits were rounded-up. - * @param allDecimalDigits Boolean value indicating if the digits in s are - * an exact decimal representation of the double that was passed. + * @param roundedUp whether or not rounding up has already happened. + * @param valueExactAsDecimal whether or not collected digits provide + * an exact decimal representation of the value. */ private void set(boolean isNegative, String s, - boolean roundedUp, boolean allDecimalDigits, + boolean roundedUp, boolean valueExactAsDecimal, int maximumDigits, boolean fixedPoint) { + this.isNegative = isNegative; int len = s.length(); char[] source = getDataChars(len); @@ -361,7 +362,7 @@ } else if (-decimalAt == maximumDigits) { // If we round 0.0009 to 3 fractional digits, then we have to // create a new one digit in the least significant location. - if (shouldRoundUp(0, roundedUp, allDecimalDigits)) { + if (shouldRoundUp(0, roundedUp, valueExactAsDecimal)) { count = 1; ++decimalAt; digits[0] = '1'; @@ -381,25 +382,26 @@ // Eliminate digits beyond maximum digits to be displayed. // Round up if appropriate. round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits, - roundedUp, allDecimalDigits); - } + roundedUp, valueExactAsDecimal); + + } /** * Round the representation to the given number of digits. * @param maximumDigits The maximum number of digits to be shown. - * @param alreadyRounded Boolean indicating if rounding up already happened. - * @param allDecimalDigits Boolean indicating if the digits provide an exact - * representation of the value. + * @param alreadyRounded whether or not rounding up has already happened. + * @param valueExactAsDecimal whether or not collected digits provide + * an exact decimal representation of the value. * * Upon return, count will be less than or equal to maximumDigits. */ private final void round(int maximumDigits, boolean alreadyRounded, - boolean allDecimalDigits) { + boolean valueExactAsDecimal) { // Eliminate digits beyond maximum digits to be displayed. // Round up if appropriate. if (maximumDigits >= 0 && maximumDigits < count) { - if (shouldRoundUp(maximumDigits, alreadyRounded, allDecimalDigits)) { + if (shouldRoundUp(maximumDigits, alreadyRounded, valueExactAsDecimal)) { // Rounding up involved incrementing digits from LSD to MSD. // In most cases this is simple, but in a worst case situation // (9999..99) we have to adjust the decimalAt value. @@ -440,6 +442,9 @@ * count-1. If 0, then all digits are rounded away, and * this method returns true if a one should be generated (e.g., formatting * 0.09 with "#.#"). + * @param alreadyRounded whether or not rounding up has already happened. + * @param valueExactAsDecimal whether or not collected digits provide + * an exact decimal representation of the value. * @exception ArithmeticException if rounding is needed with rounding * mode being set to RoundingMode.UNNECESSARY * @return true if digit maximumDigits-1 should be @@ -447,7 +452,7 @@ */ private boolean shouldRoundUp(int maximumDigits, boolean alreadyRounded, - boolean allDecimalDigits) { + boolean valueExactAsDecimal) { if (maximumDigits < count) { /* * To avoid erroneous double-rounding or truncation when converting @@ -460,7 +465,7 @@ * account what FloatingDecimal has done in the binary to decimal * conversion. * - * Considering the tie cases, FloatingDecimal may round-up the + * Considering the tie cases, FloatingDecimal may round up the * value (returning decimal digits equal to tie when it is below), * or "truncate" the value to the tie while value is above it, * or provide the exact decimal digits when the binary value can be @@ -490,7 +495,7 @@ * * - For other numbers that are always converted to exact digits * (like BigInteger, Long, ...), the passed alreadyRounded boolean - * have to be set to false, and allDecimalDigits has to be set to + * have to be set to false, and valueExactAsDecimal has to be set to * true in the upper DigitList call stack, providing the right state * for those situations.. */ @@ -520,42 +525,31 @@ } break; case HALF_UP: - if (digits[maximumDigits] >= '5') { - // We should not round up if the rounding digits position is - // exactly the last index and if digits were already rounded. - if ((maximumDigits == (count - 1)) && - (alreadyRounded)) - return false; - - // Value was exactly at or was above tie. We must round up. - return true; - } - break; case HALF_DOWN: if (digits[maximumDigits] > '5') { + // Value is above tie ==> must round up return true; - } else if (digits[maximumDigits] == '5' ) { - if (maximumDigits == (count - 1)) { - // The rounding position is exactly the last index. - if (allDecimalDigits || alreadyRounded) - /* FloatingDecimal rounded up (value was below tie), - * or provided the exact list of digits (value was - * an exact tie). We should not round up, following - * the HALF_DOWN rounding rule. - */ - return false; - else - // Value was above the tie, we must round up. - return true; - } - - // We must round up if it gives a non null digit after '5'. - for (int i=maximumDigits+1; i must round up + return true; + } else { + // Digit at rounding position is the last one ! + if (valueExactAsDecimal) { + // Exact binary representation. On the tie. + // Apply rounding given by roundingMode. + return roundingMode == RoundingMode.HALF_UP; + } else { + // Not an exact binary representation. + // Digit sequence either rounded up or truncated. + // Round up only if it was truncated. + return !alreadyRounded; } } } + // Digit at rounding position is < '5' ==> no round up. + // Just let do the default, which is no round up (thus break). break; case HALF_EVEN: // Implement IEEE half-even rounding @@ -569,7 +563,7 @@ // then we should not round up again. return false; - if (!allDecimalDigits) + if (!valueExactAsDecimal) // Otherwise if the digits don't represent exact value, // value was above tie and FloatingDecimal truncated // digits to tie. We must round up. diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/util/ResourceBundle.java --- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Wed Jul 05 20:04:43 2017 +0200 @@ -2646,7 +2646,10 @@ } catch (ClassNotFoundException e) { } } else if (format.equals("java.properties")) { - final String resourceName = toResourceName(bundleName, "properties"); + final String resourceName = toResourceName0(bundleName, "properties"); + if (resourceName == null) { + return bundle; + } final ClassLoader classLoader = loader; final boolean reloadFlag = reload; InputStream stream = null; @@ -2800,7 +2803,10 @@ } boolean result = false; try { - String resourceName = toResourceName(toBundleName(baseName, locale), format); + String resourceName = toResourceName0(toBundleName(baseName, locale), format); + if (resourceName == null) { + return result; + } URL url = loader.getResource(resourceName); if (url != null) { long lastModified = 0; @@ -2934,6 +2940,15 @@ sb.append(bundleName.replace('.', '/')).append('.').append(suffix); return sb.toString(); } + + private String toResourceName0(String bundleName, String suffix) { + // application protocol check + if (bundleName.contains("://")) { + return null; + } else { + return toResourceName(bundleName, suffix); + } + } } private static class SingleFormatControl extends Control { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java Wed Jul 05 20:04:43 2017 +0200 @@ -163,7 +163,7 @@ public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && - UNSAFE.compareAndSwapInt(this, stateOffset, NEW, + U.compareAndSwapInt(this, STATE, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception @@ -173,7 +173,7 @@ if (t != null) t.interrupt(); } finally { // final state - UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); + U.putOrderedInt(this, STATE, INTERRUPTED); } } } finally { @@ -227,9 +227,9 @@ * @param v the value */ protected void set(V v) { - if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { + if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v; - UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state + U.putOrderedInt(this, STATE, NORMAL); // final state finishCompletion(); } } @@ -245,17 +245,16 @@ * @param t the cause of failure */ protected void setException(Throwable t) { - if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { + if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = t; - UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state + U.putOrderedInt(this, STATE, EXCEPTIONAL); // final state finishCompletion(); } } public void run() { if (state != NEW || - !UNSAFE.compareAndSwapObject(this, runnerOffset, - null, Thread.currentThread())) + !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return; try { Callable c = callable; @@ -296,8 +295,7 @@ */ protected boolean runAndReset() { if (state != NEW || - !UNSAFE.compareAndSwapObject(this, runnerOffset, - null, Thread.currentThread())) + !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return false; boolean ran = false; int s = state; @@ -364,7 +362,7 @@ private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { - if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) { + if (U.compareAndSwapObject(this, WAITERS, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { @@ -391,11 +389,18 @@ * * @param timed true if use timed waits * @param nanos time to wait, if timed - * @return state upon completion + * @return state upon completion or at timeout */ private int awaitDone(boolean timed, long nanos) throws InterruptedException { - final long deadline = timed ? System.nanoTime() + nanos : 0L; + // The code below is very delicate, to achieve these goals: + // - call nanoTime exactly once for each call to park + // - if nanos <= 0, return promptly without allocation or nanoTime + // - if nanos == Long.MIN_VALUE, don't underflow + // - if nanos == Long.MAX_VALUE, and nanoTime is non-monotonic + // and we suffer a spurious wakeup, we will do no worse than + // to park-spin for a while + long startTime = 0L; // Special value 0L means not yet parked WaitNode q = null; boolean queued = false; for (;;) { @@ -412,18 +417,30 @@ } else if (s == COMPLETING) // cannot time out yet Thread.yield(); - else if (q == null) + else if (q == null) { + if (timed && nanos <= 0L) + return s; q = new WaitNode(); + } else if (!queued) - queued = UNSAFE.compareAndSwapObject(this, waitersOffset, - q.next = waiters, q); + queued = U.compareAndSwapObject(this, WAITERS, + q.next = waiters, q); else if (timed) { - nanos = deadline - System.nanoTime(); - if (nanos <= 0L) { - removeWaiter(q); - return state; + final long parkNanos; + if (startTime == 0L) { // first time + startTime = System.nanoTime(); + if (startTime == 0L) + startTime = 1L; + parkNanos = nanos; + } else { + long elapsed = System.nanoTime() - startTime; + if (elapsed >= nanos) { + removeWaiter(q); + return state; + } + parkNanos = nanos - elapsed; } - LockSupport.parkNanos(this, nanos); + LockSupport.parkNanos(this, parkNanos); } else LockSupport.park(this); @@ -454,8 +471,7 @@ if (pred.thread == null) // check for race continue retry; } - else if (!UNSAFE.compareAndSwapObject(this, waitersOffset, - q, s)) + else if (!U.compareAndSwapObject(this, WAITERS, q, s)) continue retry; } break; @@ -464,20 +480,17 @@ } // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long stateOffset; - private static final long runnerOffset; - private static final long waitersOffset; + private static final sun.misc.Unsafe U; + private static final long STATE; + private static final long RUNNER; + private static final long WAITERS; static { try { - UNSAFE = sun.misc.Unsafe.getUnsafe(); + U = sun.misc.Unsafe.getUnsafe(); Class k = FutureTask.class; - stateOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("state")); - runnerOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("runner")); - waitersOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("waiters")); + STATE = U.objectFieldOffset(k.getDeclaredField("state")); + RUNNER = U.objectFieldOffset(k.getDeclaredField("runner")); + WAITERS = U.objectFieldOffset(k.getDeclaredField("waiters")); } catch (Exception e) { throw new Error(e); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/javax/crypto/CipherInputStream.java --- a/jdk/src/java.base/share/classes/javax/crypto/CipherInputStream.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/javax/crypto/CipherInputStream.java Wed Jul 05 20:04:43 2017 +0200 @@ -107,9 +107,10 @@ done = true; try { obuffer = cipher.doFinal(); + } catch (IllegalBlockSizeException | BadPaddingException e) { + obuffer = null; + throw new IOException(e); } - catch (IllegalBlockSizeException e) {obuffer = null;} - catch (BadPaddingException e) {obuffer = null;} if (obuffer == null) return -1; else { @@ -120,7 +121,10 @@ } try { obuffer = cipher.update(ibuffer, 0, readin); - } catch (IllegalStateException e) {obuffer = null;}; + } catch (IllegalStateException e) { + obuffer = null; + throw e; + } ostart = 0; if (obuffer == null) ofinish = 0; @@ -302,6 +306,7 @@ } } catch (BadPaddingException | IllegalBlockSizeException ex) { + throw new IOException(ex); } ostart = 0; ofinish = 0; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java --- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Wed Jul 05 20:04:43 2017 +0200 @@ -102,19 +102,24 @@ case PUBLIC: return true; // already checked above case PROTECTED: + assert !defc.isInterface(); // protected members aren't allowed in interfaces if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)) return true; if ((allowedModes & PROTECTED) == 0) return false; + // Protected members are accessible by subclasses, which does not include interfaces. + // Interfaces are types, not classes. They should not have access to + // protected members in j.l.Object, even though it is their superclass. if ((mods & STATIC) != 0 && !isRelatedClass(refc, lookupClass)) return false; if ((allowedModes & PROTECTED) != 0 && - isSuperClass(defc, lookupClass)) + isSubClass(lookupClass, defc)) return true; return false; case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. + assert !defc.isInterface(); // package-private members aren't allowed in interfaces return ((allowedModes & PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)); case PRIVATE: @@ -129,12 +134,13 @@ static boolean isRelatedClass(Class refc, Class lookupClass) { return (refc == lookupClass || - refc.isAssignableFrom(lookupClass) || - lookupClass.isAssignableFrom(refc)); + isSubClass(refc, lookupClass) || + isSubClass(lookupClass, refc)); } - static boolean isSuperClass(Class defc, Class lookupClass) { - return defc.isAssignableFrom(lookupClass); + static boolean isSubClass(Class lookupClass, Class defc) { + return defc.isAssignableFrom(lookupClass) && + !lookupClass.isInterface(); // interfaces are types, not classes. } static int getClassModifiers(Class c) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -740,6 +740,25 @@ // set or refresh local address localAddress = Net.localAddress(fd); + + // flush any packets already received. + boolean blocking = false; + synchronized (blockingLock()) { + try { + blocking = isBlocking(); + ByteBuffer tmpBuf = ByteBuffer.allocate(100); + if (blocking) { + configureBlocking(false); + } + do { + tmpBuf.clear(); + } while (read(tmpBuf) > 0); + } finally { + if (blocking) { + configureBlocking(true); + } + } + } } } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java --- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.lang.reflect.*; import java.io.Serializable; import java.util.*; -import java.lang.annotation.*; import java.security.AccessController; import java.security.PrivilegedAction; @@ -45,6 +44,11 @@ private final Map memberValues; AnnotationInvocationHandler(Class type, Map memberValues) { + Class[] superInterfaces = type.getInterfaces(); + if (!type.isAnnotation() || + superInterfaces.length != 1 || + superInterfaces[0] != java.lang.annotation.Annotation.class) + throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type."); this.type = type; this.memberValues = memberValues; } @@ -57,13 +61,17 @@ if (member.equals("equals") && paramTypes.length == 1 && paramTypes[0] == Object.class) return equalsImpl(args[0]); - assert paramTypes.length == 0; - if (member.equals("toString")) + if (paramTypes.length != 0) + throw new AssertionError("Too many parameters for an annotation method"); + + switch(member) { + case "toString": return toStringImpl(); - if (member.equals("hashCode")) + case "hashCode": return hashCodeImpl(); - if (member.equals("annotationType")) + case "annotationType": return type; + } // Handle annotation member accessors Object result = memberValues.get(member); @@ -129,7 +137,7 @@ * Implementation of dynamicProxy.toString() */ private String toStringImpl() { - StringBuffer result = new StringBuffer(128); + StringBuilder result = new StringBuilder(128); result.append('@'); result.append(type.getName()); result.append('('); @@ -277,6 +285,7 @@ new PrivilegedAction() { public Method[] run() { final Method[] mm = type.getDeclaredMethods(); + validateAnnotationMethods(mm); AccessibleObject.setAccessible(mm, true); return mm; } @@ -287,6 +296,94 @@ private transient volatile Method[] memberMethods = null; /** + * Validates that a method is structurally appropriate for an + * annotation type. As of Java SE 8, annotation types cannot + * contain static methods and the declared methods of an + * annotation type must take zero arguments and there are + * restrictions on the return type. + */ + private void validateAnnotationMethods(Method[] memberMethods) { + /* + * Specification citations below are from JLS + * 9.6.1. Annotation Type Elements + */ + boolean valid = true; + for(Method method : memberMethods) { + /* + * "By virtue of the AnnotationTypeElementDeclaration + * production, a method declaration in an annotation type + * declaration cannot have formal parameters, type + * parameters, or a throws clause. + * + * "By virtue of the AnnotationTypeElementModifier + * production, a method declaration in an annotation type + * declaration cannot be default or static." + */ + if (method.getModifiers() != (Modifier.PUBLIC | Modifier.ABSTRACT) || + method.isDefault() || + method.getParameterCount() != 0 || + method.getExceptionTypes().length != 0) { + valid = false; + break; + } + + /* + * "It is a compile-time error if the return type of a + * method declared in an annotation type is not one of the + * following: a primitive type, String, Class, any + * parameterized invocation of Class, an enum type + * (section 8.9), an annotation type, or an array type + * (chapter 10) whose element type is one of the preceding + * types." + */ + Class returnType = method.getReturnType(); + if (returnType.isArray()) { + returnType = returnType.getComponentType(); + if (returnType.isArray()) { // Only single dimensional arrays + valid = false; + break; + } + } + + if (!((returnType.isPrimitive() && returnType != void.class) || + returnType == java.lang.String.class || + returnType == java.lang.Class.class || + returnType.isEnum() || + returnType.isAnnotation())) { + valid = false; + break; + } + + /* + * "It is a compile-time error if any method declared in an + * annotation type has a signature that is + * override-equivalent to that of any public or protected + * method declared in class Object or in the interface + * java.lang.annotation.Annotation." + * + * The methods in Object or Annotation meeting the other + * criteria (no arguments, contrained return type, etc.) + * above are: + * + * String toString() + * int hashCode() + * Class annotationType() + */ + String methodName = method.getName(); + if ((methodName.equals("toString") && returnType == java.lang.String.class) || + (methodName.equals("hashCode") && returnType == int.class) || + (methodName.equals("annotationType") && returnType == java.lang.Class.class)) { + valid = false; + break; + } + } + if (valid) + return; + else + throw new AnnotationFormatError("Malformed method on an annotation type"); + } + + /** * Implementation of dynamicProxy.hashCode() */ private int hashCodeImpl() { @@ -330,7 +427,6 @@ throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); - // Check to make sure that types have not evolved incompatibly AnnotationType annotationType = null; @@ -343,7 +439,6 @@ Map> memberTypes = annotationType.memberTypes(); - // If there are annotation members without values, that // situation is handled by the invoke method. for (Map.Entry memberValue : memberValues.entrySet()) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/security/provider/X509Factory.java --- a/jdk/src/java.base/share/classes/sun/security/provider/X509Factory.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/provider/X509Factory.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,6 +80,7 @@ * * @exception CertificateException on parsing errors. */ + @Override public Certificate engineGenerateCertificate(InputStream is) throws CertificateException { @@ -103,8 +104,8 @@ throw new IOException("Empty input"); } } catch (IOException ioe) { - throw (CertificateException)new CertificateException - ("Could not parse certificate: " + ioe.toString()).initCause(ioe); + throw new CertificateException("Could not parse certificate: " + + ioe.toString(), ioe); } } @@ -140,6 +141,12 @@ * It is useful for certificates that cannot be created via * generateCertificate() and for converting other X509Certificate * implementations to an X509CertImpl. + * + * @param c The source X509Certificate + * @return An X509CertImpl object that is either a cached certificate or a + * newly built X509CertImpl from the provided X509Certificate + * @throws CertificateException if failures occur while obtaining the DER + * encoding for certificate data. */ public static synchronized X509CertImpl intern(X509Certificate c) throws CertificateException { @@ -170,6 +177,12 @@ /** * Return an interned X509CRLImpl for the given certificate. * For more information, see intern(X509Certificate). + * + * @param c The source X509CRL + * @return An X509CRLImpl object that is either a cached CRL or a + * newly built X509CRLImpl from the provided X509CRL + * @throws CRLException if failures occur while obtaining the DER + * encoding for CRL data. */ public static synchronized X509CRLImpl intern(X509CRL c) throws CRLException { @@ -229,6 +242,7 @@ * @exception CertificateException if an exception occurs while decoding * @since 1.4 */ + @Override public CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException { @@ -260,6 +274,7 @@ * the encoding requested is not supported * @since 1.4 */ + @Override public CertPath engineGenerateCertPath(InputStream inStream, String encoding) throws CertificateException { @@ -292,6 +307,7 @@ * @exception CertificateException if an exception occurs * @since 1.4 */ + @Override public CertPath engineGenerateCertPath(List certificates) throws CertificateException @@ -311,6 +327,7 @@ * CertPath encodings (as Strings) * @since 1.4 */ + @Override public Iterator engineGetCertPathEncodings() { return(X509CertPath.getEncodingsStatic()); } @@ -326,6 +343,7 @@ * * @exception CertificateException on parsing errors. */ + @Override public Collection engineGenerateCertificates(InputStream is) throws CertificateException { @@ -351,6 +369,7 @@ * * @exception CRLException on parsing errors. */ + @Override public CRL engineGenerateCRL(InputStream is) throws CRLException { @@ -388,6 +407,7 @@ * * @exception CRLException on parsing errors. */ + @Override public Collection engineGenerateCRLs( InputStream is) throws CRLException { @@ -410,11 +430,30 @@ parseX509orPKCS7Cert(InputStream is) throws CertificateException, IOException { + int peekByte; + byte[] data; + PushbackInputStream pbis = new PushbackInputStream(is); Collection coll = new ArrayList<>(); - byte[] data = readOneBlock(is); + + // Test the InputStream for end-of-stream. If the stream's + // initial state is already at end-of-stream then return + // an empty collection. Otherwise, push the byte back into the + // stream and let readOneBlock look for the first certificate. + peekByte = pbis.read(); + if (peekByte == -1) { + return new ArrayList<>(0); + } else { + pbis.unread(peekByte); + data = readOneBlock(pbis); + } + + // If we end up with a null value after reading the first block + // then we know the end-of-stream has been reached and no certificate + // data has been found. if (data == null) { - return new ArrayList<>(0); + throw new CertificateException("No certificate data found"); } + try { PKCS7 pkcs7 = new PKCS7(data); X509Certificate[] certs = pkcs7.getCertificates(); @@ -422,13 +461,13 @@ if (certs != null) { return Arrays.asList(certs); } else { - // no crls provided + // no certificates provided return new ArrayList<>(0); } } catch (ParsingException e) { while (data != null) { coll.add(new X509CertImpl(data)); - data = readOneBlock(is); + data = readOneBlock(pbis); } } return coll; @@ -443,11 +482,30 @@ parseX509orPKCS7CRL(InputStream is) throws CRLException, IOException { + int peekByte; + byte[] data; + PushbackInputStream pbis = new PushbackInputStream(is); Collection coll = new ArrayList<>(); - byte[] data = readOneBlock(is); + + // Test the InputStream for end-of-stream. If the stream's + // initial state is already at end-of-stream then return + // an empty collection. Otherwise, push the byte back into the + // stream and let readOneBlock look for the first CRL. + peekByte = pbis.read(); + if (peekByte == -1) { + return new ArrayList<>(0); + } else { + pbis.unread(peekByte); + data = readOneBlock(pbis); + } + + // If we end up with a null value after reading the first block + // then we know the end-of-stream has been reached and no CRL + // data has been found. if (data == null) { - return new ArrayList<>(0); + throw new CRLException("No CRL data found"); } + try { PKCS7 pkcs7 = new PKCS7(data); X509CRL[] crls = pkcs7.getCRLs(); @@ -461,7 +519,7 @@ } catch (ParsingException e) { while (data != null) { coll.add(new X509CRLImpl(data)); - data = readOneBlock(is); + data = readOneBlock(pbis); } } return coll; @@ -623,7 +681,7 @@ int n = is.read(); if (n == -1) { - throw new IOException("BER/DER length info ansent"); + throw new IOException("BER/DER length info absent"); } bout.write(n); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ import java.security.cert.X509Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateParsingException; +import javax.security.auth.x500.X500Principal; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; @@ -89,12 +91,66 @@ private final static boolean enableSNIExtension = Debug.getBooleanProperty("jsse.enableSNIExtension", true); + /* + * Allow unsafe server certificate change? + * + * Server certificate change during SSL/TLS renegotiation may be considered + * unsafe, as described in the Triple Handshake attacks: + * + * https://secure-resumption.com/tlsauth.pdf + * + * Endpoint identification (See + * SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice + * guarantee that the server certificate change in renegotiation is legal. + * However, endpoing identification is only enabled for HTTPS and LDAP + * over SSL/TLS by default. It is not enough to protect SSL/TLS + * connections other than HTTPS and LDAP. + * + * The renegotiation indication extension (See RFC 5764) is a pretty + * strong guarantee that the endpoints on both client and server sides + * are identical on the same connection. However, the Triple Handshake + * attacks can bypass this guarantee if there is a session-resumption + * handshake between the initial full handshake and the renegotiation + * full handshake. + * + * Server certificate change may be unsafe and should be restricted if + * endpoint identification is not enabled and the previous handshake is + * a session-resumption abbreviated initial handshake, unless the + * identities represented by both certificates can be regraded as the + * same (See isIdentityEquivalent()). + * + * Considering the compatibility impact and the actual requirements to + * support server certificate change in practice, the system property, + * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe + * server certificate change in renegotiation is allowed or not. The + * default value of the system property is "false". To mitigate the + * compactibility impact, applications may want to set the system + * property to "true" at their own risk. + * + * If the value of the system property is "false", server certificate + * change in renegotiation after a session-resumption abbreviated initial + * handshake is restricted (See isIdentityEquivalent()). + * + * If the system property is set to "true" explicitly, the restriction on + * server certificate change in renegotiation is disabled. + */ + private final static boolean allowUnsafeServerCertChange = + Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false); + private List requestedServerNames = Collections.emptyList(); private boolean serverNamesAccepted = false; /* + * the reserved server certificate chain in previous handshaking + * + * The server certificate chain is only reserved if the previous + * handshake is a session-resumption abbreviated initial handshake. + */ + private X509Certificate[] reservedServerCerts = null; + + /* * Constructors */ ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context, @@ -555,14 +611,19 @@ // we wanted to resume, but the server refused session = null; if (!enableNewSession) { - throw new SSLException - ("New session creation is disabled"); + throw new SSLException("New session creation is disabled"); } } } if (resumingSession && session != null) { setHandshakeSessionSE(session); + // Reserve the handshake state if this is a session-resumption + // abbreviated initial handshake. + if (isInitialHandshake) { + session.setAsSessionResumption(true); + } + return; } @@ -1064,6 +1125,13 @@ } /* + * Reset the handshake state if this is not an initial handshake. + */ + if (!isInitialHandshake) { + session.setAsSessionResumption(false); + } + + /* * OK, it verified. If we're doing the fast handshake, add that * "Finished" message to the hash of handshake messages, then send * our own change_cipher_spec and Finished message for the server @@ -1161,8 +1229,23 @@ System.out.println("%% No cached client session"); } } - if ((session != null) && (session.isRejoinable() == false)) { - session = null; + if (session != null) { + // If unsafe server certificate change is not allowed, reserve + // current server certificates if the previous handshake is a + // session-resumption abbreviated initial handshake. + if (!allowUnsafeServerCertChange && session.isSessionResumption()) { + try { + // If existing, peer certificate chain cannot be null. + reservedServerCerts = + (X509Certificate[])session.getPeerCertificates(); + } catch (SSLPeerUnverifiedException puve) { + // Maybe not certificate-based, ignore the exception. + } + } + + if (!session.isRejoinable()) { + session = null; + } } if (session != null) { @@ -1331,9 +1414,28 @@ } X509Certificate[] peerCerts = mesg.getCertificateChain(); if (peerCerts.length == 0) { - fatalSE(Alerts.alert_bad_certificate, - "empty certificate chain"); + fatalSE(Alerts.alert_bad_certificate, "empty certificate chain"); } + + // Allow server certificate change in client side during renegotiation + // after a session-resumption abbreviated initial handshake? + // + // DO NOT need to check allowUnsafeServerCertChange here. We only + // reserve server certificates when allowUnsafeServerCertChange is + // flase. + if (reservedServerCerts != null) { + // It is not necessary to check the certificate update if endpoint + // identification is enabled. + String identityAlg = getEndpointIdentificationAlgorithmSE(); + if ((identityAlg == null || identityAlg.length() == 0) && + !isIdentityEquivalent(peerCerts[0], reservedServerCerts[0])) { + + fatalSE(Alerts.alert_bad_certificate, + "server certificate change is restricted " + + "during renegotiation"); + } + } + // ask the trust manager to verify the chain X509TrustManager tm = sslContext.getX509TrustManager(); try { @@ -1370,4 +1472,81 @@ } session.setPeerCertificates(peerCerts); } + + /* + * Whether the certificates can represent the same identity? + * + * The certificates can be used to represent the same identity: + * 1. If the subject alternative names of IP address are present in + * both certificates, they should be identical; otherwise, + * 2. if the subject alternative names of DNS name are present in + * both certificates, they should be identical; otherwise, + * 3. if the subject fields are present in both certificates, the + * certificate subjects and issuers should be identical. + */ + private static boolean isIdentityEquivalent(X509Certificate thisCert, + X509Certificate prevCert) { + if (thisCert.equals(prevCert)) { + return true; + } + + // check the iPAddress field in subjectAltName extension + Object thisIPAddress = getSubjectAltName(thisCert, 7); // 7: iPAddress + Object prevIPAddress = getSubjectAltName(prevCert, 7); + if (thisIPAddress != null && prevIPAddress!= null) { + // only allow the exactly match + return Objects.equals(thisIPAddress, prevIPAddress); + } + + // check the dNSName field in subjectAltName extension + Object thisDNSName = getSubjectAltName(thisCert, 2); // 2: dNSName + Object prevDNSName = getSubjectAltName(prevCert, 2); + if (thisDNSName != null && prevDNSName!= null) { + // only allow the exactly match + return Objects.equals(thisDNSName, prevDNSName); + } + + // check the certificate subject and issuer + X500Principal thisSubject = thisCert.getSubjectX500Principal(); + X500Principal prevSubject = prevCert.getSubjectX500Principal(); + X500Principal thisIssuer = thisCert.getIssuerX500Principal(); + X500Principal prevIssuer = prevCert.getIssuerX500Principal(); + if (!thisSubject.getName().isEmpty() && + !prevSubject.getName().isEmpty() && + thisSubject.equals(prevSubject) && + thisIssuer.equals(prevIssuer)) { + return true; + } + + return false; + } + + /* + * Returns the subject alternative name of the specified type in the + * subjectAltNames extension of a certificate. + */ + private static Object getSubjectAltName(X509Certificate cert, int type) { + Collection> subjectAltNames; + + try { + subjectAltNames = cert.getSubjectAlternativeNames(); + } catch (CertificateParsingException cpe) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Attempt to obtain subjectAltNames extension failed!"); + } + return null; + } + + if (subjectAltNames != null) { + for (List subjectAltName : subjectAltNames) { + int subjectAltNameType = (Integer)subjectAltName.get(0); + if (subjectAltNameType == type) { + return subjectAltName.get(1); + } + } + } + + return null; + } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -359,6 +359,17 @@ } } + String getEndpointIdentificationAlgorithmSE() { + SSLParameters paras; + if (conn != null) { + paras = conn.getSSLParameters(); + } else { + paras = engine.getSSLParameters(); + } + + return paras.getEndpointIdentificationAlgorithm(); + } + private void setVersionSE(ProtocolVersion protocolVersion) { if (conn != null) { conn.setVersion(protocolVersion); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,6 +115,14 @@ private Principal localPrincipal; /* + * Is the session currently re-established with a session-resumption + * abbreviated initial handshake? + * + * Note that currently we only set this variable in client side. + */ + private boolean isSessionResumption = false; + + /* * We count session creations, eventually for statistical data but * also since counters make shorter debugging IDs than the big ones * we use in the protocol for uniqueness-over-time. @@ -325,6 +333,22 @@ } /** + * Return true if the session is currently re-established with a + * session-resumption abbreviated initial handshake. + */ + boolean isSessionResumption() { + return isSessionResumption; + } + + /** + * Resets whether the session is re-established with a session-resumption + * abbreviated initial handshake. + */ + void setAsSessionResumption(boolean flag) { + isSessionResumption = flag; + } + + /** * Returns the name of the cipher suite in use on this session */ @Override diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Jul 05 20:04:43 2017 +0200 @@ -64,6 +64,7 @@ import javax.security.auth.x500.X500Principal; import java.util.Base64; +import sun.security.util.KeyUtil; import sun.security.util.ObjectIdentifier; import sun.security.pkcs10.PKCS10; import sun.security.pkcs10.PKCS10Attribute; @@ -1103,8 +1104,13 @@ doChangeKeyPasswd(alias); kssave = true; } else if (command == LIST) { + if (storePass == null + && !KeyStoreUtil.isWindowsKeyStore(storetype)) { + printWarning(); + } + if (alias != null) { - doPrintEntry(alias, out, true); + doPrintEntry(alias, out); } else { doPrintEntries(out); } @@ -1765,15 +1771,9 @@ /** * Prints a single keystore entry. */ - private void doPrintEntry(String alias, PrintStream out, - boolean printWarning) + private void doPrintEntry(String alias, PrintStream out) throws Exception { - if (storePass == null && printWarning - && !KeyStoreUtil.isWindowsKeyStore(storetype)) { - printWarning(); - } - if (keyStore.containsAlias(alias) == false) { MessageFormat form = new MessageFormat (rb.getString("Alias.alias.does.not.exist")); @@ -2090,13 +2090,6 @@ private void doPrintEntries(PrintStream out) throws Exception { - if (storePass == null - && !KeyStoreUtil.isWindowsKeyStore(storetype)) { - printWarning(); - } else { - out.println(); - } - out.println(rb.getString("Keystore.type.") + keyStore.getType()); out.println(rb.getString("Keystore.provider.") + keyStore.getProvider().getName()); @@ -2115,7 +2108,7 @@ for (Enumeration e = keyStore.aliases(); e.hasMoreElements(); ) { String alias = e.nextElement(); - doPrintEntry(alias, out, false); + doPrintEntry(alias, out); if (verbose || rfc) { out.println(rb.getString("NEWLINE")); out.println(rb.getString @@ -2922,6 +2915,7 @@ MessageFormat form = new MessageFormat (rb.getString(".PATTERN.printX509Cert")); + PublicKey pkey = cert.getPublicKey(); Object[] source = {cert.getSubjectDN().toString(), cert.getIssuerDN().toString(), cert.getSerialNumber().toString(16), @@ -2931,7 +2925,9 @@ getCertFingerPrint("SHA1", cert), getCertFingerPrint("SHA-256", cert), cert.getSigAlgName(), - cert.getVersion() + pkey.getAlgorithm(), + KeyUtil.getKeySize(pkey), + cert.getVersion(), }; out.println(form.format(source)); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java Wed Jul 05 20:04:43 2017 +0200 @@ -347,7 +347,7 @@ {".RETURN.if.same.as.for.otherAlias.", "\t(RETURN if same as for <{0}>)"}, {".PATTERN.printX509Cert", - "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t MD5: {5}\n\t SHA1: {6}\n\t SHA256: {7}\n\t Signature algorithm name: {8}\n\t Version: {9}"}, + "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t MD5: {5}\n\t SHA1: {6}\n\t SHA256: {7}\nSignature algorithm name: {8}\nSubject Public Key Algorithm: {9} ({10,number,#})\nVersion: {11}"}, {"What.is.your.first.and.last.name.", "What is your first and last name?"}, {"What.is.the.name.of.your.organizational.unit.", diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java --- a/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java Wed Jul 05 20:04:43 2017 +0200 @@ -31,6 +31,7 @@ */ package sun.util.locale; +import java.lang.ref.SoftReference; import java.util.StringJoiner; @@ -151,11 +152,11 @@ return h; } - private static final class Key implements Comparable { - private final String lang; - private final String scrt; - private final String regn; - private final String vart; + private static final class Key { + private final SoftReference lang; + private final SoftReference scrt; + private final SoftReference regn; + private final SoftReference vart; private final boolean normalized; private final int hash; @@ -167,10 +168,10 @@ assert language.intern() == language && region.intern() == region; - lang = language; - scrt = ""; - regn = region; - vart = ""; + lang = new SoftReference<>(language); + scrt = new SoftReference<>(""); + regn = new SoftReference<>(region); + vart = new SoftReference<>(""); this.normalized = true; int h = language.hashCode(); @@ -191,40 +192,40 @@ String variant, boolean normalized) { int h = 0; if (language != null) { - lang = language; + lang = new SoftReference<>(language); int len = language.length(); for (int i = 0; i < len; i++) { h = 31*h + LocaleUtils.toLower(language.charAt(i)); } } else { - lang = ""; + lang = new SoftReference<>(""); } if (script != null) { - scrt = script; + scrt = new SoftReference<>(script); int len = script.length(); for (int i = 0; i < len; i++) { h = 31*h + LocaleUtils.toLower(script.charAt(i)); } } else { - scrt = ""; + scrt = new SoftReference<>(""); } if (region != null) { - regn = region; + regn = new SoftReference<>(region); int len = region.length(); for (int i = 0; i < len; i++) { h = 31*h + LocaleUtils.toLower(region.charAt(i)); } } else { - regn = ""; + regn = new SoftReference<>(""); } if (variant != null) { - vart = variant; + vart = new SoftReference<>(variant); int len = variant.length(); for (int i = 0; i < len; i++) { h = 31*h + variant.charAt(i); } } else { - vart = ""; + vart = new SoftReference<>(""); } hash = h; this.normalized = normalized; @@ -232,28 +233,31 @@ @Override public boolean equals(Object obj) { - return (this == obj) || - (obj instanceof Key) - && this.hash == ((Key)obj).hash - && LocaleUtils.caseIgnoreMatch(((Key)obj).lang, this.lang) - && LocaleUtils.caseIgnoreMatch(((Key)obj).scrt, this.scrt) - && LocaleUtils.caseIgnoreMatch(((Key)obj).regn, this.regn) - && ((Key)obj).vart.equals(vart); // variant is case sensitive in JDK! - } + if (this == obj) { + return true; + } - @Override - public int compareTo(Key other) { - int res = LocaleUtils.caseIgnoreCompare(this.lang, other.lang); - if (res == 0) { - res = LocaleUtils.caseIgnoreCompare(this.scrt, other.scrt); - if (res == 0) { - res = LocaleUtils.caseIgnoreCompare(this.regn, other.regn); - if (res == 0) { - res = this.vart.compareTo(other.vart); + if (obj instanceof Key && this.hash == ((Key)obj).hash) { + String tl = this.lang.get(); + String ol = ((Key)obj).lang.get(); + if (tl != null && ol != null && + LocaleUtils.caseIgnoreMatch(ol, tl)) { + String ts = this.scrt.get(); + String os = ((Key)obj).scrt.get(); + if (ts != null && os != null && + LocaleUtils.caseIgnoreMatch(os, ts)) { + String tr = this.regn.get(); + String or = ((Key)obj).regn.get(); + if (tr != null && or != null && + LocaleUtils.caseIgnoreMatch(or, tr)) { + String tv = this.vart.get(); + String ov = ((Key)obj).vart.get(); + return (ov != null && ov.equals(tv)); + } } } } - return res; + return false; } @Override @@ -266,10 +270,10 @@ return key; } - String lang = LocaleUtils.toLowerString(key.lang).intern(); - String scrt = LocaleUtils.toTitleString(key.scrt).intern(); - String regn = LocaleUtils.toUpperString(key.regn).intern(); - String vart = key.vart.intern(); // preserve upper/lower cases + String lang = LocaleUtils.toLowerString(key.lang.get()).intern(); + String scrt = LocaleUtils.toTitleString(key.scrt.get()).intern(); + String regn = LocaleUtils.toUpperString(key.regn.get()).intern(); + String vart = key.vart.get().intern(); // preserve upper/lower cases return new Key(lang, scrt, regn, vart, true); } @@ -282,12 +286,18 @@ @Override protected Key normalizeKey(Key key) { + assert key.lang.get() != null && + key.scrt.get() != null && + key.regn.get() != null && + key.vart.get() != null; + return Key.normalize(key); } @Override protected BaseLocale createObject(Key key) { - return new BaseLocale(key.lang, key.scrt, key.regn, key.vart); + return new BaseLocale(key.lang.get(), key.scrt.get(), + key.regn.get(), key.vart.get()); } } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/classes/sun/util/locale/LocaleObjectCache.java --- a/jdk/src/java.base/share/classes/sun/util/locale/LocaleObjectCache.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/classes/sun/util/locale/LocaleObjectCache.java Wed Jul 05 20:04:43 2017 +0200 @@ -57,8 +57,10 @@ value = entry.get(); } if (value == null) { + V newVal = createObject(key); + // make sure key is normalized *after* the object creation + // so that newVal is assured to be created from a valid key. key = normalizeKey(key); - V newVal = createObject(key); if (key == null || newVal == null) { // subclass must return non-null key/value object return null; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/native/include/jvm.h --- a/jdk/src/java.base/share/native/include/jvm.h Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/native/include/jvm.h Wed Jul 05 20:04:43 2017 +0200 @@ -386,6 +386,19 @@ JVM_FindClassFromBootLoader(JNIEnv *env, const char *name); /* + * Find a class from a given class loader. Throws ClassNotFoundException. + * name: name of class + * init: whether initialization is done + * loader: class loader to look up the class. This may not be the same as the caller's + * class loader. + * caller: initiating class. The initiating class may be null when a security + * manager is not installed. + */ +JNIEXPORT jclass JNICALL +JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init, + jobject loader, jclass caller); + +/* * Find a class from a given class loader. Throw ClassNotFoundException * or NoClassDefFoundError depending on the value of the last * argument. diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/native/libjava/Class.c --- a/jdk/src/java.base/share/native/libjava/Class.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/native/libjava/Class.c Wed Jul 05 20:04:43 2017 +0200 @@ -93,7 +93,7 @@ JNIEXPORT jclass JNICALL Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname, - jboolean initialize, jobject loader) + jboolean initialize, jobject loader, jclass caller) { char *clname; jclass cls = 0; @@ -131,8 +131,7 @@ goto done; } - cls = JVM_FindClassFromClassLoader(env, clname, initialize, - loader, JNI_FALSE); + cls = JVM_FindClassFromCaller(env, clname, initialize, loader, caller); done: if (clname != buf) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/native/libzip/CRC32.c --- a/jdk/src/java.base/share/native/libzip/CRC32.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/native/libzip/CRC32.c Wed Jul 05 20:04:43 2017 +0200 @@ -54,7 +54,8 @@ return crc; } -JNIEXPORT jint ZIP_CRC32(jint crc, const jbyte *buf, jint len) +JNIEXPORT jint JNICALL +ZIP_CRC32(jint crc, const jbyte *buf, jint len) { return crc32(crc, (Bytef*)buf, len); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/native/libzip/ZipFile.c --- a/jdk/src/java.base/share/native/libzip/ZipFile.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/native/libzip/ZipFile.c Wed Jul 05 20:04:43 2017 +0200 @@ -174,11 +174,7 @@ } (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path); path[ulen] = '\0'; - if (addSlash == JNI_FALSE) { - ze = ZIP_GetEntry(zip, path, 0); - } else { - ze = ZIP_GetEntry(zip, path, (jint)ulen); - } + ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash); if (path != buf) { free(path); } @@ -271,7 +267,7 @@ switch (type) { case java_util_zip_ZipFile_JZENTRY_NAME: if (ze->name != 0) { - len = (int)strlen(ze->name); + len = (int)ze->nlen; // Unlike for extra and comment, we never return null for // an (extremely rarely seen) empty name if ((jba = (*env)->NewByteArray(env, len)) == NULL) diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/native/libzip/zip_util.c --- a/jdk/src/java.base/share/native/libzip/zip_util.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/native/libzip/zip_util.c Wed Jul 05 20:04:43 2017 +0200 @@ -1021,6 +1021,7 @@ if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch; memcpy(ze->name, cen + CENHDR, nlen); ze->name[nlen] = '\0'; + ze->nlen = nlen; if (elen > 0) { char *extra = cen + CENHDR + nlen; @@ -1118,7 +1119,34 @@ jzentry * ZIP_GetEntry(jzfile *zip, char *name, jint ulen) { - unsigned int hsh = hash(name); + if (ulen == 0) { + return ZIP_GetEntry2(zip, name, strlen(name), JNI_FALSE); + } + return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE); +} + +jboolean equals(char* name1, int len1, char* name2, int len2) { + if (len1 != len2) { + return JNI_FALSE; + } + while (len1-- > 0) { + if (*name1++ != *name2++) { + return JNI_FALSE; + } + } + return JNI_TRUE; +} + +/* + * Returns the zip entry corresponding to the specified name, or + * NULL if not found. + * This method supports embedded null character in "name", use ulen + * for the length of "name". + */ +jzentry * +ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash) +{ + unsigned int hsh = hashN(name, ulen); jint idx; jzentry *ze = 0; @@ -1139,7 +1167,7 @@ /* Check the cached entry first */ ze = zip->cache; - if (ze && strcmp(ze->name,name) == 0) { + if (ze && equals(ze->name, ze->nlen, name, ulen)) { /* Cache hit! Remove and return the cached entry. */ zip->cache = 0; ZIP_Unlock(zip); @@ -1165,7 +1193,7 @@ * we keep searching. */ ze = newEntry(zip, zc, ACCESS_RANDOM); - if (ze && strcmp(ze->name, name)==0) { + if (ze && equals(ze->name, ze->nlen, name, ulen)) { break; } if (ze != 0) { @@ -1184,8 +1212,8 @@ break; } - /* If no real length was passed in, we are done */ - if (ulen == 0) { + /* If no need to try appending slash, we are done */ + if (!addSlash) { break; } @@ -1195,11 +1223,11 @@ } /* Add slash and try once more */ - name[ulen] = '/'; - name[ulen+1] = '\0'; + name[ulen++] = '/'; + name[ulen] = '\0'; hsh = hash_append(hsh, '/'); idx = zip->table[hsh % zip->tablelen]; - ulen = 0; + addSlash = JNI_FALSE; } Finally: diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/share/native/libzip/zip_util.h --- a/jdk/src/java.base/share/native/libzip/zip_util.h Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/share/native/libzip/zip_util.h Wed Jul 05 20:04:43 2017 +0200 @@ -154,6 +154,7 @@ * - If pos <= 0 then it is the position of entry LOC header. * If pos > 0 then it is the position of entry data. * pos should not be accessed directly, but only by ZIP_GetEntryDataOffset. + * - entry name may include embedded null character, use nlen for length */ typedef struct jzentry { /* Zip file entry */ @@ -166,6 +167,7 @@ jbyte *extra; /* optional extra data */ jlong pos; /* position of LOC header or entry data */ jint flag; /* general purpose flag */ + jint nlen; /* length of the entry name */ } jzentry; /* @@ -269,5 +271,5 @@ jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len); void ZIP_FreeEntry(jzfile *zip, jzentry *ze); jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry); - +jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash); #endif /* !_ZIP_H_ */ diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/unix/native/libnet/AbstractPlainDatagramSocketImpl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/unix/native/libnet/AbstractPlainDatagramSocketImpl.c Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +#ifdef __solaris__ +#include +#include + +#ifndef BSD_COMP +#define BSD_COMP +#endif + +#endif + +#include + +#include "jvm.h" +#include "jni_util.h" +#include "net_util.h" + +#include "java_net_AbstractPlainDatagramSocketImpl.h" + +static jfieldID IO_fd_fdID; + +static jfieldID apdsi_fdID; + + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { + + apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fdID); + + IO_fd_fdID = NET_GetFileDescriptorID(env); +} + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: dataAvailable + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable +(JNIEnv *env, jobject this) { + int fd, retval; + + jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID); + + if (IS_NULL(fdObj)) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Socket closed"); + return -1; + } + fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); + + if (ioctl(fd, FIONREAD, &retval) < 0) { + return -1; + } + return retval; +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/windows/conf/tzmappings --- a/jdk/src/java.base/windows/conf/tzmappings Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.base/windows/conf/tzmappings Wed Jul 05 20:04:43 2017 +0200 @@ -193,5 +193,10 @@ Turkey Standard Time:926,926::Asia/Istanbul: Bahia Standard Time:927,927::America/Bahia: Libya Standard Time:928,928:LY:Africa/Tripoli: -Western Brazilian Standard Time:929,929:BR:America/Rio_Branco: -Armenian Standard Time:930,930:AM:Asia/Yerevan: +Belarus Standard Time:929,929:BY:Europe/Minsk: +Line Islands Standard Time:930,930::Pacific/Kiritimati: +Russia Time Zone 10:931,931::Asia/Srednekolymsk: +Russia Time Zone 11:932,932::Asia/Anadyr: +Russia Time Zone 3:933,933::Europe/Samara: +Western Brazilian Standard Time:934,934:BR:America/Rio_Branco: +Armenian Standard Time:935,935:AM:Asia/Yerevan: diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.base/windows/native/libnet/AbstractPlainDatagramSocketImpl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/windows/native/libnet/AbstractPlainDatagramSocketImpl.c Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +#include "jvm.h" +#include "jni_util.h" +#include "net_util.h" + +#include "java_net_AbstractPlainDatagramSocketImpl.h" + +static jfieldID IO_fd_fdID; + +static jfieldID apdsi_fdID; + + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { + + apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fdID); + + IO_fd_fdID = NET_GetFileDescriptorID(env); + CHECK_NULL(IO_fd_fdID); + + JNU_CHECK_EXCEPTION(env); +} + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: dataAvailable + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable +(JNIEnv *env, jobject this) { + SOCKET fd; + int retval; + + jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID); + + if (IS_NULL(fdObj)) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Socket closed"); + return -1; + } + fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); + + if (ioctlsocket(fd, FIONREAD, &retval) < 0) { + return -1; + } + return retval; +} + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Jul 05 20:04:43 2017 +0200 @@ -567,7 +567,10 @@ CWrapper.NSWindow.makeKeyWindow(nsWindowPtr); } } else { + // immediately hide the window CWrapper.NSWindow.orderOut(nsWindowPtr); + // process the close + CWrapper.NSWindow.close(nsWindowPtr); } } else { // otherwise, put it in a proper z-order diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWrapper.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWrapper.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWrapper.java Wed Jul 05 20:04:43 2017 +0200 @@ -54,8 +54,26 @@ static native void orderFront(long window); static native void orderFrontRegardless(long window); static native void orderWindow(long window, int ordered, long relativeTo); + + /** + * Removes the window from the screen. + * + * @param window the pointer of the NSWindow + */ static native void orderOut(long window); + /** + * Removes the window from the screen and releases it. According to + * documentation this method should be similar to {@link #orderOut}, + * because we use ReleasedWhenClosed:NO, so the window shouldn't be + * released. But the close method works differently, for example it + * close the space if the window was in the full screen via + * {@link CPlatformWindow#toggleFullScreen()}. + * + * @param window the pointer of the NSWindow + */ + static native void close(long window); + static native void addChildWindow(long parent, long child, int ordered); static native void removeChildWindow(long parent, long child); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CWrapper.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CWrapper.m Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CWrapper.m Wed Jul 05 20:04:43 2017 +0200 @@ -175,6 +175,23 @@ /* * Class: sun_lwawt_macosx_CWrapper$NSWindow + * Method: close + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_sun_lwawt_macosx_CWrapper_00024NSWindow_close + (JNIEnv *env, jclass cls, jlong windowPtr) +{ +JNF_COCOA_ENTER(env); + NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr); + [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ + [window close]; + }]; +JNF_COCOA_EXIT(env); +} + +/* + * Class: sun_lwawt_macosx_CWrapper$NSWindow * Method: orderFrontRegardless * Signature: (J)V */ diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,7 +117,7 @@ } } - + @Override public final MidiDevice.Info[] getDeviceInfo() { readDeviceInfos(); Info[] infos = getInfoCache(); @@ -126,7 +126,7 @@ return localArray; } - + @Override public final MidiDevice getDevice(MidiDevice.Info info) { if (info instanceof Info) { readDeviceInfos(); @@ -143,9 +143,7 @@ } } } - - throw new IllegalArgumentException("MidiDevice " + info.toString() - + " not supported by this provider."); + throw MidiUtils.unsupportedDevice(info); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/com/sun/media/sound/MidiUtils.java --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/MidiUtils.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/MidiUtils.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,15 @@ package com.sun.media.sound; -import javax.sound.midi.*; import java.util.ArrayList; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.Sequence; +import javax.sound.midi.Track; + // TODO: // - define and use a global symbolic constant for 60000000 (see convertTempo) @@ -48,6 +54,17 @@ private MidiUtils() { } + /** + * Returns an exception which should be thrown if MidiDevice is unsupported. + * + * @param info an info object that describes the desired device + * @return an exception instance + */ + static RuntimeException unsupportedDevice(final MidiDevice.Info info) { + return new IllegalArgumentException(String.format( + "MidiDevice %s not supported by this provider", info)); + } + /** return true if the passed message is Meta End Of Track */ public static boolean isMetaEndOfTrack(MidiMessage midiMsg) { // first check if it is a META message at all diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencer.java --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencer.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencer.java Wed Jul 05 20:04:43 2017 +0200 @@ -64,7 +64,7 @@ /** * All RealTimeSequencers share this info object. */ - static final RealTimeSequencerInfo info = new RealTimeSequencerInfo(); + static final MidiDevice.Info info = new RealTimeSequencerInfo(); private static final Sequencer.SyncMode[] masterSyncModes = { Sequencer.SyncMode.INTERNAL_CLOCK }; @@ -154,7 +154,7 @@ /* ****************************** CONSTRUCTOR ****************************** */ - RealTimeSequencer() throws MidiUnavailableException { + RealTimeSequencer(){ super(info); if (Printer.trace) Printer.trace(">> RealTimeSequencer CONSTRUCTOR"); @@ -1088,7 +1088,7 @@ private static final String description = "Software sequencer"; private static final String version = "Version 1.0"; - private RealTimeSequencerInfo() { + RealTimeSequencerInfo() { super(name, vendor, description, version); } } // class Info diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package com.sun.media.sound; import javax.sound.midi.MidiDevice; -import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.spi.MidiDeviceProvider; /** @@ -36,23 +35,16 @@ */ public final class RealTimeSequencerProvider extends MidiDeviceProvider { - + @Override public MidiDevice.Info[] getDeviceInfo() { - - MidiDevice.Info[] localArray = { RealTimeSequencer.info }; - return localArray; + return new MidiDevice.Info[]{RealTimeSequencer.info}; } - - public MidiDevice getDevice(MidiDevice.Info info) { - if ((info != null) && (!info.equals(RealTimeSequencer.info))) { - return null; + @Override + public MidiDevice getDevice(final MidiDevice.Info info) { + if (RealTimeSequencer.info.equals(info)) { + return new RealTimeSequencer(); } - - try { - return new RealTimeSequencer(); - } catch (MidiUnavailableException e) { - return null; - } + throw MidiUtils.unsupportedDevice(info); } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,10 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; -import java.util.Arrays; import javax.sound.midi.MidiDevice; -import javax.sound.midi.MidiDevice.Info; import javax.sound.midi.spi.MidiDeviceProvider; /** @@ -36,17 +35,16 @@ */ public final class SoftProvider extends MidiDeviceProvider { - static final Info softinfo = SoftSynthesizer.info; - private static final Info[] softinfos = {softinfo}; - + @Override public MidiDevice.Info[] getDeviceInfo() { - return Arrays.copyOf(softinfos, softinfos.length); + return new MidiDevice.Info[]{SoftSynthesizer.info}; } - public MidiDevice getDevice(MidiDevice.Info info) { - if (info == softinfo) { + @Override + public MidiDevice getDevice(final MidiDevice.Info info) { + if (SoftSynthesizer.info.equals(info)) { return new SoftSynthesizer(); } - return null; + throw MidiUtils.unsupportedDevice(info); } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java --- a/jdk/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java Wed Jul 05 20:04:43 2017 +0200 @@ -182,7 +182,8 @@ "SunOS".equals(osName) || "FreeBSD".equals(osName) || "NetBSD".equals(osName) || - "OpenBSD".equals(osName)) && + "OpenBSD".equals(osName) || + "AIX".equals(osName)) && (System.getenv("DISPLAY") == null)); } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java --- a/jdk/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java Wed Jul 05 20:04:43 2017 +0200 @@ -245,7 +245,7 @@ public static boolean registerService(PrintService service) { synchronized (PrintServiceLookup.class) { - if (service instanceof StreamPrintService) { + if (service == null || service instanceof StreamPrintService) { return false; } ArrayList registeredServices = getRegisteredServices(); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java --- a/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java Wed Jul 05 20:04:43 2017 +0200 @@ -31,6 +31,7 @@ import java.io.OutputStream; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -162,18 +163,11 @@ * of length 0 is returned. */ public static MidiDevice.Info[] getMidiDeviceInfo() { - List allInfos = new ArrayList<>(); - List providers = getMidiDeviceProviders(); - - for(int i = 0; i < providers.size(); i++) { - MidiDeviceProvider provider = providers.get(i); - MidiDevice.Info[] tmpinfo = provider.getDeviceInfo(); - for (int j = 0; j < tmpinfo.length; j++) { - allInfos.add( tmpinfo[j] ); - } + final List allInfos = new ArrayList<>(); + for (final MidiDeviceProvider provider : getMidiDeviceProviders()) { + Collections.addAll(allInfos, provider.getDeviceInfo()); } - MidiDevice.Info[] infosArray = allInfos.toArray(new MidiDevice.Info[0]); - return infosArray; + return allInfos.toArray(new MidiDevice.Info[allInfos.size()]); } /** @@ -187,17 +181,15 @@ * MIDI device installed on the system * @see #getMidiDeviceInfo */ - public static MidiDevice getMidiDevice(MidiDevice.Info info) throws MidiUnavailableException { - List providers = getMidiDeviceProviders(); - - for(int i = 0; i < providers.size(); i++) { - MidiDeviceProvider provider = providers.get(i); + public static MidiDevice getMidiDevice(final MidiDevice.Info info) + throws MidiUnavailableException { + for (final MidiDeviceProvider provider : getMidiDeviceProviders()) { if (provider.isDeviceSupported(info)) { - MidiDevice device = provider.getDevice(info); - return device; + return provider.getDevice(info); } } - throw new IllegalArgumentException("Requested device not installed: " + info); + throw new IllegalArgumentException(String.format( + "Requested device not installed: %s", info)); } /** diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java --- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java Wed Jul 05 20:04:43 2017 +0200 @@ -25,6 +25,8 @@ package javax.sound.midi.spi; +import java.util.Arrays; + import javax.sound.midi.MidiDevice; /** @@ -45,16 +47,8 @@ * @return {@code true} if the specified device is supported, otherwise * {@code false} */ - public boolean isDeviceSupported(MidiDevice.Info info) { - - MidiDevice.Info infos[] = getDeviceInfo(); - - for(int i=0; i { - synchronized(JComponent.this) { - setFlag(REVALIDATE_RUNNABLE_SCHEDULED, false); - } + revalidateRunnableScheduled.set(false); revalidate(); }); } @@ -5567,6 +5564,7 @@ ToolTipManager.sharedInstance().registerComponent(this); } setWriteObjCounter(this, (byte)0); + revalidateRunnableScheduled = new AtomicBoolean(false); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/swing/JTable.java --- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java Wed Jul 05 20:04:43 2017 +0200 @@ -3688,17 +3688,17 @@ // /** - * Sets the data model for this table to newModel and registers + * Sets the data model for this table to {@code dataModel} and registers * with it for listener notifications from the new data model. * - * @param dataModel the new data source for this table - * @exception IllegalArgumentException if newModel is null - * @see #getModel + * @param dataModel the new data source for this table + * @throws IllegalArgumentException if {@code dataModel} is {@code null} + * @see #getModel * @beaninfo * bound: true * description: The model that is the source of the data for this view. */ - public void setModel(TableModel dataModel) { + public void setModel(final TableModel dataModel) { if (dataModel == null) { throw new IllegalArgumentException("Cannot set a null TableModel"); } @@ -3721,29 +3721,30 @@ } /** - * Returns the TableModel that provides the data displayed by this - * JTable. - * - * @return the TableModel that provides the data displayed by this JTable - * @see #setModel + * Returns the {@code TableModel} that provides the data displayed by this + * {@code JTable}. + * + * @return the {@code TableModel} that provides the data displayed by this + * {@code JTable} + * @see #setModel */ public TableModel getModel() { return dataModel; } /** - * Sets the column model for this table to newModel and registers - * for listener notifications from the new column model. Also sets - * the column model of the JTableHeader to columnModel. - * - * @param columnModel the new data source for this table - * @exception IllegalArgumentException if columnModel is null - * @see #getColumnModel + * Sets the column model for this table to {@code columnModel} and registers + * for listener notifications from the new column model. Also sets the + * column model of the {@code JTableHeader} to {@code columnModel}. + * + * @param columnModel the new data source for this table + * @throws IllegalArgumentException if {@code columnModel} is {@code null} + * @see #getColumnModel * @beaninfo * bound: true * description: The object governing the way columns appear in the view. */ - public void setColumnModel(TableColumnModel columnModel) { + public void setColumnModel(final TableColumnModel columnModel) { if (columnModel == null) { throw new IllegalArgumentException("Cannot set a null ColumnModel"); } @@ -3766,54 +3767,55 @@ } /** - * Returns the TableColumnModel that contains all column information + * Returns the {@code TableColumnModel} that contains all column information * of this table. * - * @return the object that provides the column state of the table - * @see #setColumnModel + * @return the object that provides the column state of the table + * @see #setColumnModel */ public TableColumnModel getColumnModel() { return columnModel; } /** - * Sets the row selection model for this table to newModel + * Sets the row selection model for this table to {@code selectionModel} * and registers for listener notifications from the new selection model. * - * @param newModel the new selection model - * @exception IllegalArgumentException if newModel is null - * @see #getSelectionModel + * @param selectionModel the new selection model + * @throws IllegalArgumentException if {@code selectionModel} is + * {@code null} + * @see #getSelectionModel * @beaninfo * bound: true * description: The selection model for rows. */ - public void setSelectionModel(ListSelectionModel newModel) { - if (newModel == null) { + public void setSelectionModel(final ListSelectionModel selectionModel) { + if (selectionModel == null) { throw new IllegalArgumentException("Cannot set a null SelectionModel"); } - ListSelectionModel oldModel = selectionModel; - - if (newModel != oldModel) { + ListSelectionModel oldModel = this.selectionModel; + + if (selectionModel != oldModel) { if (oldModel != null) { oldModel.removeListSelectionListener(this); } - selectionModel = newModel; - newModel.addListSelectionListener(this); - - firePropertyChange("selectionModel", oldModel, newModel); + this.selectionModel = selectionModel; + selectionModel.addListSelectionListener(this); + + firePropertyChange("selectionModel", oldModel, selectionModel); repaint(); } } /** - * Returns the ListSelectionModel that is used to maintain row + * Returns the {@code ListSelectionModel} that is used to maintain row * selection state. * - * @return the object that provides row selection state, null - * if row selection is not allowed - * @see #setSelectionModel + * @return the object that provides row selection state, {@code null} if row + * selection is not allowed + * @see #setSelectionModel */ public ListSelectionModel getSelectionModel() { return selectionModel; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java Wed Jul 05 20:04:43 2017 +0200 @@ -1122,6 +1122,11 @@ Position.Bias b, int direction, Position.Bias[] biasRet) throws BadLocationException{ Document doc = editor.getDocument(); + + if (pos < -1 || pos > doc.getLength()) { + throw new BadLocationException("Invalid position", pos); + } + if (doc instanceof AbstractDocument) { ((AbstractDocument)doc).readLock(); } @@ -1594,7 +1599,7 @@ int direction, Position.Bias[] biasRet) throws BadLocationException { - if (pos < -1) { + if (pos < -1 || pos > getDocument().getLength()) { throw new BadLocationException("invalid position", pos); } if( view != null ) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/swing/text/AsyncBoxView.java --- a/jdk/src/java.desktop/share/classes/javax/swing/text/AsyncBoxView.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/AsyncBoxView.java Wed Jul 05 20:04:43 2017 +0200 @@ -854,7 +854,7 @@ int direction, Position.Bias[] biasRet) throws BadLocationException { - if (pos < -1) { + if (pos < -1 || pos > getDocument().getLength()) { throw new BadLocationException("invalid position", pos); } return Utilities.getNextVisualPositionFrom( diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java --- a/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java Wed Jul 05 20:04:43 2017 +0200 @@ -463,7 +463,7 @@ public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet) throws BadLocationException { - if (pos < -1) { + if (pos < -1 || pos > getDocument().getLength()) { throw new BadLocationException("invalid position", pos); } Rectangle alloc = getInsideAllocation(a); @@ -723,6 +723,9 @@ Shape a, int direction, Position.Bias[] biasRet) throws BadLocationException { + if (pos < -1 || pos > getDocument().getLength()) { + throw new BadLocationException("invalid position", pos); + } return Utilities.getNextVisualPositionFrom( this, pos, b, a, direction, biasRet); } @@ -754,6 +757,9 @@ int direction, Position.Bias[] biasRet) throws BadLocationException { + if (pos < -1 || pos > getDocument().getLength()) { + throw new BadLocationException("invalid position", pos); + } return Utilities.getNextVisualPositionFrom( this, pos, b, a, direction, biasRet); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/swing/text/GlyphView.java --- a/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphView.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphView.java Wed Jul 05 20:04:43 2017 +0200 @@ -900,7 +900,7 @@ Position.Bias[] biasRet) throws BadLocationException { - if (pos < -1) { + if (pos < -1 || pos > getDocument().getLength()) { throw new BadLocationException("invalid position", pos); } return painter.getNextVisualPositionFrom(this, pos, b, a, direction, biasRet); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/javax/swing/text/View.java --- a/jdk/src/java.desktop/share/classes/javax/swing/text/View.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/View.java Wed Jul 05 20:04:43 2017 +0200 @@ -500,7 +500,7 @@ public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet) throws BadLocationException { - if (pos < -1) { + if (pos < -1 || pos > getDocument().getLength()) { // -1 is a reserved value, see the code below throw new BadLocationException("Invalid position", pos); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java --- a/jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java Wed Jul 05 20:04:43 2017 +0200 @@ -1408,10 +1408,10 @@ } } - int lastbit = (dataBitOffset - + (height-1) * scanlineStride * 8 - + (width-1) * pixelBitStride - + pixelBitStride - 1); + long lastbit = (long) dataBitOffset + + (long) (height - 1) * (long) scanlineStride * 8 + + (long) (width - 1) * (long) pixelBitStride + + (long) pixelBitStride - 1; if (lastbit < 0 || lastbit / 8 >= data.length) { throw new RasterFormatException("raster dimensions overflow " + "array bounds"); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/classes/sun/datatransfer/DataFlavorUtil.java --- a/jdk/src/java.desktop/share/classes/sun/datatransfer/DataFlavorUtil.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/classes/sun/datatransfer/DataFlavorUtil.java Wed Jul 05 20:04:43 2017 +0200 @@ -581,6 +581,15 @@ return comp; } + // Next prefer text types + if (flavor1.isFlavorTextType()) { + return 1; + } + + if (flavor2.isFlavorTextType()) { + return -1; + } + // Next, look for application/x-java-* types. Prefer unknown // MIME types because if the user provides his own data flavor, // it will likely be the most descriptive one. diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c --- a/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c Wed Jul 05 20:04:43 2017 +0200 @@ -425,7 +425,6 @@ jobject metrics; jfloat ax, ay, dx, dy, bx, by, lx, ly, mx, my; jfloat f0 = 0.0; - FT_Pos bmodifier = 0; FTScalerContext *context = (FTScalerContext*) jlong_to_ptr(pScalerContext); FTScalerInfo *scalerInfo = @@ -458,43 +457,38 @@ So, we have to do adust them explicitly and stay consistent with what freetype does to outlines. */ - /* For bolding glyphs are not just widened. Height is also changed - (see ftsynth.c). - - TODO: In vertical direction we could do better job and adjust metrics - proportionally to glyoh shape. */ - if (context->doBold) { - bmodifier = FT_MulFix( - scalerInfo->face->units_per_EM, - scalerInfo->face->size->metrics.y_scale)/24; - } - /**** Note: only some metrics are affected by styling ***/ + /* See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657854 */ +#define FT_MulFixFloatShift6(a, b) (((float) (a)) * ((float) (b)) / 65536.0 / 64.0) + + /* + * See FreeType source code: src/base/ftobjs.c ft_recompute_scaled_metrics() + * http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1659 + */ /* ascent */ ax = 0; - ay = -(jfloat) FT26Dot6ToFloat(FT_MulFix( - ((jlong) scalerInfo->face->ascender + bmodifier/2), + ay = -(jfloat) (FT_MulFixFloatShift6( + ((jlong) scalerInfo->face->ascender), (jlong) scalerInfo->face->size->metrics.y_scale)); /* descent */ dx = 0; - dy = -(jfloat) FT26Dot6ToFloat(FT_MulFix( - ((jlong) scalerInfo->face->descender + bmodifier/2), + dy = -(jfloat) (FT_MulFixFloatShift6( + ((jlong) scalerInfo->face->descender), (jlong) scalerInfo->face->size->metrics.y_scale)); /* baseline */ bx = by = 0; /* leading */ lx = 0; - ly = (jfloat) FT26Dot6ToFloat(FT_MulFix( - (jlong) scalerInfo->face->height + bmodifier, + ly = (jfloat) (FT_MulFixFloatShift6( + (jlong) scalerInfo->face->height, (jlong) scalerInfo->face->size->metrics.y_scale)) + ay - dy; /* max advance */ mx = (jfloat) FT26Dot6ToFloat( scalerInfo->face->size->metrics.max_advance + - 2*bmodifier + OBLIQUE_MODIFIER(scalerInfo->face->size->metrics.height)); my = 0; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualSubstSubtables.cpp --- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualSubstSubtables.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualSubstSubtables.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -243,12 +243,22 @@ le_uint16 srSetCount = SWAPW(subRuleSetCount); if (coverageIndex < srSetCount) { + LEReferenceToArrayOf subRuleSetTableOffsetArrayRef(base, success, + &subRuleSetTableOffsetArray[coverageIndex], 1); + if (LE_FAILURE(success)) { + return 0; + } Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); LEReferenceTo subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset)); le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); + LEReferenceToArrayOf subRuleTableOffsetArrayRef(base, success, + subRuleSetTable->subRuleTableOffsetArray, subRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) { Offset subRuleTableOffset = SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]); @@ -301,34 +311,44 @@ glyphIterator->getCurrGlyphID(), success); - if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) { - Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); - LEReferenceTo - subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset)); - le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); - le_int32 position = glyphIterator->getCurrStreamPosition(); + if (setClass < scSetCount) { + LEReferenceToArrayOf + subClassSetTableOffsetArrayRef(base, success, subClassSetTableOffsetArray, setClass); + if (LE_FAILURE(success)) { return 0; } + if (subClassSetTableOffsetArray[setClass] != 0) { - for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { - Offset subClassRuleTableOffset = - SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); - LEReferenceTo - subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset); - le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; - le_uint16 substCount = SWAPW(subClassRuleTable->substCount); - - LEReferenceToArrayOf classArray(base, success, subClassRuleTable->classArray, matchCount+1); + Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); + LEReferenceTo + subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset)); + le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); + le_int32 position = glyphIterator->getCurrStreamPosition(); + LEReferenceToArrayOf + subClassRuleTableOffsetArrayRef(base, success, subClassSetTable->subClassRuleTableOffsetArray, subClassRuleCount); + if (LE_FAILURE(success)) { + return 0; + } + for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { + Offset subClassRuleTableOffset = + SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); + LEReferenceTo + subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset); + le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; + le_uint16 substCount = SWAPW(subClassRuleTable->substCount); - if (LE_FAILURE(success)) { return 0; } - if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) { - LEReferenceToArrayOf - substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount); + LEReferenceToArrayOf classArray(base, success, subClassRuleTable->classArray, matchCount+1); + + if (LE_FAILURE(success)) { return 0; } + 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); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); - return matchCount + 1; + return matchCount + 1; + } + + glyphIterator->setCurrStreamPosition(position); } - - glyphIterator->setCurrStreamPosition(position); } } @@ -442,13 +462,22 @@ le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); if (coverageIndex < srSetCount) { + LEReferenceToArrayOf + chainSubRuleSetTableOffsetArrayRef(base, success, chainSubRuleSetTableOffsetArray, coverageIndex); + if (LE_FAILURE(success)) { + return 0; + } Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); LEReferenceTo chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset)); le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); - + LEReferenceToArrayOf + chainSubRuleTableOffsetArrayRef(base, success, chainSubRuleSetTable->chainSubRuleTableOffsetArray, chainSubRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { Offset chainSubRuleTableOffset = SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]); @@ -530,6 +559,11 @@ le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable, glyphIterator->getCurrGlyphID(), success); + LEReferenceToArrayOf + chainSubClassSetTableOffsetArrayRef(base, success, chainSubClassSetTableOffsetArray, setClass); + if (LE_FAILURE(success)) { + return 0; + } if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) { Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]); @@ -538,7 +572,11 @@ le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); - + LEReferenceToArrayOf + chainSubClassRuleTableOffsetArrayRef(base, success, chainSubClassSetTable->chainSubClassRuleTableOffsetArray, chainSubClassRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { Offset chainSubClassRuleTableOffset = SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]); @@ -603,12 +641,14 @@ } le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); + LEReferenceToArrayOf backtrackGlyphArrayRef(base, success, backtrackCoverageTableOffsetArray, backtrkGlyphCount); + if (LE_FAILURE(success)) { + return 0; + } le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); LEReferenceToArrayOf inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset if (LE_FAILURE(success)) { return 0; } const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]); - - if( LE_FAILURE(success)) { return 0; } LEReferenceToArrayOf lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2); if( LE_FAILURE(success) ) { return 0; } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java --- a/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java Wed Jul 05 20:04:43 2017 +0200 @@ -136,7 +136,7 @@ /** * Returns array of MediaSizeNames derived from PPD. */ - public MediaSizeName[] getMediaSizeNames() { + MediaSizeName[] getMediaSizeNames() { initMedia(); return cupsMediaSNames; } @@ -145,7 +145,7 @@ /** * Returns array of Custom MediaSizeNames derived from PPD. */ - public CustomMediaSizeName[] getCustomMediaSizeNames() { + CustomMediaSizeName[] getCustomMediaSizeNames() { initMedia(); return cupsCustomMediaSNames; } @@ -157,7 +157,7 @@ /** * Returns array of MediaPrintableArea derived from PPD. */ - public MediaPrintableArea[] getMediaPrintableArea() { + MediaPrintableArea[] getMediaPrintableArea() { initMedia(); return cupsMediaPrintables; } @@ -165,7 +165,7 @@ /** * Returns array of MediaTrays derived from PPD. */ - public MediaTray[] getMediaTrays() { + MediaTray[] getMediaTrays() { initMedia(); return cupsMediaTrays; } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java --- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Wed Jul 05 20:04:43 2017 +0200 @@ -1002,7 +1002,9 @@ public synchronized Class[] getSupportedAttributeCategories() { if (supportedCats != null) { - return supportedCats; + Class [] copyCats = new Class[supportedCats.length]; + System.arraycopy(supportedCats, 0, copyCats, 0, copyCats.length); + return copyCats; } initAttributes(); @@ -1065,7 +1067,9 @@ supportedCats = new Class[catList.size()]; catList.toArray(supportedCats); - return supportedCats; + Class[] copyCats = new Class[supportedCats.length]; + System.arraycopy(supportedCats, 0, copyCats, 0, copyCats.length); + return copyCats; } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/unix/native/common/awt/awt_util.h --- a/jdk/src/java.desktop/unix/native/common/awt/awt_util.h Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/unix/native/common/awt/awt_util.h Wed Jul 05 20:04:43 2017 +0200 @@ -52,6 +52,8 @@ */ extern XErrorHandler current_native_xerror_handler; +Window get_xawt_root_shell(JNIEnv *env); + #endif /* !HEADLESS */ #ifndef INTERSECTS diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c --- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c Wed Jul 05 20:04:43 2017 +0200 @@ -2011,10 +2011,14 @@ * Toolkit thread to process PropertyNotify or SelectionNotify events. */ static Bool -secondary_loop_event(Display* dpy, XEvent* event, char* arg) { - return (event->type == SelectionNotify || - event->type == SelectionClear || - event->type == PropertyNotify) ? True : False; +secondary_loop_event(Display* dpy, XEvent* event, XPointer xawt_root_window) { + return ( + event->type == SelectionNotify || + event->type == SelectionClear || + event->type == PropertyNotify || + (event->type == ConfigureNotify + && event->xany.window == *(Window*) xawt_root_window) + ) ? True : False; } @@ -2025,8 +2029,11 @@ AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); exitSecondaryLoop = False; + Window xawt_root_window = get_xawt_root_shell(env); + while (!exitSecondaryLoop) { - if (XCheckIfEvent((Display*) jlong_to_ptr(display), (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, NULL)) { + if (XCheckIfEvent((Display*) jlong_to_ptr(display), + (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, (XPointer) &xawt_root_window)) { return JNI_TRUE; } timeout = (timeout < AWT_SECONDARY_LOOP_TIMEOUT) ? (timeout << 1) : AWT_SECONDARY_LOOP_TIMEOUT; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIRenderer.cpp --- a/jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIRenderer.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/windows/GDIRenderer.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -670,7 +670,7 @@ if (ypoints != NULL) { pPoints = TransformPoly(xpoints, ypoints, transx, transy, tmpPts, &npoints, FALSE, FALSE); - env->ReleasePrimitiveArrayCritical(ypointsarray, xpoints, JNI_ABORT); + env->ReleasePrimitiveArrayCritical(ypointsarray, ypoints, JNI_ABORT); } env->ReleasePrimitiveArrayCritical(xpointsarray, xpoints, JNI_ABORT); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -3936,7 +3936,6 @@ DASSERT(stringCls); CHECK_NULL(stringCls); clauseReading = env->NewObjectArray(cClause, stringCls, NULL); - env->DeleteLocalRef(stringCls); DASSERT(clauseReading); CHECK_NULL(clauseReading); for (int i=0; iSetObjectArrayElement(clauseReading, i, rgClauseReading[i]); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -47,16 +47,12 @@ jfieldID AwtTextArea::scrollbarVisibilityID; -WNDPROC AwtTextArea::sm_pDefWindowProc = NULL; - /************************************************************************ * AwtTextArea methods */ AwtTextArea::AwtTextArea() { - m_bIgnoreEnChange = FALSE; m_bCanUndo = FALSE; - m_hEditCtrl = NULL; m_lHDeltaAccum = 0; m_lVDeltaAccum = 0; } @@ -67,10 +63,6 @@ void AwtTextArea::Dispose() { - if (m_hEditCtrl != NULL) { - VERIFY(::DestroyWindow(m_hEditCtrl)); - m_hEditCtrl = NULL; - } AwtTextComponent::Dispose(); } @@ -91,10 +83,6 @@ } } -void AwtTextArea::EditGetSel(CHARRANGE &cr) { - SendMessage(EM_EXGETSEL, 0, reinterpret_cast(&cr)); -} - /* Count how many '\n's are there in jStr */ size_t AwtTextArea::CountNewLines(JNIEnv *env, jstring jStr, size_t maxlen) { @@ -149,159 +137,6 @@ return retValue; } -/* - * This routine is a window procedure for the subclass of the standard edit control - * used to generate context menu. RichEdit controls don't have built-in context menu. - * To implement this functionality we have to create an invisible edit control and - * forward WM_CONTEXTMENU messages from a RichEdit control to this helper edit control. - * While the edit control context menu is active we intercept the message generated in - * response to particular item selection and forward it back to the RichEdit control. - * (See AwtTextArea::WmContextMenu for more details). - */ -LRESULT -AwtTextArea::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - - static BOOL bContextMenuActive = FALSE; - - LRESULT retValue = 0; - MsgRouting mr = mrDoDefault; - - DASSERT(::IsWindow(::GetParent(hWnd))); - - switch (message) { - case WM_UNDO: - case WM_CUT: - case WM_COPY: - case WM_PASTE: - case WM_CLEAR: - case EM_SETSEL: - if (bContextMenuActive) { - ::SendMessage(::GetParent(hWnd), message, wParam, lParam); - mr = mrConsume; - } - break; - case WM_CONTEXTMENU: - bContextMenuActive = TRUE; - break; - } - - if (mr == mrDoDefault) { - DASSERT(sm_pDefWindowProc != NULL); - retValue = ::CallWindowProc(sm_pDefWindowProc, - hWnd, message, wParam, lParam); - } - - if (message == WM_CONTEXTMENU) { - bContextMenuActive = FALSE; - } - - return retValue; -} - -MsgRouting -AwtTextArea::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) { - /* Use the system provided edit control class to generate context menu. */ - if (m_hEditCtrl == NULL) { - DWORD dwStyle = WS_CHILD; - DWORD dwExStyle = 0; - m_hEditCtrl = ::CreateWindowEx(dwExStyle, - L"EDIT", - L"TEXT", - dwStyle, - 0, 0, 0, 0, - GetHWnd(), - reinterpret_cast( - static_cast( - CreateControlID())), - AwtToolkit::GetInstance().GetModuleHandle(), - NULL); - DASSERT(m_hEditCtrl != NULL); - if (sm_pDefWindowProc == NULL) { - sm_pDefWindowProc = (WNDPROC)::GetWindowLongPtr(m_hEditCtrl, - GWLP_WNDPROC); - } - ::SetLastError(0); - INT_PTR ret = ::SetWindowLongPtr(m_hEditCtrl, GWLP_WNDPROC, - (INT_PTR)AwtTextArea::EditProc); - DASSERT(ret != 0 || ::GetLastError() == 0); - } - - /* - * Tricks on the edit control to ensure that its context menu has - * the correct set of enabled items according to the RichEdit state. - */ - ::SetWindowText(m_hEditCtrl, TEXT("TEXT")); - - if (m_bCanUndo == TRUE && SendMessage(EM_CANUNDO)) { - /* Enable 'Undo' item. */ - ::SendMessage(m_hEditCtrl, WM_CHAR, 'A', 0); - } - - { - /* - * Initial selection for the edit control - (0,1). - * This enables 'Cut', 'Copy' and 'Delete' and 'Select All'. - */ - INT nStart = 0; - INT nEnd = 1; - if (SendMessage(EM_SELECTIONTYPE) == SEL_EMPTY) { - /* - * RichEdit selection is empty - clear selection of the edit control. - * This disables 'Cut', 'Copy' and 'Delete'. - */ - nStart = -1; - nEnd = 0; - } else { - - CHARRANGE cr; - EditGetSel(cr); - /* Check if all the text is selected. */ - if (cr.cpMin == 0) { - - int len = ::GetWindowTextLength(GetHWnd()); - if (cr.cpMin == 0 && cr.cpMax >= len) { - /* - * All the text is selected in RichEdit - select all the - * text in the edit control. This disables 'Select All'. - */ - nStart = 0; - nEnd = -1; - } - } - } - ::SendMessage(m_hEditCtrl, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd); - } - - /* Disable 'Paste' item if the RichEdit control is read-only. */ - ::SendMessage(m_hEditCtrl, EM_SETREADONLY, - GetStyle() & ES_READONLY ? TRUE : FALSE, 0); - - POINT p; - p.x = xPos; - p.y = yPos; - - /* - * If the context menu is requested with SHIFT+F10 or VK_APPS key, - * we position its top left corner to the center of the RichEdit - * client rect. - */ - if (p.x == -1 && p.y == -1) { - RECT r; - VERIFY(::GetClientRect(GetHWnd(), &r)); - p.x = (r.left + r.right) / 2; - p.y = (r.top + r.bottom) / 2; - VERIFY(::ClientToScreen(GetHWnd(), &p)); - } - - // The context menu steals focus from the proxy. - // So, set the focus-restore flag up. - SetRestoreFocus(TRUE); - ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y)); - SetRestoreFocus(FALSE); - - return mrConsume; -} - MsgRouting AwtTextArea::WmNcHitTest(UINT x, UINT y, LRESULT& retVal) { @@ -314,27 +149,8 @@ MsgRouting -AwtTextArea::WmNotify(UINT notifyCode) -{ - if (notifyCode == EN_CHANGE) { - /* - * Ignore notifications if the text hasn't been changed. - * EN_CHANGE sent on character formatting changes as well. - */ - if (m_bIgnoreEnChange == FALSE) { - m_bCanUndo = TRUE; - DoCallback("valueChanged", "()V"); - } else { - m_bCanUndo = FALSE; - } - } - return mrDoDefault; -} - -MsgRouting AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic) { - MsgRouting returnVal; /* * RichEdit 1.0 control starts internal message loop if the * left mouse button is pressed while the cursor is not over @@ -486,26 +302,6 @@ } delete msg; return mrConsume; - } else if (msg->message == WM_RBUTTONUP || - (msg->message == WM_SYSKEYDOWN && msg->wParam == VK_F10 && - HIBYTE(::GetKeyState(VK_SHIFT)))) { - POINT p; - if (msg->message == WM_RBUTTONUP) { - VERIFY(::GetCursorPos(&p)); - } else { - p.x = -1; - p.y = -1; - } - - if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(), - MAKELPARAM(p.x, p.y))) { - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); - env->ExceptionDescribe(); - env->ExceptionClear(); - } - delete msg; - return mrConsume; } else if (msg->message == WM_MOUSEWHEEL) { // 4417236: If there is an old version of RichEd32.dll which // does not provide the mouse wheel scrolling we have to @@ -596,15 +392,7 @@ // 4417236: end of fix } - /* - * Store the 'synthetic' parameter so that the WM_PASTE security check - * happens only for synthetic events. - */ - m_synthetic = synthetic; - returnVal = AwtComponent::HandleEvent(msg, synthetic); - m_synthetic = FALSE; - - return returnVal; + return AwtTextComponent::HandleEvent(msg, synthetic); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.h --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.h Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.h Wed Jul 05 20:04:43 2017 +0200 @@ -57,17 +57,11 @@ static size_t GetALength(JNIEnv* env, jstring jStr, size_t maxlen); LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK EditProc(HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam); MsgRouting WmEnable(BOOL fEnabled); - MsgRouting WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos); - MsgRouting WmNotify(UINT notifyCode); MsgRouting WmNcHitTest(UINT x, UINT y, LRESULT &retVal); MsgRouting HandleEvent(MSG *msg, BOOL synthetic); - INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; } - virtual BOOL InheritsNativeMouseWheelBehavior(); virtual void Reshape(int x, int y, int w, int h); @@ -81,22 +75,7 @@ protected: void EditSetSel(CHARRANGE &cr); - void EditGetSel(CHARRANGE &cr); private: - // RichEdit 1.0 control generates EN_CHANGE notifications not only - // on text changes, but also on any character formatting change. - // This flag is true when the latter case is detected. - BOOL m_bIgnoreEnChange; - - // RichEdit 1.0 control undoes a character formatting change - // if it is the latest. We don't create our own undo buffer, - // but just prohibit undo in case if the latest operation - // is a formatting change. - BOOL m_bCanUndo; - - HWND m_hEditCtrl; - static WNDPROC sm_pDefWindowProc; - LONG m_lHDeltaAccum; LONG m_lVDeltaAccum; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -66,6 +66,8 @@ m_lLastPos = -1; m_isLFonly = FALSE; m_EOLchecked = FALSE; + m_hEditCtrl = NULL; + m_bIgnoreEnChange = FALSE; // javaEventsMask = 0; // accessibility support } @@ -213,6 +215,16 @@ return c; } +void AwtTextComponent::Dispose() +{ + if (m_hEditCtrl != NULL) { + VERIFY(::DestroyWindow(m_hEditCtrl)); + m_hEditCtrl = NULL; + } + AwtComponent::Dispose(); +} + + LRESULT AwtTextComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { @@ -322,7 +334,16 @@ AwtTextComponent::WmNotify(UINT notifyCode) { if (notifyCode == EN_CHANGE) { - DoCallback("valueChanged", "()V"); + /* + * Ignore notifications if the text hasn't been changed. + * EN_CHANGE sent on character formatting changes as well. + */ + if (m_bIgnoreEnChange == FALSE) { + m_bCanUndo = TRUE; + DoCallback("valueChanged", "()V"); + } else { + m_bCanUndo = FALSE; + } } return mrDoDefault; } @@ -337,6 +358,28 @@ { MsgRouting returnVal; + if (msg->message == WM_RBUTTONUP || + (msg->message == WM_SYSKEYDOWN && msg->wParam == VK_F10 && + HIBYTE(::GetKeyState(VK_SHIFT)))) { + POINT p; + if (msg->message == WM_RBUTTONUP) { + VERIFY(::GetCursorPos(&p)); + } else { + p.x = -1; + p.y = -1; + } + + if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(), + MAKELPARAM(p.x, p.y))) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); + env->ExceptionDescribe(); + env->ExceptionClear(); + } + delete msg; + return mrConsume; + } + /* * Store the 'synthetic' parameter so that the WM_PASTE security check * happens only for synthetic events. @@ -701,6 +744,10 @@ SendMessage(EM_SETBKGNDCOLOR, (WPARAM)FALSE, (LPARAM)GetBackgroundColor()); } +void AwtTextComponent::EditGetSel(CHARRANGE &cr) { + SendMessage(EM_EXGETSEL, 0, reinterpret_cast(&cr)); +} + /************************************************************************ * WTextComponentPeer native methods @@ -983,6 +1030,161 @@ } +/* + * This routine is a window procedure for the subclass of the standard edit control + * used to generate context menu. RichEdit controls don't have built-in context menu. + * To implement this functionality we have to create an invisible edit control and + * forward WM_CONTEXTMENU messages from a RichEdit control to this helper edit control. + * While the edit control context menu is active we intercept the message generated in + * response to particular item selection and forward it back to the RichEdit control. + * (See AwtTextArea::WmContextMenu for more details). + */ + +WNDPROC AwtTextComponent::sm_pDefWindowProc = NULL; + +LRESULT +AwtTextComponent::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + + static BOOL bContextMenuActive = FALSE; + + LRESULT retValue = 0; + MsgRouting mr = mrDoDefault; + + DASSERT(::IsWindow(::GetParent(hWnd))); + + switch (message) { + case WM_UNDO: + case WM_CUT: + case WM_COPY: + case WM_PASTE: + case WM_CLEAR: + case EM_SETSEL: + if (bContextMenuActive) { + ::SendMessage(::GetParent(hWnd), message, wParam, lParam); + mr = mrConsume; + } + break; + case WM_CONTEXTMENU: + bContextMenuActive = TRUE; + break; + } + + if (mr == mrDoDefault) { + DASSERT(sm_pDefWindowProc != NULL); + retValue = ::CallWindowProc(sm_pDefWindowProc, + hWnd, message, wParam, lParam); + } + + if (message == WM_CONTEXTMENU) { + bContextMenuActive = FALSE; + } + + return retValue; +} + +MsgRouting +AwtTextComponent::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) { + /* Use the system provided edit control class to generate context menu. */ + if (m_hEditCtrl == NULL) { + DWORD dwStyle = WS_CHILD; + DWORD dwExStyle = 0; + m_hEditCtrl = ::CreateWindowEx(dwExStyle, + L"EDIT", + L"TEXT", + dwStyle, + 0, 0, 0, 0, + GetHWnd(), + reinterpret_cast( + static_cast( + CreateControlID())), + AwtToolkit::GetInstance().GetModuleHandle(), + NULL); + DASSERT(m_hEditCtrl != NULL); + if (sm_pDefWindowProc == NULL) { + sm_pDefWindowProc = (WNDPROC)::GetWindowLongPtr(m_hEditCtrl, + GWLP_WNDPROC); + } + ::SetLastError(0); + INT_PTR ret = ::SetWindowLongPtr(m_hEditCtrl, GWLP_WNDPROC, + (INT_PTR)AwtTextArea::EditProc); + DASSERT(ret != 0 || ::GetLastError() == 0); + } + + /* + * Tricks on the edit control to ensure that its context menu has + * the correct set of enabled items according to the RichEdit state. + */ + ::SetWindowText(m_hEditCtrl, TEXT("TEXT")); + + if (m_bCanUndo == TRUE && SendMessage(EM_CANUNDO)) { + /* Enable 'Undo' item. */ + ::SendMessage(m_hEditCtrl, WM_CHAR, 'A', 0); + } + + { + /* + * Initial selection for the edit control - (0,1). + * This enables 'Cut', 'Copy' and 'Delete' and 'Select All'. + */ + INT nStart = 0; + INT nEnd = 1; + if (SendMessage(EM_SELECTIONTYPE) == SEL_EMPTY) { + /* + * RichEdit selection is empty - clear selection of the edit control. + * This disables 'Cut', 'Copy' and 'Delete'. + */ + nStart = -1; + nEnd = 0; + } else { + + CHARRANGE cr; + EditGetSel(cr); + /* Check if all the text is selected. */ + if (cr.cpMin == 0) { + + int len = ::GetWindowTextLength(GetHWnd()); + if (cr.cpMin == 0 && cr.cpMax >= len) { + /* + * All the text is selected in RichEdit - select all the + * text in the edit control. This disables 'Select All'. + */ + nStart = 0; + nEnd = -1; + } + } + } + ::SendMessage(m_hEditCtrl, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd); + } + + /* Disable 'Paste' item if the RichEdit control is read-only. */ + ::SendMessage(m_hEditCtrl, EM_SETREADONLY, + GetStyle() & ES_READONLY ? TRUE : FALSE, 0); + + POINT p; + p.x = xPos; + p.y = yPos; + + /* + * If the context menu is requested with SHIFT+F10 or VK_APPS key, + * we position its top left corner to the center of the RichEdit + * client rect. + */ + if (p.x == -1 && p.y == -1) { + RECT r; + VERIFY(::GetClientRect(GetHWnd(), &r)); + p.x = (r.left + r.right) / 2; + p.y = (r.top + r.bottom) / 2; + VERIFY(::ClientToScreen(GetHWnd(), &p)); + } + + // The context menu steals focus from the proxy. + // So, set the focus-restore flag up. + SetRestoreFocus(TRUE); + ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y)); + SetRestoreFocus(FALSE); + + return mrConsume; +} // // Accessibility support diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h Wed Jul 05 20:04:43 2017 +0200 @@ -47,6 +47,8 @@ static AwtTextComponent* Create(jobject self, jobject parent, BOOL isMultiline); + virtual void Dispose(); + virtual LPCTSTR GetClassName(); LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); @@ -83,6 +85,8 @@ MsgRouting HandleEvent(MSG *msg, BOOL synthetic); MsgRouting WmPaste(); + INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; } + virtual BOOL IsFocusingMouseMessage(MSG *pMsg); /* To be fully implemented in a future release @@ -115,11 +119,24 @@ INLINE VOID SetEndSelectionPos(LONG lPos) { m_lEndPos = lPos; } INLINE VOID SetLastSelectionPos(LONG lPos) { m_lLastPos = lPos; } + void EditGetSel(CHARRANGE &cr); + // Used to prevent untrusted code from synthesizing a WM_PASTE message // by posting a -V KeyEvent BOOL m_synthetic; LONG EditGetCharFromPos(POINT& pt); + // RichEdit 1.0 control generates EN_CHANGE notifications not only + // on text changes, but also on any character formatting change. + // This flag is true when the latter case is detected. + BOOL m_bIgnoreEnChange; + + // RichEdit 1.0 control undoes a character formatting change + // if it is the latest. We don't create our own undo buffer, + // but just prohibit undo in case if the latest operation + // is a formatting change. + BOOL m_bCanUndo; + /***************************************************************** * Inner class OleCallback declaration. */ @@ -166,6 +183,13 @@ static OleCallback sm_oleCallback; + static WNDPROC sm_pDefWindowProc; + HWND m_hEditCtrl; + + static LRESULT CALLBACK EditProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + MsgRouting WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos); + // // Accessibility support // diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp Wed Jul 05 20:04:43 2017 +0200 @@ -249,13 +249,7 @@ } } - /* - * Store the 'synthetic' parameter so that the WM_PASTE security check - * happens only for synthetic events. - */ - m_synthetic = synthetic; - returnVal = AwtComponent::HandleEvent(msg, synthetic); - m_synthetic = FALSE; + returnVal = AwtTextComponent::HandleEvent(msg, synthetic); if(systemBeeperEnabled){ SystemParametersInfo(SPI_SETBEEP, 1, NULL, 0); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c --- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,6 +213,14 @@ void SplashRedrawWindow(Splash * splash) { + if (!SplashIsStillLooping(splash)) { + KillTimer(splash->hWnd, 0); + } + + if (splash->currentFrame < 0) { + return; + } + SplashUpdateScreenData(splash); if (splash->isLayered) { BLENDFUNCTION bf; @@ -303,9 +311,6 @@ time = 0; SetTimer(splash->hWnd, 0, time, NULL); } - else { - KillTimer(splash->hWnd, 0); - } } void SplashReconfigureNow(Splash * splash) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java --- a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java Wed Jul 05 20:04:43 2017 +0200 @@ -509,7 +509,13 @@ // If necessary, try to regenerate the resource bundle. if (resourceBundleName != null) { try { - resourceBundle = ResourceBundle.getBundle(resourceBundleName); + // use system class loader to ensure the ResourceBundle + // instance is a different instance than null loader uses + final ResourceBundle bundle = + ResourceBundle.getBundle(resourceBundleName, + Locale.getDefault(), + ClassLoader.getSystemClassLoader()); + resourceBundle = bundle; } catch (MissingResourceException ex) { // This is not a good place to throw an exception, // so we simply leave the resourceBundle null. diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.logging/share/classes/java/util/logging/Logger.java --- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1937,6 +1937,9 @@ } setCallersClassLoaderRef(callersClass); + if (isSystemLogger && getCallersClassLoader() != null) { + checkPermission(); + } if (findResourceBundle(name, true) == null) { // We've failed to find an expected ResourceBundle. // unset the caller's ClassLoader since we were unable to find the @@ -2170,11 +2173,13 @@ return trb; } final String rbName = isSystemLogger - ? trb.resourceBundleName + // ancestor of a system logger is expected to be a system logger. + // ignore resource bundle name if it's not. + ? (target.isSystemLogger ? trb.resourceBundleName : null) : target.getResourceBundleName(); if (rbName != null) { return LoggerBundle.get(rbName, - findResourceBundle(rbName, true)); + findResourceBundle(rbName, true)); } target = isSystemLogger ? target.parent : target.getParent(); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.naming/share/classes/javax/naming/spi/NamingManager.java --- a/jdk/src/java.naming/share/classes/javax/naming/spi/NamingManager.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.naming/share/classes/javax/naming/spi/NamingManager.java Wed Jul 05 20:04:43 2017 +0200 @@ -25,9 +25,7 @@ package javax.naming.spi; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.StringTokenizer; +import java.util.*; import java.net.MalformedURLException; import javax.naming.*; @@ -625,15 +623,28 @@ /** * Creates an initial context using the specified environment * properties. - *

- * If an InitialContextFactoryBuilder has been installed, - * it is used to create the factory for creating the initial context. - * Otherwise, the class specified in the - * Context.INITIAL_CONTEXT_FACTORY environment property is used. - * Note that an initial context factory (an object that implements the - * InitialContextFactory interface) must be public and must have a - * public constructor that accepts no arguments. - * + *

+ * This is done as follows: + *

    + *
  • If an InitialContextFactoryBuilder has been installed, + * it is used to create the factory for creating the initial + * context
  • + *
  • Otherwise, the class specified in the + * Context.INITIAL_CONTEXT_FACTORY environment property + * is used + *
      + *
    • First, the {@linkplain java.util.ServiceLoader ServiceLoader} + * mechanism tries to locate an {@code InitialContextFactory} + * provider using the current thread's context class loader
    • + *
    • Failing that, this implementation tries to locate a suitable + * {@code InitialContextFactory} using a built-in mechanism + *
      + * (Note that an initial context factory (an object that implements + * the InitialContextFactory interface) must be public and must have + * a public constructor that accepts no arguments)
    • + *
    + *
  • + *
* @param env The possibly null environment properties used when * creating the context. * @return A non-null initial context. @@ -649,11 +660,11 @@ */ public static Context getInitialContext(Hashtable env) throws NamingException { - InitialContextFactory factory; + InitialContextFactory factory = null; InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder(); if (builder == null) { - // No factory installed, use property + // No builder installed, use property // Get initial context factory class name String className = env != null ? @@ -666,16 +677,39 @@ throw ne; } + ServiceLoader loader = + ServiceLoader.load(InitialContextFactory.class); + + Iterator iterator = loader.iterator(); try { - factory = (InitialContextFactory) - helper.loadClass(className).newInstance(); - } catch(Exception e) { + while (iterator.hasNext()) { + InitialContextFactory f = iterator.next(); + if (f.getClass().getName().equals(className)) { + factory = f; + break; + } + } + } catch (ServiceConfigurationError e) { NoInitialContextException ne = - new NoInitialContextException( - "Cannot instantiate class: " + className); + new NoInitialContextException( + "Cannot load initial context factory " + + "'" + className + "'"); ne.setRootCause(e); throw ne; } + + if (factory == null) { + try { + factory = (InitialContextFactory) + helper.loadClass(className).newInstance(); + } catch (Exception e) { + NoInitialContextException ne = + new NoInitialContextException( + "Cannot instantiate class: " + className); + ne.setRootCause(e); + throw ne; + } + } } else { factory = builder.createInitialContextFactory(env); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java Wed Jul 05 20:04:43 2017 +0200 @@ -244,8 +244,11 @@ * establishment. */ public final void requestCredDeleg(boolean value) throws GSSException { - if (state == STATE_NEW && isInitiator()) - credDelegState = value; + if (state == STATE_NEW && isInitiator()) { + if (myCred == null || !(myCred instanceof Krb5ProxyCredential)) { + credDelegState = value; + } + } } /** diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java Wed Jul 05 20:04:43 2017 +0200 @@ -25,6 +25,8 @@ import java.io.InputStream; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; @@ -35,6 +37,7 @@ import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm; import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; +import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver; import com.sun.org.apache.xml.internal.security.transforms.Transform; import com.sun.org.apache.xml.internal.security.utils.ElementProxy; @@ -118,43 +121,50 @@ log.log(java.util.logging.Level.FINE, "Registering default algorithms"); } try { - // - // Bind the default prefixes - // - ElementProxy.registerDefaultPrefixes(); + AccessController.doPrivileged(new PrivilegedExceptionAction(){ + @Override public Void run() throws XMLSecurityException { + // + // Bind the default prefixes + // + ElementProxy.registerDefaultPrefixes(); - // - // Set the default Transforms - // - Transform.registerDefaultAlgorithms(); + // + // Set the default Transforms + // + Transform.registerDefaultAlgorithms(); - // - // Set the default signature algorithms - // - SignatureAlgorithm.registerDefaultAlgorithms(); + // + // Set the default signature algorithms + // + SignatureAlgorithm.registerDefaultAlgorithms(); + + // + // Set the default JCE algorithms + // + JCEMapper.registerDefaultAlgorithms(); - // - // Set the default JCE algorithms - // - JCEMapper.registerDefaultAlgorithms(); + // + // Set the default c14n algorithms + // + Canonicalizer.registerDefaultAlgorithms(); - // - // Set the default c14n algorithms - // - Canonicalizer.registerDefaultAlgorithms(); + // + // Register the default resolvers + // + ResourceResolver.registerDefaultResolvers(); - // - // Register the default resolvers - // - ResourceResolver.registerDefaultResolvers(); + // + // Register the default key resolvers + // + KeyResolver.registerDefaultResolvers(); - // - // Register the default key resolvers - // - KeyResolver.registerDefaultResolvers(); - } catch (Exception ex) { - log.log(java.util.logging.Level.SEVERE, ex.getMessage(), ex); - ex.printStackTrace(); + return null; + } + }); + } catch (PrivilegedActionException ex) { + XMLSecurityException xse = (XMLSecurityException)ex.getException(); + log.log(java.util.logging.Level.SEVERE, xse.getMessage(), xse); + xse.printStackTrace(); } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java Wed Jul 05 20:04:43 2017 +0200 @@ -27,6 +27,7 @@ import com.sun.org.apache.xml.internal.security.encryption.XMLCipher; import com.sun.org.apache.xml.internal.security.signature.XMLSignature; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Element; @@ -49,8 +50,11 @@ * * @param id * @param algorithm + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the JCE algorithm */ public static void register(String id, Algorithm algorithm) { + JavaUtils.checkRegisterPermission(); algorithmsMap.put(id, algorithm); } @@ -296,8 +300,11 @@ /** * Sets the default Provider for obtaining the security algorithms * @param provider the default providerId. + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the JCE provider */ public static void setProviderId(String provider) { + JavaUtils.checkRegisterPermission(); providerName = provider; } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java Wed Jul 05 20:04:43 2017 +0200 @@ -37,6 +37,7 @@ import com.sun.org.apache.xml.internal.security.signature.XMLSignature; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; import com.sun.org.apache.xml.internal.security.utils.Constants; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -314,18 +315,21 @@ } /** - * Registers implementing class of the Transform algorithm with algorithmURI + * Registers implementing class of the SignatureAlgorithm with algorithmURI * - * @param algorithmURI algorithmURI URI representation of Transform algorithm. + * @param algorithmURI algorithmURI URI representation of SignatureAlgorithm. * @param implementingClass implementingClass the implementing class of * {@link SignatureAlgorithmSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered * @throws XMLSignatureException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the signature algorithm */ @SuppressWarnings("unchecked") public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException, XMLSignatureException { + JavaUtils.checkRegisterPermission(); if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass); } @@ -352,15 +356,18 @@ /** * Registers implementing class of the Transform algorithm with algorithmURI * - * @param algorithmURI algorithmURI URI representation of Transform algorithm. + * @param algorithmURI algorithmURI URI representation of SignatureAlgorithm. * @param implementingClass implementingClass the implementing class of * {@link SignatureAlgorithmSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered * @throws XMLSignatureException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the signature algorithm */ public static void register(String algorithmURI, Class implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException, XMLSignatureException { + JavaUtils.checkRegisterPermission(); if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java Wed Jul 05 20:04:43 2017 +0200 @@ -41,6 +41,7 @@ import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments; import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerPhysical; import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -142,10 +143,13 @@ * @param algorithmURI * @param implementingClass * @throws AlgorithmAlreadyRegisteredException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the canonicalizer */ @SuppressWarnings("unchecked") public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException { + JavaUtils.checkRegisterPermission(); // check whether URI is already registered Class registeredClass = canonicalizerHash.get(algorithmURI); @@ -166,9 +170,12 @@ * @param algorithmURI * @param implementingClass * @throws AlgorithmAlreadyRegisteredException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the canonicalizer */ - public static void register(String algorithmURI, Class implementingClass) + public static void register(String algorithmURI, Class implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException { + JavaUtils.checkRegisterPermission(); // check whether URI is already registered Class registeredClass = canonicalizerHash.get(algorithmURI); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java Wed Jul 05 20:04:43 2017 +0200 @@ -42,6 +42,7 @@ import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SKIResolver; import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SubjectNameResolver; import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -175,9 +176,12 @@ * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void register(String className, boolean globalResolver) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + JavaUtils.checkRegisterPermission(); KeyResolverSpi keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance(); keyResolverSpi.setGlobalResolver(globalResolver); @@ -195,8 +199,11 @@ * * @param className * @param globalResolver Whether the KeyResolverSpi is a global resolver or not + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void registerAtStart(String className, boolean globalResolver) { + JavaUtils.checkRegisterPermission(); KeyResolverSpi keyResolverSpi = null; Exception ex = null; try { @@ -228,11 +235,14 @@ * * @param keyResolverSpi a KeyResolverSpi instance to register * @param start whether to register the KeyResolverSpi at the start of the list or not + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void register( KeyResolverSpi keyResolverSpi, boolean start ) { + JavaUtils.checkRegisterPermission(); KeyResolver resolver = new KeyResolver(keyResolverSpi); if (start) { resolverVector.add(0, resolver); @@ -254,9 +264,12 @@ * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void registerClassNames(List classNames) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + JavaUtils.checkRegisterPermission(); List keyResolverList = new ArrayList(classNames.size()); for (String className : classNames) { KeyResolverSpi keyResolverSpi = diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java Wed Jul 05 20:04:43 2017 +0200 @@ -46,6 +46,7 @@ import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.HelperNodeList; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Document; @@ -181,11 +182,14 @@ * class of {@link TransformSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI * is already registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the transform */ @SuppressWarnings("unchecked") public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException, InvalidTransformException { + JavaUtils.checkRegisterPermission(); // are we already registered? Class transformSpi = transformSpiHash.get(algorithmURI); if (transformSpi != null) { @@ -206,9 +210,12 @@ * class of {@link TransformSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI * is already registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the transform */ public static void register(String algorithmURI, Class implementingClass) throws AlgorithmAlreadyRegisteredException { + JavaUtils.checkRegisterPermission(); // are we already registered? Class transformSpi = transformSpiHash.get(algorithmURI); if (transformSpi != null) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java Wed Jul 05 20:04:43 2017 +0200 @@ -468,9 +468,12 @@ * @param namespace * @param prefix * @throws XMLSecurityException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the default prefix */ public static void setDefaultPrefix(String namespace, String prefix) throws XMLSecurityException { + JavaUtils.checkRegisterPermission(); if (prefixMappings.containsValue(prefix)) { String storedPrefix = prefixMappings.get(namespace); if (!storedPrefix.equals(prefix)) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java Wed Jul 05 20:04:43 2017 +0200 @@ -28,6 +28,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.security.SecurityPermission; /** * A collection of different, general-purpose methods for JAVA-specific things @@ -39,6 +40,10 @@ private static java.util.logging.Logger log = java.util.logging.Logger.getLogger(JavaUtils.class.getName()); + private static final SecurityPermission REGISTER_PERMISSION = + new SecurityPermission( + "com.sun.org.apache.xml.internal.security.register"); + private JavaUtils() { // we don't allow instantiation } @@ -147,6 +152,23 @@ } /** + * Throws a {@code SecurityException} if a security manager is installed + * and the caller is not allowed to register an implementation of an + * algorithm, transform, or other security sensitive XML Signature function. + * + * @throws SecurityException if a security manager is installed and the + * caller has not been granted the + * {@literal "com.sun.org.apache.xml.internal.security.register"} + * {@code SecurityPermission} + */ + public static void checkRegisterPermission() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(REGISTER_PERMISSION); + } + } + + /** * Converts an ASN.1 DSA value to a XML Signature DSA Value. * * The JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java Wed Jul 05 20:04:43 2017 +0200 @@ -80,32 +80,44 @@ /** * Set the prefix for the digital signature namespace * @param prefix the new prefix for the digital signature namespace + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setDsPrefix(String prefix) { + JavaUtils.checkRegisterPermission(); dsPrefix = prefix; } /** * Set the prefix for the digital signature 1.1 namespace * @param prefix the new prefix for the digital signature 1.1 namespace + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setDs11Prefix(String prefix) { + JavaUtils.checkRegisterPermission(); ds11Prefix = prefix; } /** * Set the prefix for the encryption namespace * @param prefix the new prefix for the encryption namespace + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setXencPrefix(String prefix) { + JavaUtils.checkRegisterPermission(); xencPrefix = prefix; } /** * Set the prefix for the encryption namespace 1.1 * @param prefix the new prefix for the encryption namespace 1.1 + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setXenc11Prefix(String prefix) { + JavaUtils.checkRegisterPermission(); xenc11Prefix = prefix; } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java Wed Jul 05 20:04:43 2017 +0200 @@ -27,6 +27,7 @@ import java.util.Map; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP; import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment; import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverLocalFilesystem; @@ -199,9 +200,12 @@ * the class cannot be registered. * * @param className the name of the ResourceResolverSpi class to be registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ @SuppressWarnings("unchecked") public static void register(String className) { + JavaUtils.checkRegisterPermission(); try { Class resourceResolverClass = (Class) Class.forName(className); @@ -216,9 +220,12 @@ * list. This method logs a warning if the class cannot be registered. * * @param className the name of the ResourceResolverSpi class to be registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ @SuppressWarnings("unchecked") public static void registerAtStart(String className) { + JavaUtils.checkRegisterPermission(); try { Class resourceResolverClass = (Class) Class.forName(className); @@ -233,8 +240,11 @@ * cannot be registered. * @param className * @param start + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ public static void register(Class className, boolean start) { + JavaUtils.checkRegisterPermission(); try { ResourceResolverSpi resourceResolverSpi = className.newInstance(); register(resourceResolverSpi, start); @@ -250,8 +260,11 @@ * cannot be registered. * @param resourceResolverSpi * @param start + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ public static void register(ResourceResolverSpi resourceResolverSpi, boolean start) { + JavaUtils.checkRegisterPermission(); synchronized(resolverList) { if (start) { resolverList.add(0, new ResourceResolver(resourceResolverSpi)); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/com/sun/tools/attach/StartManagementAgent.java --- a/jdk/test/com/sun/tools/attach/StartManagementAgent.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/com/sun/tools/attach/StartManagementAgent.java Wed Jul 05 20:04:43 2017 +0200 @@ -53,7 +53,9 @@ public static void main(String[] args) throws Throwable { ProcessThread processThread = null; try { + System.out.println("Starting test application"); processThread = RunnerUtil.startApplication(); + System.out.println("Application started"); runTests(processThread.getPid()); } catch (Throwable t) { System.out.println("StartManagementAgent got unexpected exception: " + t); @@ -70,6 +72,7 @@ // Try calling with null argument boolean exception = false; try { + System.out.println("Starting management agent with null"); vm.startManagementAgent(null); } catch (NullPointerException e) { exception = true; @@ -86,6 +89,7 @@ } p.put("com.sun.management.config.file", f.getAbsolutePath()); try { + System.out.println("Starting management agent with bogus port"); vm.startManagementAgent(p); } catch(AttachOperationFailedException ex) { // We expect parsing of "apa" above to fail, but if the file path @@ -93,6 +97,9 @@ if (!ex.getMessage().contains("Invalid com.sun.management.jmxremote.port number")) { throw ex; } + ex.printStackTrace(System.err); + } catch (Throwable t) { + t.printStackTrace(System.err); } } @@ -134,14 +141,19 @@ } public static void testLocalAgent(VirtualMachine vm) throws Exception { + System.out.println("Getting VM properties"); Properties agentProps = vm.getAgentProperties(); String address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP); if (address != null) { throw new Exception("Local management agent already started"); } + System.out.println("Starting local agent"); + String result = vm.startLocalManagementAgent(); + System.out.println("Agent started"); + // try to parse the return value as a JMXServiceURL new JMXServiceURL(result); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java --- a/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,7 +26,7 @@ @bug 8048887 @summary Tests SortingFTP for an exception caused by the tim-sort algo. @author anton.tarasov: area=awt.focus - @run main JDK8040632 + @run main JDK8048887 */ import javax.swing.JFrame; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Portions Copyright (c) 2014 IBM Corporation + */ + +public class TestDetectHeadless { + public static void main(String[] args) throws Exception { + Class.forName("javax.swing.plaf.basic.BasicInternalFrameTitlePane"); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.sh Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# Portions Copyright (c) 2014 IBM Corporation +# + +# @test +# @bug 8058930 +# @summary java.awt.GraphicsEnvironment.getHeadlessProperty() does not work for AIX +# +# @build TestDetectHeadless +# @run shell TestDetectHeadless.sh + +OS=`uname -s` +case "$OS" in + Windows* | CYGWIN* ) + echo "Passed"; exit 0 ;; + * ) unset DISPLAY ;; +esac + +${TESTJAVA}/bin/java ${TESTVMOPTS} \ + -cp ${TESTCLASSES} TestDetectHeadless + +exit $? diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java --- a/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java Wed Jul 05 20:04:43 2017 +0200 @@ -22,6 +22,8 @@ */ import com.oracle.testlibrary.jsr292.Helper; +import com.sun.management.HotSpotDiagnosticMXBean; +import java.lang.management.ManagementFactory; import java.lang.reflect.Method; import java.util.Collection; import java.util.function.Function; @@ -37,6 +39,8 @@ private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle"; private final static String INTERNAL_FORM_METHOD_NAME = "internalForm"; + private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO + = 45 / (128.0 * 1024 * 1024); /** * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is @@ -87,7 +91,35 @@ boolean passed = true; int testCounter = 0; int failCounter = 0; - long iterations = Math.max(1, Helper.TEST_LIMIT / testMethods.size()); + long testCaseNum = testMethods.size(); + long iterations = Math.max(1, Helper.TEST_LIMIT / testCaseNum); + System.out.printf("Number of iterations according to -DtestLimit is %d (%d cases)%n", + iterations, iterations * testCaseNum); + HotSpotDiagnosticMXBean hsDiagBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + long codeCacheSize = Long.parseLong( + hsDiagBean.getVMOption("ReservedCodeCacheSize").getValue()); + System.out.printf("Code cache size is %d bytes%n", codeCacheSize); + long iterationsByCodeCacheSize = (long) (codeCacheSize + * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO); + long nonProfiledCodeCacheSize = Long.parseLong( + hsDiagBean.getVMOption("NonProfiledCodeHeapSize").getValue()); + System.out.printf("Non-profiled code cache size is %d bytes%n", nonProfiledCodeCacheSize); + long iterationsByNonProfiledCodeCacheSize = (long) (nonProfiledCodeCacheSize + * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO); + System.out.printf("Number of iterations limited by code cache size is %d (%d cases)%n", + iterationsByCodeCacheSize, iterationsByCodeCacheSize * testCaseNum); + System.out.printf("Number of iterations limited by non-profiled code cache size is %d (%d cases)%n", + iterationsByNonProfiledCodeCacheSize, iterationsByNonProfiledCodeCacheSize * testCaseNum); + iterations = Math.min(iterationsByCodeCacheSize, + Math.min(iterations, iterationsByNonProfiledCodeCacheSize)); + if (iterations == 0) { + System.out.println("Warning: code cache size is too small to provide at" + + " least one iteration! Test will try to do one iteration."); + iterations = 1; + } + System.out.printf("Number of iterations is set to %d (%d cases)%n", + iterations, iterations * testCaseNum); + System.out.flush(); for (long i = 0; i < iterations; i++) { System.err.println(String.format("Iteration %d:", i)); for (TestMethods testMethod : testMethods) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/net/SetFactoryPermission/SetFactoryPermission.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/SetFactoryPermission/SetFactoryPermission.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + * @test + * @bug 8048052 + * @summary Test a series of methods which requires "setFactory" runtime permission + * @run main SetFactoryPermission success + * @run main/othervm/policy=policy.fail SetFactoryPermission fail + * @run main/othervm/policy=policy.success SetFactoryPermission success + */ +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URL; +import java.net.URLConnection; +import java.rmi.server.RMISocketFactory; +import java.security.AccessControlException; + +public class SetFactoryPermission { + static boolean success = false; + + interface Runner { + public void run() throws Exception; + } + + public static void main (String[] args) throws Exception { + if (args.length > 0) { + success = System.getSecurityManager() == null || args[0].equals("success"); + } + + doTest(()->{ + System.out.println("Verify URLConnection.setContentHandlerFactor()"); + URLConnection.setContentHandlerFactory(null); + }); + doTest(()->{ + System.out.println("Verify URL.setURLStreamHandlerFactory()"); + URL.setURLStreamHandlerFactory(null); + }); + doTest(()->{ + System.out.println("Verify ServerSocket.setSocketFactory()"); + ServerSocket.setSocketFactory(null); + }); + doTest(()->{ + System.out.println("Verify Socket.setSocketImplFactory()"); + Socket.setSocketImplFactory(null); + }); + doTest(()->{ + System.out.println("Verify RMISocketFactory.setSocketFactory()"); + RMISocketFactory.setSocketFactory(null); + }); + } + + static void doTest(Runner func) throws Exception { + try { + func.run(); + if (!success) { + throw new RuntimeException("AccessControlException is not thrown. Test failed"); + } + } catch (SecurityException e) { + if (success) { + e.printStackTrace(); + throw new RuntimeException("AccessControlException is thrown unexpectedly. Test failed"); + } + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/net/SetFactoryPermission/policy.fail --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/SetFactoryPermission/policy.fail Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,3 @@ +grant { + +}; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/net/SetFactoryPermission/policy.success --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/SetFactoryPermission/policy.success Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,4 @@ +grant { + permission java.lang.RuntimePermission "setFactory"; +}; + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/net/SocketPermission/SocketPermissionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/SocketPermission/SocketPermissionTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8047031 + * @summary SocketPermission tests for legacy socket types + * @library ../../../lib/testlibrary + * @run testng/othervm/policy=policy SocketPermissionTest + */ +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketPermission; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.Permission; +import java.security.Permissions; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.function.Function; +import java.util.function.IntConsumer; +import static jdk.testlibrary.Utils.getFreePort; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class SocketPermissionTest { + private int freePort = -1; + + //positive tests + @Test(dataProvider = "positiveProvider") + public void testPositive(Function genAcc, IntConsumer func) { + String addr = "localhost:" + freePort; + AccessControlContext acc = genAcc.apply(addr); + AccessController.doPrivileged((PrivilegedAction) () -> { + func.accept(freePort); + return null; + }, acc); + } + + //negative tests + @Test(dataProvider = "negativeProvider", expectedExceptions = SecurityException.class) + public void testNegative(AccessControlContext acc, IntConsumer func) { + AccessController.doPrivileged((PrivilegedAction) () -> { + func.accept(freePort); + return null; + }, acc); + } + + @BeforeMethod + public void setFreePort() throws Exception { + freePort = getFreePort(); + } + + @DataProvider + public Object[][] positiveProvider() { + //test for SocketPermission "host:port","connect,resolve"; + Function generateAcc1 = (addr) -> getAccessControlContext( + new SocketPermission(addr, "listen, connect,resolve")); + IntConsumer func1 = (i) -> connectSocketTest(i); + IntConsumer func2 = (i) -> connectDatagramSocketTest(i); + + //test for SocketPermission "localhost:1024-","accept"; + Function generateAcc2 = (addr) -> getAccessControlContext( + new SocketPermission(addr, "listen,connect,resolve"), + new SocketPermission("localhost:1024-", "accept")); + IntConsumer func3 = (i) -> acceptServerSocketTest(i); + + //test for SocketPermission "229.227.226.221", "connect,accept" + Function generateAcc3 = (addr) -> getAccessControlContext( + new SocketPermission(addr, "listen,resolve"), + new SocketPermission("229.227.226.221", "connect,accept")); + IntConsumer func4 = (i) -> sendDatagramPacketTest(i); + IntConsumer func5 = (i) -> joinGroupMulticastTest(i); + + //test for SocketPermission "host:port", "listen" + Function generateAcc4 = (addr) -> getAccessControlContext( + new SocketPermission(addr, "listen")); + IntConsumer func6 = (i) -> listenDatagramSocketTest(i); + IntConsumer func7 = (i) -> listenMulticastSocketTest(i); + IntConsumer func8 = (i) -> listenServerSocketTest(i); + + return new Object[][]{ + {generateAcc1, func1}, + {generateAcc1, func2}, + {generateAcc2, func3}, + {generateAcc3, func4}, + {generateAcc3, func5}, + {generateAcc4, func6}, + {generateAcc4, func7}, + {generateAcc4, func8} + }; + } + + @DataProvider + public Object[][] negativeProvider() { + IntConsumer[] funcs = {i -> connectSocketTest(i), + i -> connectDatagramSocketTest(i), i -> acceptServerSocketTest(i), + i -> sendDatagramPacketTest(i), i -> joinGroupMulticastTest(i), + i -> listenDatagramSocketTest(i), i -> listenMulticastSocketTest(i), + i -> listenServerSocketTest(i)}; + return Arrays.stream(funcs).map(f -> { + //Construct an AccessControlContext without SocketPermission + AccessControlContext acc = getAccessControlContext( + new java.io.FilePermission("<>", "read,write,execute,delete"), + new java.net.NetPermission("*"), + new java.util.PropertyPermission("*", "read,write"), + new java.lang.reflect.ReflectPermission("*"), + new java.lang.RuntimePermission("*"), + new java.security.SecurityPermission("*"), + new java.io.SerializablePermission("*")); + return new Object[]{acc, f}; + }).toArray(Object[][]::new); + } + + public void connectSocketTest(int port) { + try (ServerSocket server = new ServerSocket(port); + Socket client = new Socket(InetAddress.getLocalHost(), port);) { + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void connectDatagramSocketTest(int port) { + String msg = "Hello"; + try { + InetAddress me = InetAddress.getLocalHost(); + try (DatagramSocket ds = new DatagramSocket(port, me)) { + DatagramPacket dp = new DatagramPacket(msg.getBytes(), + msg.length(), me, port); + ds.send(dp); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void acceptServerSocketTest(int port) { + try { + InetAddress me = InetAddress.getLocalHost(); + try (ServerSocket server = new ServerSocket(port)) { + Socket client = new Socket(me, port); + server.accept(); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public static void sendDatagramPacketTest(int port) { + String msg = "Hello"; + try { + InetAddress group = InetAddress.getByName("229.227.226.221"); + try (DatagramSocket s = new DatagramSocket(port)) { + DatagramPacket hi = new DatagramPacket(msg.getBytes(), + msg.length(), group, port); + s.send(hi); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void joinGroupMulticastTest(int port) { + try { + InetAddress group = InetAddress.getByName("229.227.226.221"); + try (MulticastSocket s = new MulticastSocket(port)) { + s.joinGroup(group); + s.leaveGroup(group); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void listenDatagramSocketTest(int port) { + try (DatagramSocket ds = new DatagramSocket(port)) { + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void listenMulticastSocketTest(int port) { + try (MulticastSocket ms = new MulticastSocket(port)) { + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void listenServerSocketTest(int port) { + try (ServerSocket ms = new ServerSocket(port)) { + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + private static AccessControlContext getAccessControlContext(Permission... ps) { + Permissions perms = new Permissions(); + for (Permission p : ps) { + perms.add(p); + } + /* + *Create an AccessControlContext that consist a single protection domain + * with only the permissions calculated above + */ + ProtectionDomain pd = new ProtectionDomain(null, perms); + return new AccessControlContext(new ProtectionDomain[]{pd}); + } + +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/net/SocketPermission/policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/SocketPermission/policy Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,3 @@ +grant { + permission java.security.AllPermission; +}; \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/DetectInvalidEncoding.java --- a/jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/DetectInvalidEncoding.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/DetectInvalidEncoding.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,27 +23,548 @@ /** * @test - * @bug 4776466 + * @bug 4776466 8032573 * @summary check that CertificateFactory rejects invalid encoded X.509 certs */ import java.io.*; +import java.util.Collection; +import java.util.List; +import java.util.LinkedList; +import javax.security.auth.x500.X500Principal; +import java.security.GeneralSecurityException; import java.security.cert.*; public class DetectInvalidEncoding { + // Originally found in the test file: + // java/security/cert/CertificateFactory/invalidEncodedCerts/invalidcert.pem + // The first character of the PEM encoding has been changed from "M" to + // "X" to force a failure during decoding. + private static final String INVALID_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "XIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx\n" + + "EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFTAT\n" + + "BgNVBAoTDEJFQSBXZWJMb2dpYzERMA8GA1UECxMIU2VjdXJpdHkxIzAhBgNVBAMT\n" + + "GkRlbW8gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9zdXBw\n" + + "b3J0QGJlYS5jb20wHhcNMDAwNTMwMjEzODAxWhcNMDQwNTEzMjEzODAxWjCBjDEL\n" + + "MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\n" + + "cmFuY2lzY28xFTATBgNVBAoTDEJFQSBXZWJMb2dpYzEZMBcGA1UEAxMQd2VibG9n\n" + + "aWMuYmVhLmNvbTEeMBwGCSqGSIb3DQEJARYPc3VwcG9ydEBiZWEuY29tMFwwDQYJ\n" + + "KoZIhvcNAQEBBQADSwAwSAJBALdsXEHqKHgs6zj0hU5sXMAUHzoT8kgWXmNkKHXH\n" + + "79qbPh6EfdlriW9G/AbRF/pKrCQu7hhllAxREbqTuSlf2EMCAwEAATANBgkqhkiG\n" + + "9w0BAQQFAANBACgmqflL5m5LNeJGpWx9aIoABCiuDcpw1fFyegsqGX7CBhffcruS\n" + + "1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=\n" + + "-----END CERTIFICATE-----"; + + // Created with keytool: + // keytool -genkeypair -keyalg rsa -keysize 2048 -keystore + // -alias root -sigalg SHA256withRSA -dname "CN=Root, O=SomeCompany" + // -validity 730 -ext bc:critical=ca:true + // -ext ku:critical=keyCertSign,cRLSign + private static final String SINGLE_ROOT_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDCjCCAfKgAwIBAgIEDUiw+DANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtT\n" + + "b21lQ29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMTI5MjZaFw0xNjA4\n" + + "MjcyMTI5MjZaMCUxFDASBgNVBAoTC1NvbWVDb21wYW55MQ0wCwYDVQQDEwRSb290\n" + + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0VFecSNdH6CJhPOSG127\n" + + "tuvld4y7GGJ0kQf3Q0b8qgprsXAmn0/bQR+YX7PfS408cFW+q2SWXeY2kC/3chvi\n" + + "2syMsGdUJrDzuMbYsbvKPKyuJ2GJskX3mSbLMJj5Tzhg4qmwbzDTFIJ51yGa1Wmh\n" + + "i2+4PhltqT0TohvSVJlBrOWNhmvwv5UWsF4e2i04rebDZQoWkmD3MpImZXF/HYre\n" + + "9P8NP97vN0xZmh5PySHy2ILXN3ZhTn3tq0YxNSQTaMUfhgoyzWFvZKAnm/tZIh/1\n" + + "oswwEQPIZJ25AUTm9r3YPQXl1hsNdLU0asEVYRsgzGSTX5gCuUY+KzhStzisOcUY\n" + + "uQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" + + "HQ4EFgQUz1FBNixG/KCgcn6FOWzxP1hujG0wDQYJKoZIhvcNAQELBQADggEBAL60\n" + + "ZaNc6eIMbKntGVE/pdxxyKwPdDyAAeEevX23KRWoLbQjHXo5jrfDPhI5k45ztlyU\n" + + "+tIQbc81LlCl88I4dIx0fvEbxjNaAYhFNXwwSQBs2CuEAdRK8hodXbRcEeI+G10F\n" + + "ARIVs2C7JNm/RhxskCWgj6tFIOGaTZ9gHyvlQUEM18sr5fXZlXTqspZCmz3t5XPi\n" + + "5/wYLv6vk7k3G8WzMHbBE0bYI+61cCc8rbMHldtymbwSwiqfKC9y7oPEfRCbzVUe\n" + + "fgrKcOyVWDuw0y0hhsQL/oONjPp4uK/bl9B7T84t4+ihxdocWKx6eyhFvOvZH9t2\n" + + "kUylb9yBUYStwGExMHg=\n" + + "-----END CERTIFICATE-----"; + + // Created with keytool: + // keytool -genkeypair -keyalg rsa -keysize 2048 -keystore + // -alias root -sigalg SHA256withRSA + // -dname "CN=Intermed, O=SomeCompany" -validity 730 + // -ext bc:critical=ca:true -ext ku:critical=keyCertSign,cRLSign + // keytool -certreq -keystore -sigalg SHA256withRSA + // -alias intermed -dname "CN=Intermed, O=SomeCompany" + // keytool -gencert -keystore -alias intermed + // -sigalg SHA256withRSA -validity 730 + // -ext bc:critical=ca:true -ext ku:critical=keyCertSign,cRLSign + private static final String INTERMED_CA_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDLzCCAhegAwIBAgIEIIgOyDANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtT\n" + + "b21lQ29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMjUyNDJaFw0xNjA4\n" + + "MDcyMjUyNDJaMCkxFDASBgNVBAoTC1NvbWVDb21wYW55MREwDwYDVQQDEwhJbnRl\n" + + "cm1lZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJEecvTWla8kdWx+\n" + + "HHu5ryfBpJ95I7V4MEajnmzJVZcwvKhDjlDgABDMuVwFEUUSyeOdbWJF3DLKnyMD\n" + + "KTx6/58kuVak3NX2TJ8cmmIlKf1upFbdrEtjYViSnNrApprfO8B3ORdBbO6QDYza\n" + + "IkAWdI5GllFnVkb4yhMUBg3zfhglF+bl3D3lVRlp9bCrUZoNRs+mZjhVbcMn22ej\n" + + "TfG5Y3VpNM4SN8dFIxPQLLk/aao+cmWEQdbQ0R6ydemRukqrw170olSVLeoGGala\n" + + "3D4oJckde8EgNPcghcsdQ6tpGhkpFhmoyzEsuToR7Gq9UT5V2kkqJneiKXqQg4wz\n" + + "vMAlUGECAwEAAaNjMGEwHwYDVR0jBBgwFoAUOw+92bevFoJz96pR1DrAkPPUKb0w\n" + + "DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLbnErBs\n" + + "q/Mhci5XElfjjLZp3GRyMA0GCSqGSIb3DQEBCwUAA4IBAQAq8y2DpkSV31IXZ1vr\n" + + "/Ye+Nj/2NvBydFeHVRGMAN1LJv6/Q42TCSXbr6cDQ4NWQUtPm90yZBYJSznkbShx\n" + + "HOJEE6R8PRJvoUtMm7fJrNtkybTt6jX4j50Lw8gdYB/rgZb4z8ZQZVEo/0zpW4HV\n" + + "Gs+q4z8TkdmLR18hl39sUEsxt99AOBk8NtKKVNfBWq9b0QDhRkXfmqhyeXdDsHOV\n" + + "8ksulsa7hseheHhdjziEOpQugh8qzSea2kFPrLB53VjWfa4qDzEPaNhahho9piCu\n" + + "82XDnOrcEk9KyHWM7sa7vtK7++W+0MXD/p9nkZ6NHrJXweLriU0DXO6ZY3mzNKJK\n" + + "435M\n" + + "-----END CERTIFICATE-----"; + + // Subordinate cert created using keytool, both certs exported to + // files individually, then use openssl to place in a PKCS#7: + // openssl crl2pkcs7 -nocrl -certfile + // -certfile -out + private static final String PKCS7_INTERMED_ROOT_CERTS = + "-----BEGIN PKCS7-----\n" + + "MIIGbgYJKoZIhvcNAQcCoIIGXzCCBlsCAQExADALBgkqhkiG9w0BBwGgggZBMIID\n" + + "LzCCAhegAwIBAgIEIIgOyDANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtTb21l\n" + + "Q29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMjUyNDJaFw0xNjA4MDcy\n" + + "MjUyNDJaMCkxFDASBgNVBAoTC1NvbWVDb21wYW55MREwDwYDVQQDEwhJbnRlcm1l\n" + + "ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJEecvTWla8kdWx+HHu5\n" + + "ryfBpJ95I7V4MEajnmzJVZcwvKhDjlDgABDMuVwFEUUSyeOdbWJF3DLKnyMDKTx6\n" + + "/58kuVak3NX2TJ8cmmIlKf1upFbdrEtjYViSnNrApprfO8B3ORdBbO6QDYzaIkAW\n" + + "dI5GllFnVkb4yhMUBg3zfhglF+bl3D3lVRlp9bCrUZoNRs+mZjhVbcMn22ejTfG5\n" + + "Y3VpNM4SN8dFIxPQLLk/aao+cmWEQdbQ0R6ydemRukqrw170olSVLeoGGala3D4o\n" + + "Jckde8EgNPcghcsdQ6tpGhkpFhmoyzEsuToR7Gq9UT5V2kkqJneiKXqQg4wzvMAl\n" + + "UGECAwEAAaNjMGEwHwYDVR0jBBgwFoAUOw+92bevFoJz96pR1DrAkPPUKb0wDwYD\n" + + "VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLbnErBsq/Mh\n" + + "ci5XElfjjLZp3GRyMA0GCSqGSIb3DQEBCwUAA4IBAQAq8y2DpkSV31IXZ1vr/Ye+\n" + + "Nj/2NvBydFeHVRGMAN1LJv6/Q42TCSXbr6cDQ4NWQUtPm90yZBYJSznkbShxHOJE\n" + + "E6R8PRJvoUtMm7fJrNtkybTt6jX4j50Lw8gdYB/rgZb4z8ZQZVEo/0zpW4HVGs+q\n" + + "4z8TkdmLR18hl39sUEsxt99AOBk8NtKKVNfBWq9b0QDhRkXfmqhyeXdDsHOV8ksu\n" + + "lsa7hseheHhdjziEOpQugh8qzSea2kFPrLB53VjWfa4qDzEPaNhahho9piCu82XD\n" + + "nOrcEk9KyHWM7sa7vtK7++W+0MXD/p9nkZ6NHrJXweLriU0DXO6ZY3mzNKJK435M\n" + + "MIIDCjCCAfKgAwIBAgIEdffjKTANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtT\n" + + "b21lQ29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMjQ2MzZaFw0xNjA4\n" + + "MjcyMjQ2MzZaMCUxFDASBgNVBAoTC1NvbWVDb21wYW55MQ0wCwYDVQQDEwRSb290\n" + + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhnXc8Avv54Gk2xjVa2yA\n" + + "lBL/Cug1nyvKl5wqmN+foT6cMOX6bneCkJOJ4lSbch3gvl4ctlX/9hm3pB/+HhSr\n" + + "em2NcLQrLEq8l9Ar4RnqfoXQR4Uy+4P6wj9OcVV7e/v/+ZPnStOoEAtb5nAwsR2b\n" + + "hOC/tIFNwflrsmsmtMSoOiNftpYLFF4eOAdpDrXYMrqNu6ZxZsOQ7WZl4SsVOx1N\n" + + "/IINXwBLyoHJDzLZ0iJEV0O6mh846s0n6QXeK1P5d0uLcoZaZ1k8Q4sRcdoLA6rS\n" + + "e1WffipBFMvIuoDIigkHZIKVYRLG828rO+PFnRah0ybybkVsN6s3oLxfhswZDvut\n" + + "OwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" + + "HQ4EFgQUOw+92bevFoJz96pR1DrAkPPUKb0wDQYJKoZIhvcNAQELBQADggEBACBN\n" + + "wEaV70FKKBINHtNwesd7TB6fgSaVgDZOO08aseHbXnm7AUhtDV3P5rQR2AsKtbg4\n" + + "COhlKw2/Ki18D4DfdCccFKFTRZBjqj2PxNmn6C68l1/bT4PuUXuM7rW++53RcOA7\n" + + "TbgLuzA25kSz7XinRvR8L4VwHtppu5tSYEthMIMgLZLGGV9r7kBfpY8lXdxQM8vb\n" + + "xZUIysasvVtVUFPOTV6g2dfn8QCoqLOmxyzTLdXe4M6acP6f7lmhgr3LMqDtB6K9\n" + + "pN+OImr77zNdZ+jTB+5e9a8gAvc5ZfG7Nk5RfwUatYTAFZ6Uggy2cKmIRpXCia18\n" + + "If78mc7goS1+lHkGCs2hADEA\n" + + "-----END PKCS7-----"; + + // Empty PKCS#7 in DER form can be created with openssl: + // openssl crl2pkcs7 -nocrl -outform DER + private static final byte[] PKCS7_BER_EMPTY = { + 48, 39, 6, 9, 42, -122, 72, -122, + -9, 13, 1, 7, 2, -96, 26, 48, + 24, 2, 1, 1, 49, 0, 48, 11, + 6, 9, 42, -122, 72, -122, -9, 13, + 1, 7, 1, -96, 0, -95, 0, 49, + 0 + }; + + private static final String JTEST_ROOT_CRL = + "-----BEGIN X509 CRL-----\n" + + "MIICoTCBigIBATANBgkqhkiG9w0BAQsFADA1MQ4wDAYDVQQKEwVKVGVzdDELMAkG\n" + + "A1UECxMCSVQxFjAUBgNVBAMTDUpUZXN0IFJvb3QgQ0EXDTE0MDkwNDE4NDIyMVqg\n" + + "MDAuMB8GA1UdIwQYMBaAFO6bllCV6kctH77MfqAtefNeRdsmMAsGA1UdFAQEAgIA\n" + + "jjANBgkqhkiG9w0BAQsFAAOCAgEAmp8ihtiRthknDC+VzehmlQw5u8MftMZYQYk5\n" + + "EI04SwyzY9JTL8QHb4u7fXjnZAyN89aYPypI5OSyDsyyGP/JDNsBt2Um/fl0aaCl\n" + + "Z4Np6x+dB9+oIU1XY7y2+uyQUC5MHivQ5ddbGPoAvK/msbugTGAjHvZpM+l0okiV\n" + + "3SofDrii5BSosFEkXfkf2oG9ZLO3YamsFMEZaOj/eWDyGhTyJMGsq2/8NeTF21Tp\n" + + "YkeDcTHqR5KHoYXjOIaS7NjmErm+uDpKH9Lq+JUcYrbUhmjnq5z04EsPF2F2L7Vb\n" + + "THI+awQAUQit16lXGuz7fFRZi2vPyiaRP5n2QT5D+ac1dAs+oWLDJw6Tf2v9KVTe\n" + + "OmW62yd6zQqCwBg+n57UcNu3sv/Sq3t7iRuN0AmWlIhu659POPQv7Np6bEo6dIpp\n" + + "u7Ze6D2KPtM177ETHYlCx2a3g9VEZYKrVhQ2749St0Cp5szVq691jFZAWYOzcfEO\n" + + "XfK1y25pmlBjvhNIIVRlU+T5rjNb8GaleYKVYnKOcv700K32QxFzcPf7nbNKwW99\n" + + "tcaNHFNP+LW/XP8I3CJ8toXLLcOITKVwMA+0GlO5eL7eX5POc+vE9+7IzGuybmU4\n" + + "uslxoLdJ0NSZWpYmf6a6qrJ67cj5i3706H+eBsWQcShfSYreh+TyWQaGk+fkEiUV\n" + + "iy4QdJ0=\n" + + "-----END X509 CRL-----"; + + private static final String JTEST_INTERMED_CRL = + "-----BEGIN X509 CRL-----\n" + + "MIICzzCBuAIBATANBgkqhkiG9w0BAQsFADA/MQ4wDAYDVQQKEwVKVGVzdDELMAkG\n" + + "A1UECxMCSVQxIDAeBgNVBAMTF0pUZXN0IEludGVybWVkaWF0ZSBDQSAxFw0xNDA5\n" + + "MDQyMjE2NTRaMCIwIAIBBhcNMTQwOTA0MjIxNjU0WjAMMAoGA1UdFQQDCgEFoDAw\n" + + "LjAfBgNVHSMEGDAWgBSvRdjbkSMJ3A7s5H6EWghQ+lkw/zALBgNVHRQEBAICAJsw\n" + + "DQYJKoZIhvcNAQELBQADggIBALJmikMwil8oywhenoO8o9xxCOIU0xrt3KdfiSXw\n" + + "8MtQXZHT9d1C6tlLAsYkWAfmfTvM2OU6wquFCLLsFmDZszbbCqmn4JhYBSKQMqlm\n" + + "IHnsiOFPvITW2FU08fWNLM+FtQzPnTFmx/CJo+wfGpq5tZMIbsccsCJ5uvZVAWGh\n" + + "0KbPmYcJG/O384+kzr/2H2IaoZoMMABec5c5FEF/tpp8jawzY+0VFyaVrumKWdan\n" + + "+3OvRQxT1wLxfNi2vdxB2rmNPo423qanXZAoVv260um3LYlmXBNK1jwQ9lp78jkT\n" + + "B7zMVa4hOUWVxdWc/LE6fUYgPsNqZd+hWy/PolIRp5TS21B5hkc5K87LT59GkexK\n" + + "vNVKQennOLGtH+Q7htK4UeY4Gm/W7UydOQ0k7hZzyfMDkCfLfNfK0l63qKwUku36\n" + + "UdeI1LXqulPEvb/d7rRAAM9p5Sm+RsECj2bcrZBMdIGXcSo26A5tzZpTEC79i4S1\n" + + "yxYIooeBnouUkDJ9+VBsJTSKY5fpU8JSkQPRyHKt+trGAkBt2Ka5MqrHtITzQ1vP\n" + + "5q4tNr45JGEXllH83NlBpWURfsdtkDHa3lxTD/pkrywOCyzz7wQ22D8Kul7EN8nT\n" + + "7LDbN+O3G9GHICxvWlJHp6HMsqGTuH1MIUR+5uZFOJa1S0IzorUIEieLncDUPgzO\n" + + "M4JA\n" + + "-----END X509 CRL-----"; + + // PKCS#7 CRL Set containing JTEST root and intermediate CRLs + private static final String PKCS7_CRL_SET = + "-----BEGIN PKCS7-----\n" + + "MIIFpQYJKoZIhvcNAQcCoIIFljCCBZICAQExADALBgkqhkiG9w0BBwGgAKGCBXgw\n" + + "ggKhMIGKAgEBMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNVBAoTBUpUZXN0MQswCQYD\n" + + "VQQLEwJJVDEWMBQGA1UEAxMNSlRlc3QgUm9vdCBDQRcNMTQwOTA0MTg0MjIxWqAw\n" + + "MC4wHwYDVR0jBBgwFoAU7puWUJXqRy0fvsx+oC15815F2yYwCwYDVR0UBAQCAgCO\n" + + "MA0GCSqGSIb3DQEBCwUAA4ICAQCanyKG2JG2GScML5XN6GaVDDm7wx+0xlhBiTkQ\n" + + "jThLDLNj0lMvxAdvi7t9eOdkDI3z1pg/Kkjk5LIOzLIY/8kM2wG3ZSb9+XRpoKVn\n" + + "g2nrH50H36ghTVdjvLb67JBQLkweK9Dl11sY+gC8r+axu6BMYCMe9mkz6XSiSJXd\n" + + "Kh8OuKLkFKiwUSRd+R/agb1ks7dhqawUwRlo6P95YPIaFPIkwayrb/w15MXbVOli\n" + + "R4NxMepHkoehheM4hpLs2OYSub64Okof0ur4lRxittSGaOernPTgSw8XYXYvtVtM\n" + + "cj5rBABRCK3XqVca7Pt8VFmLa8/KJpE/mfZBPkP5pzV0Cz6hYsMnDpN/a/0pVN46\n" + + "ZbrbJ3rNCoLAGD6fntRw27ey/9Kre3uJG43QCZaUiG7rn0849C/s2npsSjp0imm7\n" + + "tl7oPYo+0zXvsRMdiULHZreD1URlgqtWFDbvj1K3QKnmzNWrr3WMVkBZg7Nx8Q5d\n" + + "8rXLbmmaUGO+E0ghVGVT5PmuM1vwZqV5gpVico5y/vTQrfZDEXNw9/uds0rBb321\n" + + "xo0cU0/4tb9c/wjcIny2hcstw4hMpXAwD7QaU7l4vt5fk85z68T37sjMa7JuZTi6\n" + + "yXGgt0nQ1JlaliZ/prqqsnrtyPmLfvTof54GxZBxKF9Jit6H5PJZBoaT5+QSJRWL\n" + + "LhB0nTCCAs8wgbgCAQEwDQYJKoZIhvcNAQELBQAwPzEOMAwGA1UEChMFSlRlc3Qx\n" + + "CzAJBgNVBAsTAklUMSAwHgYDVQQDExdKVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMRcN\n" + + "MTQwOTA0MjIxNjU0WjAiMCACAQYXDTE0MDkwNDIyMTY1NFowDDAKBgNVHRUEAwoB\n" + + "BaAwMC4wHwYDVR0jBBgwFoAUr0XY25EjCdwO7OR+hFoIUPpZMP8wCwYDVR0UBAQC\n" + + "AgCbMA0GCSqGSIb3DQEBCwUAA4ICAQCyZopDMIpfKMsIXp6DvKPccQjiFNMa7dyn\n" + + "X4kl8PDLUF2R0/XdQurZSwLGJFgH5n07zNjlOsKrhQiy7BZg2bM22wqpp+CYWAUi\n" + + "kDKpZiB57IjhT7yE1thVNPH1jSzPhbUMz50xZsfwiaPsHxqaubWTCG7HHLAiebr2\n" + + "VQFhodCmz5mHCRvzt/OPpM6/9h9iGqGaDDAAXnOXORRBf7aafI2sM2PtFRcmla7p\n" + + "ilnWp/tzr0UMU9cC8XzYtr3cQdq5jT6ONt6mp12QKFb9utLpty2JZlwTStY8EPZa\n" + + "e/I5Ewe8zFWuITlFlcXVnPyxOn1GID7DamXfoVsvz6JSEaeU0ttQeYZHOSvOy0+f\n" + + "RpHsSrzVSkHp5zixrR/kO4bSuFHmOBpv1u1MnTkNJO4Wc8nzA5Any3zXytJet6is\n" + + "FJLt+lHXiNS16rpTxL2/3e60QADPaeUpvkbBAo9m3K2QTHSBl3EqNugObc2aUxAu\n" + + "/YuEtcsWCKKHgZ6LlJAyfflQbCU0imOX6VPCUpED0chyrfraxgJAbdimuTKqx7SE\n" + + "80Nbz+auLTa+OSRhF5ZR/NzZQaVlEX7HbZAx2t5cUw/6ZK8sDgss8+8ENtg/Crpe\n" + + "xDfJ0+yw2zfjtxvRhyAsb1pSR6ehzLKhk7h9TCFEfubmRTiWtUtCM6K1CBIni53A\n" + + "1D4MzjOCQDEA\n" + + "-----END PKCS7-----"; + public static void main(String[] args) throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509"); - File f = new File - (System.getProperty("test.src", "."), "invalidcert.pem"); - InputStream inStream = new FileInputStream(f); - try { - X509Certificate cert = - (X509Certificate) cf.generateCertificate(inStream); - } catch (CertificateParsingException ce) { - return; + List validTests = new LinkedList<>(); + List invalidTests = new LinkedList<>(); + + // Load up positive test cases (for sanity checks) + StringBuilder sb = new StringBuilder(); + + validTests.add(new GenMultiCertTest("Single, valid certificate", + SINGLE_ROOT_CERT.getBytes(), null, + new X500Principal("CN=Root, O=SomeCompany"))); + validTests.add(new GenMultiCertTest("PEM-encoded PKCS#7 chain", + PKCS7_INTERMED_ROOT_CERTS.getBytes(), null, + new X500Principal("CN=Intermed, O=SomeCompany"), + new X500Principal("CN=Root, O=SomeCompany"))); + validTests.add(new GenMultiCertTest("Two PEM-encoded X509 certs", + (INTERMED_CA_CERT + "\n" + SINGLE_ROOT_CERT).getBytes(), + null, + new X500Principal("CN=Intermed, O=SomeCompany"), + new X500Principal("CN=Root, O=SomeCompany"))); + validTests.add(new GenMultiCertTest("Empty data", new byte[0], null)); + + sb.append("Certificate 1: CN=Root, O=SomeCompany\n"); + sb.append(SINGLE_ROOT_CERT).append("\n"); + sb.append("Certificate 2: CN=Intermed, O=SomeCompany\n"); + sb.append(INTERMED_CA_CERT).append("\n"); + sb.append("Extra trailing data\n"); + validTests.add(new GenMultiCertTest( + "Two PEM-encoded certs with leading/trailing " + + "text data around each.", sb.toString().getBytes(), null, + new X500Principal("CN=Root, O=SomeCompany"), + new X500Principal("CN=Intermed, O=SomeCompany"))); + validTests.add(new GenMultiCertTest( + "BER-encoded PKCS#7 with empty certificates segment", + PKCS7_BER_EMPTY, null)); + validTests.add(new GenMultiCRLTest( + "CRL with leading and trailing text data", + ("This is a CRL\n" + JTEST_ROOT_CRL + + "\nSee? Told you so\n\n").getBytes(), null, + new X500Principal("CN=JTest Root CA,OU=IT,O=JTest"))); + validTests.add(new GenMultiCRLTest( + "Two CRLs, one after the other with leading/trailing text", + ("This is a CRL\n" + JTEST_ROOT_CRL + + "\nAnd this is another CRL\n" + JTEST_INTERMED_CRL + + "\nAnd this is trailing text\n").getBytes(), null, + new X500Principal("CN=JTest Root CA,OU=IT,O=JTest"), + new X500Principal( + "CN=JTest Intermediate CA 1,OU=IT,O=JTest"))); + validTests.add(new GenMultiCRLTest("Two CRLs in a PKCS#7 CRL set", + PKCS7_CRL_SET.getBytes(), null, + new X500Principal("CN=JTest Root CA,OU=IT,O=JTest"), + new X500Principal("CN=JTest Intermediate CA 1,OU=IT,O=JTest"))); + + // Load up all test cases where we expect failures + invalidTests.add(new GenSingleCertTest("Invalid PEM encoding", + INVALID_CERT.getBytes(), + new CertificateParsingException())); + invalidTests.add(new GenMultiCertTest("Invalid PEM encoding", + INVALID_CERT.getBytes(), + new CertificateParsingException())); + invalidTests.add(new GenMultiCertTest( + "Two cert sequence, one valid and one invalid", + (INTERMED_CA_CERT + "\n" + INVALID_CERT).getBytes(), + new CertificateParsingException())); + invalidTests.add(new GenMultiCertTest("Non-certificate text", + "This is not a certificate".getBytes(), + new CertificateException())); + invalidTests.add(new GenMultiCertTest( + "Non-certificate text with partial PEM header (4 hyphens)", + "----This is not a valid x509 certificate".getBytes(), + new CertificateException())); + invalidTests.add(new GenMultiCertTest( + "Leading non-certificate text plus valid PEM header, " + + "but not on new line", + "This is not valid -----BEGIN CERTIFICATE-----".getBytes(), + new CertificateException())); + byte[] emptyCString = {0}; + invalidTests.add(new GenMultiCertTest("Empty C-style string", + emptyCString, new CertificateException())); + invalidTests.add(new GenMultiCRLTest("Non-CRL text", + "This is not a CRL".getBytes(), new CRLException())); + invalidTests.add(new GenMultiCRLTest("Valid headers, but not a CRL", + INTERMED_CA_CERT.getBytes(), new CRLException())); + + System.out.println("===== Valid Tests ====="); + for (DecodeTest dt : validTests) { + dt.passTest(); + } + System.out.print("\n"); + + System.out.println("===== Invalid Tests ====="); + for (DecodeTest dt : invalidTests) { + dt.failTest(); + } + } + + public static abstract class DecodeTest { + protected String testName; + protected byte[] testData; + protected Throwable expectedException; + protected X500Principal[] principals; + protected CertificateFactory cf; + + /** + * Construct a DecodeTest + * + * @param name The test name + * @param input A byte array consisting of the input for this test + * @param failType An exception whose class should match the expected + * exception that will be thrown when this test is run + * @param princs Zero of more X500Principals which will be used + * to compare the output in a success case. + */ + DecodeTest(String name, byte[] input, Throwable failType, + X500Principal... princs) throws CertificateException { + testName = name; + testData = input.clone(); + expectedException = failType; + principals = princs; + cf = CertificateFactory.getInstance("X.509"); + } + + public abstract void passTest() throws GeneralSecurityException; + + public abstract void failTest() throws GeneralSecurityException; + } + + public static class GenMultiCertTest extends DecodeTest { + public GenMultiCertTest(String name, byte[] input, Throwable failType, + X500Principal... princs) throws CertificateException { + super(name, input, failType, princs); + } + + @Override + public void passTest() throws GeneralSecurityException { + Collection certs; + + System.out.println("generateCertificates(): " + testName); + certs = cf.generateCertificates(new ByteArrayInputStream(testData)); + + // Walk the certs Collection and do a comparison of subject names + int i = 0; + if (certs.size() == principals.length) { + for (Certificate crt : certs) { + X509Certificate xc = (X509Certificate)crt; + if (!xc.getSubjectX500Principal().equals( + principals[i])) { + throw new RuntimeException("Name mismatch: " + + "cert: " + xc.getSubjectX500Principal() + + ", expected: " + principals[i]); + } + i++; + } + } else { + throw new RuntimeException("Size mismatch: certs = " + + certs.size() + ", expected = " + + principals.length); + } } - throw new Exception("CertificateFactory.generateCertificate() did not " - + "throw CertificateParsingException on invalid X.509 cert data"); + + @Override + public void failTest() throws GeneralSecurityException { + Throwable caughtException = null; + Collection certs = null; + + System.out.println("generateCertificates(): " + testName); + if (expectedException == null) { + throw new RuntimeException("failTest requires non-null " + + "expectedException"); + } + + try { + certs = + cf.generateCertificates(new ByteArrayInputStream(testData)); + } catch (CertificateException ce) { + caughtException = ce; + } + + if (caughtException != null) { + // It has to be the right kind of exception though... + if (!caughtException.getClass().equals( + expectedException.getClass())) { + System.err.println("Unexpected exception thrown. " + + "Received: " + caughtException + ", Expected: " + + expectedException.getClass()); + throw new RuntimeException(caughtException); + } + } else { + // For a failure test, we'd expect some kind of exception + // to be thrown. + throw new RuntimeException("Failed to catch expected " + + "exception " + expectedException.getClass()); + } + } + } + + public static class GenSingleCertTest extends DecodeTest { + public GenSingleCertTest(String name, byte[] input, Throwable failType, + X500Principal... princs) throws CertificateException { + super(name, input, failType, princs); + } + + @Override + public void passTest() throws GeneralSecurityException { + X509Certificate cert; + + System.out.println("generateCertificate(): " + testName); + cert = (X509Certificate)cf.generateCertificate( + new ByteArrayInputStream(testData)); + + // Compare the cert's subject name against the expected value + // provided in the test. If multiple X500Principals were provided + // just use the first one as the expected value. + if (!cert.getSubjectX500Principal().equals(principals[0])) { + throw new RuntimeException("Name mismatch: " + + "cert: " + cert.getSubjectX500Principal() + + ", expected: " + principals[0]); + } + } + + @Override + public void failTest() throws GeneralSecurityException { + Throwable caughtException = null; + X509Certificate cert = null; + System.out.println("generateCertificate(): " + testName); + + if (expectedException == null) { + throw new RuntimeException("failTest requires non-null " + + "expectedException"); + } + + try { + cert = (X509Certificate)cf.generateCertificate( + new ByteArrayInputStream(testData)); + } catch (CertificateException e) { + caughtException = e; + } + + if (caughtException != null) { + // It has to be the right kind of exception though... + if (!caughtException.getClass().equals( + expectedException.getClass())) { + System.err.println("Unexpected exception thrown. " + + "Received: " + caughtException + ", Expected: " + + expectedException.getClass()); + throw new RuntimeException(caughtException); + } + } else { + // For a failure test, we'd expect some kind of exception + // to be thrown. + throw new RuntimeException("Failed to catch expected " + + "exception " + expectedException.getClass()); + } + } + } + + public static class GenMultiCRLTest extends DecodeTest { + public GenMultiCRLTest(String name, byte[] input, Throwable failType, + X500Principal... princs) throws CertificateException { + super(name, input, failType, princs); + } + + @Override + public void passTest() throws GeneralSecurityException { + Collection crls; + + System.out.println("generateCRLs(): " + testName); + crls = cf.generateCRLs(new ByteArrayInputStream(testData)); + + // Walk the crls Collection and do a comparison of issuer names + int i = 0; + if (crls.size() == principals.length) { + for (CRL revlist : crls) { + X509CRL xc = (X509CRL)revlist; + if (!xc.getIssuerX500Principal().equals(principals[i])) { + throw new RuntimeException("Name mismatch: " + + "CRL: " + xc.getIssuerX500Principal() + + ", expected: " + principals[i]); + } + i++; + } + } else { + throw new RuntimeException("Size mismatch: crls = " + + crls.size() + ", expected = " + + principals.length); + } + } + + @Override + public void failTest() throws GeneralSecurityException { + Throwable caughtException = null; + Collection crls = null; + + System.out.println("generateCRLs(): " + testName); + if (expectedException == null) { + throw new RuntimeException("failTest requires non-null " + + "expectedException"); + } + + try { + crls = + cf.generateCRLs(new ByteArrayInputStream(testData)); + } catch (CRLException e) { + caughtException = e; + } + + if (caughtException != null) { + // It has to be the right kind of exception though... + if (!caughtException.getClass().equals( + expectedException.getClass())) { + System.err.println("Unexpected exception thrown. " + + "Received: " + caughtException + ", Expected: " + + expectedException.getClass()); + throw new RuntimeException(caughtException); + } + } else { + // For a failure test, we'd expect some kind of exception + // to be thrown. + throw new RuntimeException("Failed to catch expected " + + "exception " + expectedException.getClass()); + } + } } } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/invalidcert.pem --- a/jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/invalidcert.pem Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -XIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx -EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFTAT -BgNVBAoTDEJFQSBXZWJMb2dpYzERMA8GA1UECxMIU2VjdXJpdHkxIzAhBgNVBAMT -GkRlbW8gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9zdXBw -b3J0QGJlYS5jb20wHhcNMDAwNTMwMjEzODAxWhcNMDQwNTEzMjEzODAxWjCBjDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG -cmFuY2lzY28xFTATBgNVBAoTDEJFQSBXZWJMb2dpYzEZMBcGA1UEAxMQd2VibG9n -aWMuYmVhLmNvbTEeMBwGCSqGSIb3DQEJARYPc3VwcG9ydEBiZWEuY29tMFwwDQYJ -KoZIhvcNAQEBBQADSwAwSAJBALdsXEHqKHgs6zj0hU5sXMAUHzoT8kgWXmNkKHXH -79qbPh6EfdlriW9G/AbRF/pKrCQu7hhllAxREbqTuSlf2EMCAwEAATANBgkqhkiG -9w0BAQQFAANBACgmqflL5m5LNeJGpWx9aIoABCiuDcpw1fFyegsqGX7CBhffcruS -1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU= ------END CERTIFICATE----- diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/text/Format/DecimalFormat/TieRoundingTest.java --- a/jdk/test/java/text/Format/DecimalFormat/TieRoundingTest.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/java/text/Format/DecimalFormat/TieRoundingTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * - * @bug 7131459 + * @bug 7131459 8039915 * @summary test various situations of NumberFormat rounding when close to tie * @author Olivier Lagneau * @run main TieRoundingTest @@ -56,7 +56,7 @@ if (!result.equals(expectedOutput)) { System.out.println(); System.out.println("========================================"); - System.out.println("***Error formatting double value from string : " + + System.out.println("***Failure : error formatting value from string : " + inputDigits); System.out.println("NumberFormat pattern is : " + ((DecimalFormat ) nf).toPattern()); @@ -103,7 +103,7 @@ if (!result.equals(expectedOutput)) { System.out.println(); System.out.println("========================================"); - System.out.println("***Error formatting double value from string : " + + System.out.println("***Failure : error formatting value from string : " + inputDigits); System.out.println("NumberFormat pattern is : " + ((DecimalFormat ) nf).toPattern()); @@ -144,7 +144,7 @@ if (!result.equals(expectedOutput)) { System.out.println(); System.out.println("========================================"); - System.out.println("***Error formatting number value from string : " + + System.out.println("***Failure : error formatting value from string : " + inputDigits); System.out.println("NumberFormat pattern is : " + ((DecimalFormat ) nf).toPattern()); @@ -174,7 +174,7 @@ public static void main(String[] args) { - // Only the 3 rounding modes below may be impacted by bug 7131459. + // The 3 HALF_* rounding modes are impacted by bugs 7131459, 8039915. // So we do not test the other rounding modes. RoundingMode[] roundingModes = { RoundingMode.HALF_DOWN, @@ -183,10 +183,14 @@ }; // Precise the relative position of input value against its closest tie. + // The double values tested below for 3 and 5 fractional digits must follow + // this scheme (position toward tie). String[] tieRelativePositions = { "below", "exact", "above", "below", "exact", "above", "below", "exact", "above", + "below", "above", "above", + "below", "below", "above", "below", "exact", "above" }; @@ -196,9 +200,13 @@ double[] values3FractDigits = { // unimpacting values close to tie, with less than 3 input fract digits 1.115d, 1.125d, 1.135d, - // impacting close to tie values covering all 6 cases + // HALF_* impacting close to tie values covering all 6 tie cases 0.3115d, 0.3125d, 0.3135d, 0.6865d, 0.6875d, 0.6885d, + // specific HALF_UP close to tie values + 0.3124d, 0.3126d, 0.3128d, + // specific HALF_DOWN close to tie values + 0.6864d, 0.6865d, 0.6868d, // unimpacting values close to tie, with more than 3 input fract digits 1.46885d, 2.46875d, 1.46865d }; @@ -207,6 +215,8 @@ "1.115d", "1.125d", "1.135d", "0.3115d", "0.3125d", "0.3135d", "0.6865d", "0.6875d", "0.6885d", + "0.3124d", "0.3126d", "0.3128d", + "0.6864d", "0.6865d", "0.6868d", "1.46885d", "2.46875d", "1.46865d" }; @@ -214,16 +224,22 @@ {"1.115", "1.125", "1.135", "0.311", "0.312", "0.314", "0.686", "0.687", "0.689", + "0.312", "0.313", "0.313", + "0.686", "0.686", "0.687", "1.469", "2.469", "1.469" }, {"1.115", "1.125", "1.135", "0.311", "0.312", "0.314", "0.686", "0.688", "0.689", + "0.312", "0.313", "0.313", + "0.686", "0.686", "0.687", "1.469", "2.469", "1.469" }, {"1.115", "1.125", "1.135", "0.311", "0.313", "0.314", "0.686", "0.688", "0.689", + "0.312", "0.313", "0.313", + "0.686", "0.686", "0.687", "1.469", "2.469", "1.469" }, }; @@ -250,9 +266,13 @@ double[] values5FractDigits = { // unimpacting values close to tie, with less than 5 input fract digits 1.3135d, 1.3125d, 1.3115d, - // impacting values close to tie, covering all 6 cases + // HALF_* impacting values close to tie, covering all 6 cases 1.328115d, 1.328125d, 1.328135d, 1.796865d, 1.796875d, 1.796885d, + // specific HALF_UP close to tie values + 1.328124d, 1.798876d, 1.796889d, + // specific HALF_DOWN close to tie values + 1.328114d, 1.796865d, 1.328138d, // unimpacting values close to tie, with more than 5 input fract digits 1.3281149999999d, 1.75390625d, 1.7968750000001d }; @@ -261,6 +281,8 @@ "1.3135d", "1.3125d", "1.3115d", "1.328115d", "1.328125d", "1.328135d", "1.796865d", "1.796875d", "1.796885d", + "1.328124d", "1.798876d", "1.796889d", + "1.328114d", "1.796865d", "1.328138d", "1.3281149999999d", "1.75390625d", "1.7968750000001d" }; @@ -268,16 +290,22 @@ {"1.3135", "1.3125", "1.3115", "1.32811", "1.32812", "1.32814", "1.79686", "1.79687", "1.79689", + "1.32812", "1.79888", "1.79689", + "1.32811", "1.79686", "1.32814", "1.32811", "1.75391", "1.79688" }, {"1.3135", "1.3125", "1.3115", "1.32811", "1.32812", "1.32814", "1.79686", "1.79688", "1.79689", + "1.32812", "1.79888", "1.79689", + "1.32811", "1.79686", "1.32814", "1.32811", "1.75391", "1.79688" }, {"1.3135", "1.3125", "1.3115", "1.32811", "1.32813", "1.32814", "1.79686", "1.79688", "1.79689", + "1.32812", "1.79888", "1.79689", + "1.32811", "1.79686", "1.32814", "1.32811", "1.75391", "1.79688" } }; diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/util/concurrent/FutureTask/NegativeTimeout.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/concurrent/FutureTask/NegativeTimeout.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8060052 + * @summary FutureTask; fix underflow when timeout = Long.MIN_VALUE + * @author Chris Hegarty + */ + +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; + +// If the bug exists the test will eventually be interrupted by the +// test harness and fail with an InterruptedException, otherwise it +// will throw a TimeoutException almost immediately and return silently. + +public class NegativeTimeout { + public static void main(String[] args) throws Exception { + FutureTask task = new FutureTask<>( () -> { return null; } ); + try { + task.get(Long.MIN_VALUE, TimeUnit.NANOSECONDS); + } catch (TimeoutException success) {} + } +} + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/util/zip/InterruptibleZip.java --- a/jdk/test/java/util/zip/InterruptibleZip.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/java/util/zip/InterruptibleZip.java Wed Jul 05 20:04:43 2017 +0200 @@ -30,32 +30,14 @@ import java.util.zip.*; public class InterruptibleZip { - private static String rtJar() { - String bcp = System.getProperty("sun.boot.class.path"); - for (String pathElement : bcp.split(File.pathSeparator)) { - if (pathElement.endsWith(File.separator + "rt.jar") && - new File(pathElement).exists()) { - System.out.println("rtJar="+pathElement); - return pathElement; - } - if (pathElement.endsWith(File.separator + "classes") && - new File(pathElement).isDirectory()) { - System.out.println("rt.jar not available"); - return null; - } - } - throw new Error("Can't find rt.jar or classes directory"); - } public static void main(String[] args) throws Exception { /* Interrupt the current thread. The is.read call below - should continue reading rt.jar. + should continue reading input.jar. */ - String rtJar = rtJar(); - if (rtJar == null) return; Thread.currentThread().interrupt(); - ZipFile zf = new ZipFile(rtJar); - ZipEntry ze = zf.getEntry("java/lang/Object.class"); + ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.jar")); + ZipEntry ze = zf.getEntry("Available.java"); InputStream is = zf.getInputStream(ze); byte[] buf = new byte[512]; int n = is.read(buf); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/java/util/zip/ZipFile/FinalizeZipFile.java --- a/jdk/test/java/util/zip/ZipFile/FinalizeZipFile.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/java/util/zip/ZipFile/FinalizeZipFile.java Wed Jul 05 20:04:43 2017 +0200 @@ -51,12 +51,11 @@ private static void makeGarbage() throws Throwable { final Random rnd = new Random(); - final String javaHome = System.getProperty("java.home"); // Create some ZipFiles. - // Find some .jar files in JDK's lib directory. - final File lib = new File(javaHome, "lib"); - check(lib.isDirectory()); - final File[] jars = lib.listFiles( + // Find some .jar files in test directory. + final File testdir = new File(System.getProperty("test.src", ".")); + check(testdir.isDirectory()); + final File[] jars = testdir.listFiles( new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".jar");}}); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/management/MBeanInfo/NotificationInfoTest.java --- a/jdk/test/javax/management/MBeanInfo/NotificationInfoTest.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/javax/management/MBeanInfo/NotificationInfoTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -36,7 +36,6 @@ import java.lang.management.*; import java.lang.reflect.*; import java.net.*; -import java.security.CodeSource; import java.util.*; import java.util.jar.*; import javax.management.*; @@ -83,27 +82,10 @@ System.out.println("Checking platform MBeans..."); checkPlatformMBeans(); - CodeSource cs = - javax.management.MBeanServer.class.getProtectionDomain() - .getCodeSource(); - URL codeBase; - if (cs == null) { - String javaHome = System.getProperty("java.home"); - String[] candidates = {"/lib/rt.jar", "/classes/"}; - codeBase = null; - for (String candidate : candidates) { - File file = new File(javaHome + candidate); - if (file.exists()) { - codeBase = file.toURI().toURL(); - break; - } - } - if (codeBase == null) { - throw new Exception( - "Could not determine codeBase for java.home=" + javaHome); - } - } else - codeBase = cs.getLocation(); + URL codeBase = ClassLoader.getSystemResource("javax/management/MBeanServer.class"); + if (codeBase == null) { + throw new Exception("Could not determine codeBase for " + MBeanServer.class); + } System.out.println(); System.out.println("Looking for standard MBeans..."); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/naming/spi/providers/InitialContextTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/naming/spi/providers/InitialContextTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.naming.Context; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonMap; + +/* + * @test + * @bug 8044627 + * @summary Examines different ways JNDI providers can hook up themselves and + * become available. Each case mimics the most straightforward way of + * executing scenarios. + */ +public class InitialContextTest { + + public static void main(String[] args) throws Throwable { + unknownInitialContextFactory(); + initialContextFactoryInAJar(); + initialContextFactoryAsService(); + } + + private static void unknownInitialContextFactory() throws Throwable { + + // This is a parameter of this test case, it should work for any value + // of it, provided a class with this FQN is not available in a runtime. + // So pick any name you like. + String factoryClassFqn = + "net.java.openjdk.test.UnknownInitialContextFactory"; + + Path tmp = Files.createDirectory(Paths.get("InitialContextTest-1")); + + Path src = templatesHome().resolve("test.template"); + Path dst = tmp.resolve("Test.java"); + Files.copy(src, dst); + + javac(tmp, dst); + + Path build = Files.createDirectory(tmp.resolve("build")); + Files.copy(tmp.resolve("Test.class"), build.resolve("Test.class")); + + Map props + = singletonMap(Context.INITIAL_CONTEXT_FACTORY, factoryClassFqn); + + Result r = java(props, singleton(build), "Test"); + + if (r.exitValue == 0 || !r.output.startsWith( + stackTraceStringForClassNotFound(factoryClassFqn))) { + throw new RuntimeException( + "Expected a different kind of failure: " + r.output); + } + } + + private static String stackTraceStringForClassNotFound(String fqn) { + return String.format( + "Exception in thread \"main\" javax.naming.NoInitialContextException: " + + "Cannot instantiate class: %s " + + "[Root exception is java.lang.ClassNotFoundException: %s]", + fqn, fqn); + } + + private static void initialContextFactoryInAJar() throws Throwable { + + String factoryClassFqn = + "net.java.openjdk.test.DummyInitialContextFactory"; + + Path tmp = Files.createDirectory(Paths.get("InitialContextTest-2")); + + Path src = templatesHome().resolve("test.template"); + Path dst = tmp.resolve("Test.java"); + Files.copy(src, dst); + + Path dst1 = createFactoryFrom(templatesHome().resolve("factory.template"), + factoryClassFqn, tmp); + + javac(tmp, dst); + Path explodedJar = Files.createDirectory(tmp.resolve("exploded-jar")); + javac(explodedJar, dst1); + jar(tmp.resolve("test.jar"), explodedJar); + + Path build = Files.createDirectory(tmp.resolve("build")); + Files.copy(tmp.resolve("Test.class"), build.resolve("Test.class")); + Files.copy(tmp.resolve("test.jar"), build.resolve("test.jar")); + + Map props + = singletonMap(Context.INITIAL_CONTEXT_FACTORY, factoryClassFqn); + + Result r = java(props, asList(build.resolve("test.jar"), build), "Test"); + + if (r.exitValue != 0 || !r.output.isEmpty()) + throw new RuntimeException(r.output); + } + + + private static Path createFactoryFrom(Path srcTemplate, + String factoryFqn, + Path dstFolder) throws IOException { + + String factorySimpleName, packageName; + int i = factoryFqn.lastIndexOf('.'); + if (i < 0) { + packageName = ""; + factorySimpleName = factoryFqn; + } else { + packageName = factoryFqn.substring(0, i); + factorySimpleName = factoryFqn.substring(i + 1); + } + + Path result = dstFolder.resolve(factorySimpleName + ".java"); + File dst = result.toFile(); + File src = srcTemplate.toFile(); + try (BufferedReader r = new BufferedReader(new FileReader(src)); + BufferedWriter w = new BufferedWriter(new FileWriter(dst))) { + + List lines = processTemplate(packageName, factorySimpleName, + r.lines()).collect(Collectors.toList()); + + Iterator it = lines.iterator(); + if (it.hasNext()) + w.write(it.next()); + while (it.hasNext()) { + w.newLine(); + w.write(it.next()); + } + } + return result; + } + + private static Stream processTemplate(String packageName, + String factorySimpleName, + Stream lines) { + Function pckg; + + if (packageName.isEmpty()) { + pckg = s -> s.contains("$package") ? "" : s; + } else { + pckg = s -> s.replaceAll("\\$package", packageName); + } + + Function factory + = s -> s.replaceAll("\\$factoryName", factorySimpleName); + + return lines.map(pckg).map(factory); + } + + private static void initialContextFactoryAsService() throws Throwable { + + String factoryClassFqn = + "net.java.openjdk.test.BrokenInitialContextFactory"; + + Path tmp = Files.createDirectory(Paths.get("InitialContextTest-3")); + + Path src = templatesHome().resolve("test.template"); + Path dst = tmp.resolve("Test.java"); + Files.copy(src, dst); + + Path dst1 = createFactoryFrom(templatesHome().resolve("broken_factory.template"), + factoryClassFqn, tmp); + + javac(tmp, dst); + + Path explodedJar = Files.createDirectory(tmp.resolve("exploded-jar")); + Path services = Files.createDirectories(explodedJar.resolve("META-INF") + .resolve("services")); + + Path s = services.resolve("javax.naming.spi.InitialContextFactory"); + FileWriter fw = new FileWriter(s.toFile()); + try { + fw.write(factoryClassFqn); + } finally { + fw.close(); + } + + javac(explodedJar, dst1); + jar(tmp.resolve("test.jar"), explodedJar); + + Path build = Files.createDirectory(tmp.resolve("build")); + Files.copy(tmp.resolve("Test.class"), build.resolve("Test.class")); + Files.copy(tmp.resolve("test.jar"), build.resolve("test.jar")); + + Map props = new HashMap<>(); + props.put("java.ext.dirs", build.toString()); + props.put(Context.INITIAL_CONTEXT_FACTORY, factoryClassFqn); + + Result r = java(props, singleton(build), "Test"); + + if (r.exitValue == 0 || !verifyOutput(r.output, factoryClassFqn)) + throw new RuntimeException(r.output); + } + + // IMO, that's the easiest way that gives you a fair amount of confidence in + // that j.u.ServiceLoader is loading a factory rather than Class.forName + private static boolean verifyOutput(String output, String fqn) { + String s1 = String.format( + "Exception in thread \"main\" javax.naming.NoInitialContextException: " + + "Cannot load initial context factory '%s' " + + "[Root exception is java.util.ServiceConfigurationError: " + + "javax.naming.spi.InitialContextFactory: " + + "Provider %s could not be instantiated]", fqn, fqn); + + String s2 = String.format("Caused by: java.util.ServiceConfigurationError: " + + "javax.naming.spi.InitialContextFactory: " + + "Provider %s could not be instantiated", fqn); + + String s3 = "Caused by: java.lang.RuntimeException: " + + "This is a broken factory. It is supposed to throw this exception."; + + return output.startsWith(s1) && output.contains(s2) + && output.contains(s1); + } + + private static void jar(Path jarName, Path jarRoot) { + String jar = getJDKTool("jar"); + ProcessBuilder p = new ProcessBuilder(jar, "cf", jarName.toString(), + "-C", jarRoot.toString(), "."); + quickFail(run(p)); + } + + private static void javac(Path compilationOutput, Path... sourceFiles) { + String javac = getJDKTool("javac"); + List commands = new ArrayList<>(); + commands.addAll(asList(javac, "-d", compilationOutput.toString())); + List paths = asList(sourceFiles); + commands.addAll(paths.stream() + .map(Path::toString) + .collect(Collectors.toList())); + quickFail(run(new ProcessBuilder(commands))); + } + + private static void quickFail(Result r) { + if (r.exitValue != 0) + throw new RuntimeException(r.output); + } + + private static Result java(Map properties, + Collection classpath, + String classname) { + + String java = getJDKTool("java"); + + List commands = new ArrayList<>(); + commands.add(java); + commands.addAll(properties.entrySet() + .stream() + .map(e -> "-D" + e.getKey() + "=" + e.getValue()) + .collect(Collectors.toList())); + + String cp = classpath.stream() + .map(Path::toString) + .collect(Collectors.joining(File.pathSeparator)); + commands.add("-cp"); + commands.add(cp); + commands.add(classname); + + return run(new ProcessBuilder(commands)); + } + + private static Result run(ProcessBuilder b) { + Process p = null; + try { + p = b.start(); + } catch (IOException e) { + throw new RuntimeException( + format("Couldn't start process '%s'", b.command()), e); + } + + String output; + try { + output = toString(p.getInputStream(), p.getErrorStream()); + } catch (IOException e) { + throw new RuntimeException( + format("Couldn't read process output '%s'", b.command()), e); + } + + try { + p.waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException( + format("Process hasn't finished '%s'", b.command()), e); + } + + return new Result(p.exitValue(), output); + } + + private static String getJDKTool(String name) { + String testJdk = System.getProperty("test.jdk"); + if (testJdk == null) + throw new RuntimeException("Please provide test.jdk property at a startup"); + return testJdk + File.separator + "bin" + File.separator + name; + } + + private static Path templatesHome() { + String testSrc = System.getProperty("test.src"); + if (testSrc == null) + throw new RuntimeException("Please provide test.src property at a startup"); + return Paths.get(testSrc); + } + + private static String toString(InputStream... src) throws IOException { + StringWriter dst = new StringWriter(); + Reader concatenated = + new InputStreamReader( + new SequenceInputStream( + Collections.enumeration(asList(src)))); + copy(concatenated, dst); + return dst.toString(); + } + + private static void copy(Reader src, Writer dst) throws IOException { + int len; + char[] buf = new char[1024]; + try { + while ((len = src.read(buf)) != -1) + dst.write(buf, 0, len); + } finally { + try { + src.close(); + } catch (IOException ignored1) { + } finally { + try { + dst.close(); + } catch (IOException ignored2) { + } + } + } + } + + private static class Result { + + final int exitValue; + final String output; + + private Result(int exitValue, String output) { + this.exitValue = exitValue; + this.output = output; + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/naming/spi/providers/broken_factory.template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/naming/spi/providers/broken_factory.template Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package $package; + +import javax.naming.*; +import javax.naming.spi.InitialContextFactory; +import java.util.Hashtable; + +public class $factoryName implements InitialContextFactory { + + public $factoryName() { + throw new RuntimeException( + "This is a broken factory. It is supposed to throw this exception."); + } + + @Override + public Context getInitialContext(Hashtable env) throws NamingException { + return new DummyInitialContext(); + } + + private class DummyInitialContext implements Context { + + @Override + public Object lookup(Name name) { + return null; + } + + @Override + public Object lookup(String name) { + return null; + } + + @Override + public void bind(Name name, Object obj) { + } + + @Override + public void bind(String name, Object obj) { + } + + @Override + public void rebind(Name name, Object obj) { + } + + @Override + public void rebind(String name, Object obj) { + } + + @Override + public void unbind(Name name) { + } + + @Override + public void unbind(String name) { + } + + @Override + public void rename(Name oldName, Name newName) { + } + + @Override + public void rename(String oldName, String newName) { + } + + @Override + public NamingEnumeration list(Name name) { + return null; + } + + @Override + public NamingEnumeration list(String name) { + return null; + } + + @Override + public NamingEnumeration listBindings(Name name) { + return null; + } + + @Override + public NamingEnumeration listBindings(String name) { + return null; + } + + @Override + public void destroySubcontext(Name name) { + } + + @Override + public void destroySubcontext(String name) { + } + + @Override + public Context createSubcontext(Name name) { + return null; + } + + @Override + public Context createSubcontext(String name) { + return null; + } + + @Override + public Object lookupLink(Name name) { + return null; + } + + @Override + public Object lookupLink(String name) { + return null; + } + + @Override + public NameParser getNameParser(Name name) { + return null; + } + + @Override + public NameParser getNameParser(String name) { + return null; + } + + @Override + public Name composeName(Name name, Name prefix) { + return null; + } + + @Override + public String composeName(String name, String prefix) { + return null; + } + + @Override + public Object addToEnvironment(String propName, Object propVal) { + return null; + } + + @Override + public Object removeFromEnvironment(String propName) { + return null; + } + + @Override + public Hashtable getEnvironment() { + return null; + } + + @Override + public void close() { + } + + @Override + public String getNameInNamespace() { + return null; + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/naming/spi/providers/factory.template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/naming/spi/providers/factory.template Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package $package; + +import javax.naming.*; +import javax.naming.spi.InitialContextFactory; +import java.util.Hashtable; + +public class $factoryName implements InitialContextFactory { + + @Override + public Context getInitialContext(Hashtable env) throws NamingException { + return new DummyInitialContext(); + } + + private class DummyInitialContext implements Context { + + @Override + public Object lookup(Name name) { + return null; + } + + @Override + public Object lookup(String name) { + return null; + } + + @Override + public void bind(Name name, Object obj) { + } + + @Override + public void bind(String name, Object obj) { + } + + @Override + public void rebind(Name name, Object obj) { + } + + @Override + public void rebind(String name, Object obj) { + } + + @Override + public void unbind(Name name) { + } + + @Override + public void unbind(String name) { + } + + @Override + public void rename(Name oldName, Name newName) { + } + + @Override + public void rename(String oldName, String newName) { + } + + @Override + public NamingEnumeration list(Name name) { + return null; + } + + @Override + public NamingEnumeration list(String name) { + return null; + } + + @Override + public NamingEnumeration listBindings(Name name) { + return null; + } + + @Override + public NamingEnumeration listBindings(String name) { + return null; + } + + @Override + public void destroySubcontext(Name name) { + } + + @Override + public void destroySubcontext(String name) { + } + + @Override + public Context createSubcontext(Name name) { + return null; + } + + @Override + public Context createSubcontext(String name) { + return null; + } + + @Override + public Object lookupLink(Name name) { + return null; + } + + @Override + public Object lookupLink(String name) { + return null; + } + + @Override + public NameParser getNameParser(Name name) { + return null; + } + + @Override + public NameParser getNameParser(String name) { + return null; + } + + @Override + public Name composeName(Name name, Name prefix) { + return null; + } + + @Override + public String composeName(String name, String prefix) { + return null; + } + + @Override + public Object addToEnvironment(String propName, Object propVal) { + return null; + } + + @Override + public Object removeFromEnvironment(String propName) { + return null; + } + + @Override + public Hashtable getEnvironment() { + return null; + } + + @Override + public void close() { + } + + @Override + public String getNameInNamespace() { + return null; + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/naming/spi/providers/test.template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/naming/spi/providers/test.template Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.util.Properties; + +public class Test { + + public static void main(String[] args) throws NamingException { + Properties env = System.getProperties(); + Context ctx = new InitialContext(env); + try { + ctx.lookup(""); + } finally { + ctx.close(); + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/print/RegisterNullService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/print/RegisterNullService.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8059219 + * @summary Should not be able to register null service. + * @run main RegisterNullService +*/ + +import javax.print.PrintService; +import javax.print.PrintServiceLookup; + +public class RegisterNullService { + public static void main (String [] args) throws RuntimeException { + + boolean registered = PrintServiceLookup.registerService(null); + if (registered) { + throw new RuntimeException("Null service was registered"); + } + PrintService[] services = + PrintServiceLookup.lookupPrintServices(null, null); + for (int i = 0; i < services.length; i++) { + if (services[i] == null) { + throw new RuntimeException("Null service found."); + } + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/sound/midi/MidiDeviceProvider/NullInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiDeviceProvider/NullInfo.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Collection; +import java.util.HashSet; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.spi.MidiDeviceProvider; + +import static java.util.ServiceLoader.load; + +/** + * @test + * @bug 8058115 + * @summary MidiDeviceProvider shouldn't returns incorrect results or throw NPE + * in case of null MidiDevice.Info + * @author Sergey Bylokhov + */ +public final class NullInfo { + + public static void main(final String[] args) { + // MidiSystem API + try { + MidiSystem.getMidiDevice(null); + throw new RuntimeException("IllegalArgumentException expected"); + } catch (final MidiUnavailableException e) { + throw new RuntimeException("IllegalArgumentException expected", e); + } catch (final IllegalArgumentException ignored) { + // expected + } + // MidiDeviceProvider API + final Collection errors = new HashSet<>(); + for (final MidiDeviceProvider mdp : load(MidiDeviceProvider.class)) { + try { + if (mdp.isDeviceSupported(null)) { + throw new RuntimeException("null is supported"); + } + final MidiDevice device = mdp.getDevice(null); + System.err.println("MidiDevice: " + device); + throw new RuntimeException("IllegalArgumentException expected"); + } catch (final IllegalArgumentException e) { + errors.add(e.getMessage()); + } + } + if (errors.size() != 1) { + throw new RuntimeException("Wrong number of messages:" + errors); + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/sound/midi/MidiDeviceProvider/UnsupportedInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/MidiDeviceProvider/UnsupportedInfo.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.spi.MidiDeviceProvider; + +import static java.util.ServiceLoader.load; + +/** + * @test + * @bug 8058115 + * @summary MidiDeviceProvider shouldn't returns incorrect results in case of + * unsupported MidiDevice.Info + * @author Sergey Bylokhov + */ +public final class UnsupportedInfo { + + public static void main(final String[] args) { + final MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (final MidiDeviceProvider mdp : load(MidiDeviceProvider.class)) { + for (final MidiDevice.Info info : infos) { + if (mdp.isDeviceSupported(info)) { + if (mdp.getDevice(info) == null) { + throw new RuntimeException("MidiDevice is null"); + } + } else { + try { + mdp.getDevice(info); + throw new RuntimeException( + "IllegalArgumentException expected"); + } catch (final IllegalArgumentException ignored) { + // expected + } + } + } + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/swing/text/NavigationFilter/8058305/bug8058305.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/text/NavigationFilter/8058305/bug8058305.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.text.BadLocationException; +import javax.swing.text.NavigationFilter; +import javax.swing.text.Position; + +/* + * @test + * @bug 8058305 + * @summary BadLocationException is not thrown by + * javax.swing.text.View.getNextVisualPositionFrom() for invalid positions + * @run main bug8058305 + */ +public class bug8058305 { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(bug8058305::createAndShowGUI); + } + + private static void createAndShowGUI() { + JFrame frame = new JFrame(); + + JFormattedTextField textField = new JFormattedTextField(); + NavigationFilter navigationFilter = new NavigationFilter(); + textField.setText("Test for Tests"); + frame.getContentPane().add(textField); + frame.pack(); + + Position.Bias[] biasRet = {Position.Bias.Forward}; + try { + navigationFilter.getNextVisualPositionFrom(textField, 100, + Position.Bias.Backward, SwingConstants.EAST, biasRet); + throw new RuntimeException("BadLocationException is not thrown!"); + } catch (BadLocationException expectedException) { + } + + frame.setVisible(true); + + try { + navigationFilter.getNextVisualPositionFrom(textField, 200, + Position.Bias.Forward, SwingConstants.WEST, biasRet); + throw new RuntimeException("BadLocationException is not thrown!"); + } catch (BadLocationException expectedException) { + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/TEST.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/TEST.properties Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,3 @@ +# This file identifies root(s) of the test-ng hierarchy. + +TestNG.dirs = . diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/BaseTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/BaseTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,338 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.File; -import java.net.URL; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.impl.Constants; -import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; -import com.sun.org.apache.xerces.internal.xs.ElementPSVI; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; -import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; -import javax.xml.transform.stream.StreamSource; -import org.w3c.dom.Document; -import org.w3c.dom.Node; - -public abstract class BaseTest { - protected final static String ROOT_TYPE = Constants.XERCES_PROPERTY_PREFIX - + Constants.ROOT_TYPE_DEFINITION_PROPERTY; - - protected final static String IGNORE_XSI_TYPE = Constants.XERCES_FEATURE_PREFIX - + Constants.IGNORE_XSI_TYPE_FEATURE; - - protected final static String ID_IDREF_CHECKING = Constants.XERCES_FEATURE_PREFIX - + Constants.ID_IDREF_CHECKING_FEATURE; - - protected final static String IDC_CHECKING = Constants.XERCES_FEATURE_PREFIX - + Constants.IDC_CHECKING_FEATURE; - - protected final static String UNPARSED_ENTITY_CHECKING = Constants.XERCES_FEATURE_PREFIX - + Constants.UNPARSED_ENTITY_CHECKING_FEATURE; - - protected final static String USE_GRAMMAR_POOL_ONLY = Constants.XERCES_FEATURE_PREFIX - + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE; - - protected final static String DYNAMIC_VALIDATION = Constants.XERCES_FEATURE_PREFIX - + Constants.DYNAMIC_VALIDATION_FEATURE; - - protected final static String DOCUMENT_CLASS_NAME = Constants.XERCES_PROPERTY_PREFIX - + Constants.DOCUMENT_CLASS_NAME_PROPERTY; - - protected Schema schema; - protected Validator fValidator; - - protected SpecialCaseErrorHandler fErrorHandler; - - DocumentBuilder builder; - protected Document fDocument; - - protected ElementPSVI fRootNode; - - protected URL fDocumentURL; - protected String documentPath; - protected String fDocumentId; - - static String errMessage; - - int passed = 0, failed = 0; - - public static boolean isWindows = false; - static { - if (System.getProperty("os.name").indexOf("Windows")>-1) { - isWindows = true; - } - }; - public static final String USER_DIR = System.getProperty("user.dir", "."); - public static final String BASE_DIR = System.getProperty("test.src", USER_DIR) - .replaceAll("\\" + System.getProperty("file.separator"), "/"); - - protected abstract String getSchemaFile(); - - protected abstract String getXMLDocument(); - - public BaseTest(String name) { - fErrorHandler = new SpecialCaseErrorHandler(getRelevantErrorIDs()); - } - - protected void setUp() throws Exception { - - DocumentBuilderFactory docFactory = DocumentBuilderFactory - .newInstance(); - docFactory.setAttribute(DOCUMENT_CLASS_NAME, - "com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl"); - docFactory.setNamespaceAware(true); - builder = docFactory.newDocumentBuilder(); - - documentPath = BASE_DIR + "/" + getXMLDocument(); -System.out.println("documentPath:"+documentPath); - if (isWindows) { - fDocumentId = "file:/" + documentPath; - } else { - fDocumentId = "file:" + documentPath; - } - //fDocumentURL = ClassLoader.getSystemResource(documentPath); - //fDocumentURL = getClass().getResource(documentPath); -System.out.println("fDocumentId:"+fDocumentId); -//System.out.println("fDocumentURL.toExternalForm:"+fDocumentURL.toExternalForm()); -/** - if (fDocumentURL == null) { - throw new FileNotFoundException("Couldn't find xml file for test: " + documentPath); - } - fDocument = builder.parse(fDocumentURL.toExternalForm()); - fRootNode = (ElementPSVI) fDocument.getDocumentElement(); - */ - SchemaFactory sf = SchemaFactory - .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - sf.setFeature(USE_GRAMMAR_POOL_ONLY, getUseGrammarPoolOnly()); - String schemaPath = BASE_DIR + "/" + getSchemaFile(); - /** - URL schemaURL = ClassLoader.getSystemResource(schemaPath); - if (schemaURL == null) { - throw new FileNotFoundException("Couldn't find schema file for test: " + schemaPath); - } - */ - schema = sf.newSchema(new StreamSource(new File(schemaPath))); - } - - protected void tearDown() throws Exception { - fValidator = null; - fDocument = null; - fRootNode = null; - fErrorHandler.reset(); - System.out.println("\nNumber of tests passed: " + passed); - System.out.println("Number of tests failed: " + failed + "\n"); - - if (errMessage != null) { - throw new RuntimeException(errMessage); - } - } - - protected void validateDocument() throws Exception { - Source source = new DOMSource(fDocument); - source.setSystemId(fDocumentId); - Result result = new DOMResult(fDocument); - fValidator.validate(source, result); - } - - protected void validateFragment() throws Exception { - Source source = new DOMSource((Node) fRootNode); - source.setSystemId(fDocumentId); - Result result = new DOMResult((Node) fRootNode); - fValidator.validate(source, result); - } - - protected void reset() throws Exception { - try { -System.out.println("new File(documentPath)" + new File(documentPath)); - - fDocument = builder.parse(new File(documentPath)); - fRootNode = (ElementPSVI) fDocument.getDocumentElement(); -System.out.println("fDocument" + fDocument); -System.out.println("fRootNode" + fRootNode); - fValidator = schema.newValidator(); - fErrorHandler.reset(); - fValidator.setErrorHandler(fErrorHandler); - fValidator.setFeature(DYNAMIC_VALIDATION, false); - } catch (Exception e) { - e.printStackTrace(); - } - } - - protected PSVIElementNSImpl getChild(int n) { - int numFound = 0; - Node child = ((Node) fRootNode).getFirstChild(); - while (child != null) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - numFound++; - if (numFound == n) { - return (PSVIElementNSImpl) child; - } - } - child = child.getNextSibling(); - } - return null; - } - - protected String[] getRelevantErrorIDs() { - return new String[] {}; - } - - protected boolean getUseGrammarPoolOnly() { - return false; - } - - // specialized asserts - - protected void assertValidity(short expectedValidity, short actualValidity) { - String expectedString = expectedValidity == ItemPSVI.VALIDITY_VALID ? "valid" - : (expectedValidity == ItemPSVI.VALIDITY_INVALID ? "invalid" - : "notKnown"); - String actualString = actualValidity == ItemPSVI.VALIDITY_VALID ? "valid" - : (actualValidity == ItemPSVI.VALIDITY_INVALID ? "invalid" - : "notKnown"); - String message = "{validity} was <" + actualString - + "> but it should have been <" + expectedString + ">"; - assertEquals(message, expectedValidity, actualValidity); - } - - protected void assertValidationAttempted(short expectedAttempted, - short actualAttempted) { - String expectedString = expectedAttempted == ItemPSVI.VALIDATION_FULL ? "full" - : (expectedAttempted == ItemPSVI.VALIDATION_PARTIAL ? "partial" - : "none"); - String actualString = actualAttempted == ItemPSVI.VALIDATION_FULL ? "full" - : (actualAttempted == ItemPSVI.VALIDATION_PARTIAL ? "partial" - : "none"); - String message = "{validity} was <" + actualString - + "> but it should have been <" + expectedString + ">"; - assertEquals(message, expectedAttempted, actualAttempted); - } - - protected void assertElementName(String expectedName, String actualName) { - assertEquals("Local name of element declaration is wrong.", - expectedName, actualName); - } - - protected void assertElementNull(XSElementDeclaration elem) { - assertNull("Element declaration should be null.", elem); - } - - protected void assertElementNamespace(String expectedName, String actualName) { - assertEquals("Namespace of element declaration is wrong.", - expectedName, actualName); - } - - protected void assertElementNamespaceNull(String actualName) { - assertNull("Local name of element declaration should be null.", - actualName); - } - - protected void assertTypeName(String expectedName, String actualName) { - assertEquals("Local name of type definition is wrong.", expectedName, - actualName); - } - - protected void assertTypeNull(XSTypeDefinition type) { - assertNull("Type definition should be null.", type); - } - - protected void assertTypeNamespace(String expectedName, String actualName) { - assertEquals("Namespace of type definition is wrong.", expectedName, - actualName); - } - - protected void assertTypeNamespaceNull(String actualName) { - assertNull("Namespace of type definition should be null.", actualName); - } - - protected void assertError(String error) { - assertTrue("Error <" + error + "> should have occured, but did not.", - fErrorHandler.specialCaseFound(error)); - } - - protected void assertNoError(String error) { - assertFalse("Error <" + error - + "> should not have occured (but it did)", fErrorHandler - .specialCaseFound(error)); - } - - protected void assertAnyType(XSTypeDefinition type) { - assertEquals("Type is supposed to be anyType", SchemaGrammar.fAnyType, - type); - } - - void assertEquals(String msg, Object expected, Object actual) { - if (!expected.equals(actual)) { - fail(msg + " Expected: " + expected + " Actual: " + actual); - } else { - success(null); - } - } - void assertNull(String msg, Object value) { - if (value != null) { - fail(msg); - } else { - success(null); - } - } - void assertTrue(String msg, boolean value) { - if (!value) { - fail(msg); - } else { - success(null); - } - } - void assertFalse(String msg, boolean value) { - if (value) { - fail(msg); - } else { - success(null); - } - } - void fail(String errMsg) { - if (errMessage == null) { - errMessage = errMsg; - } else { - errMessage = errMessage + "\n" + errMsg; - } - failed++; - } - - void success(String msg) { - passed++; - System.out.println(msg); - if (msg != null) { - if (msg.length() != 0) { - System.out.println(msg); - } - } - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/BasicTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/BasicTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class BasicTest extends BaseTest { - - protected String getXMLDocument() { - return "base.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public BasicTest(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testSimpleValidation() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - doValidityAsserts(); - } - - @Test - public void testSimpleValidationWithTrivialXSIType() { - try { - reset(); - ((PSVIElementNSImpl) fRootNode).setAttributeNS( - "http://www.w3.org/2001/XMLSchema-instance", "type", "X"); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - doValidityAsserts(); - } - - private void doValidityAsserts() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertElementNamespaceNull(fRootNode.getElementDeclaration() - .getNamespace()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/FixedAttrTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/FixedAttrTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * The purpose of this test is to execute all of the isComparable calls in - * XMLSchemaValidator. There are two calls in processElementContent and two - * calls in processOneAttribute. - * - * @author peterjm - */ -public class FixedAttrTest extends BaseTest { - - protected String getXMLDocument() { - return "fixedAttr.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public FixedAttrTest(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefault() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("B", child.getElementDeclaration().getName()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("D", child.getElementDeclaration().getName()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IdIdrefCheckingTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IdIdrefCheckingTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.xml.sax.SAXException; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -// duplicate IDs -// reference to non-existent ID - -public class IdIdrefCheckingTest extends BaseTest { - public static final String DUPLICATE_ID = "cvc-id.2"; - - public static final String NO_ID_BINDING = "cvc-id.1"; - - protected String getXMLDocument() { - return "idIdref.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - protected String[] getRelevantErrorIDs() { - return new String[] { DUPLICATE_ID, NO_ID_BINDING }; - } - - public IdIdrefCheckingTest(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefault() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSetFalse() { - try { - reset(); - fValidator.setFeature(ID_IDREF_CHECKING, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkValidResult(); - } - - @Test - public void testSetTrue() { - try { - reset(); - fValidator.setFeature(ID_IDREF_CHECKING, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - private void checkDefault() { - assertError(DUPLICATE_ID); - assertError(NO_ID_BINDING); - - assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("idType", child.getTypeDefinition().getName()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("idType", child.getTypeDefinition().getName()); - - child = super.getChild(3); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("idrefType", child.getTypeDefinition().getName()); - } - - private void checkValidResult() { - assertNoError(DUPLICATE_ID); - assertNoError(NO_ID_BINDING); - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("idType", child.getTypeDefinition().getName()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("idType", child.getTypeDefinition().getName()); - - child = super.getChild(3); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("idrefType", child.getTypeDefinition().getName()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IdentityConstraintCheckingTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IdentityConstraintCheckingTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.xml.sax.SAXException; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IdentityConstraintCheckingTest extends BaseTest { - // These values are unstable, since they're not actually error keys, but - // simply - // the first part of the error message. - public static final String DUPLICATE_UNIQUE = "cvc-identity-constraint.4.1"; - - public static final String DUPLICATE_KEY = "cvc-identity-constraint.4.2.2"; - - public static final String INVALID_KEYREF = "cvc-identity-constraint.4.3"; - - protected String getXMLDocument() { - return "idc.xml"; - } - - protected String getSchemaFile() { - return "idc.xsd"; - } - - protected String[] getRelevantErrorIDs() { - return new String[] { DUPLICATE_UNIQUE, DUPLICATE_KEY, INVALID_KEYREF }; - } - - public IdentityConstraintCheckingTest(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefault() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSetFalse() { - try { - reset(); - fValidator.setFeature(IDC_CHECKING, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkValidResult(); - } - - @Test - public void testSetTrue() { - try { - reset(); - fValidator.setFeature(IDC_CHECKING, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - private void checkDefault() { - assertError(DUPLICATE_UNIQUE); - assertError(DUPLICATE_KEY); - assertError(INVALID_KEYREF); - - assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("itemList", fRootNode.getElementDeclaration() - .getName()); - assertTypeName("itemListType", fRootNode.getTypeDefinition().getName()); - - // this one is valid because it's the first one to define the unique - // value - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("item", child.getElementDeclaration().getName()); - assertTypeName("itemType", child.getTypeDefinition().getName()); - - // invalid because it repeats the unique value - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("item", child.getElementDeclaration().getName()); - assertTypeName("itemType", child.getTypeDefinition().getName()); - - // invalid because it repeats the key - child = super.getChild(3); - assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("item", child.getElementDeclaration().getName()); - assertTypeName("itemType", child.getTypeDefinition().getName()); - - // valid because key references aren't figured out until the validation - // root - child = super.getChild(4); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("itemRef", child.getElementDeclaration().getName()); - assertTypeName("string", child.getTypeDefinition().getName()); - } - - private void checkValidResult() { - assertNoError(DUPLICATE_UNIQUE); - assertNoError(DUPLICATE_KEY); - assertNoError(INVALID_KEYREF); - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("itemList", fRootNode.getElementDeclaration() - .getName()); - assertTypeName("itemListType", fRootNode.getTypeDefinition().getName()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("item", child.getElementDeclaration().getName()); - assertTypeName("itemType", child.getTypeDefinition().getName()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("item", child.getElementDeclaration().getName()); - assertTypeName("itemType", child.getTypeDefinition().getName()); - - child = super.getChild(3); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("item", child.getElementDeclaration().getName()); - assertTypeName("itemType", child.getTypeDefinition().getName()); - - child = super.getChild(4); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("itemRef", child.getElementDeclaration().getName()); - assertTypeName("string", child.getTypeDefinition().getName()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_A_A.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_A_A.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IgnoreXSITypeTest_A_A extends BaseTest { - - protected String getXMLDocument() { - return "xsitype_A_A.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public IgnoreXSITypeTest_A_A(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultDocument() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testDefaultFragment() { - try { - reset(); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testSetFalseDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetFalseFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetTrueDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - @Test - public void testSetTrueFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - private void checkTrueResult() { - checkResult(); - } - - private void checkFalseResult() { - checkResult(); - } - - private void checkResult() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_A_C.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_A_C.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IgnoreXSITypeTest_A_C extends BaseTest { - - protected String getXMLDocument() { - return "xsitype_A_C.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public IgnoreXSITypeTest_A_C(String name) { - super(name); - } - - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultDocument() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testDefaultFragment() { - try { - reset(); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testSetFalseDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetFalseFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetTrueDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - @Test - public void testSetTrueFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - private void checkTrueResult() { - checkResult(); - } - - private void checkFalseResult() { - checkResult(); - } - - private void checkResult() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_A.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_A.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IgnoreXSITypeTest_C_A extends BaseTest { - - protected String getXMLDocument() { - return "xsitype_C_A.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public IgnoreXSITypeTest_C_A(String name) { - super(name); - } - - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultDocument() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testDefaultFragment() { - try { - reset(); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testSetFalseDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetFalseFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetTrueDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - @Test - public void testSetTrueFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - private void checkTrueResult() { - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertAnyType(fRootNode.getTypeDefinition()); - - checkChild(); - } - - private void checkFalseResult() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - - checkChild(); - } - - private void checkChild() { - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_AC.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_AC.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IgnoreXSITypeTest_C_AC extends BaseTest { - - protected String getXMLDocument() { - return "xsitype_C_AC.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public IgnoreXSITypeTest_C_AC(String name) { - super(name); - } - - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultDocument() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testDefaultFragment() { - try { - reset(); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testSetFalseDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetFalseFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetTrueDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - @Test - public void testSetTrueFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - private void checkTrueResult() { - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertAnyType(fRootNode.getTypeDefinition()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertAnyType(child.getTypeDefinition()); - } - - private void checkFalseResult() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_C.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_C.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IgnoreXSITypeTest_C_C extends BaseTest { - - protected String getXMLDocument() { - return "xsitype_C_C.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public IgnoreXSITypeTest_C_C(String name) { - super(name); - } - - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultDocument() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testDefaultFragment() { - try { - reset(); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testSetFalseDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetFalseFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetTrueDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - @Test - public void testSetTrueFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - private void checkTrueResult() { - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_NONE, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertAnyType(fRootNode.getTypeDefinition()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertAnyType(child.getTypeDefinition()); - } - - private void checkFalseResult() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_CA.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_CA.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class IgnoreXSITypeTest_C_CA extends BaseTest { - - protected String getXMLDocument() { - return "xsitype_C_CA.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - public IgnoreXSITypeTest_C_CA(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultDocument() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testDefaultFragment() { - try { - reset(); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - // default value of the feature is false - checkFalseResult(); - } - - @Test - public void testSetFalseDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetFalseFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, false); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkFalseResult(); - } - - @Test - public void testSetTrueDocument() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - @Test - public void testSetTrueFragment() { - try { - reset(); - fValidator.setFeature(IGNORE_XSI_TYPE, true); - validateFragment(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkTrueResult(); - } - - private void checkTrueResult() { - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertAnyType(fRootNode.getTypeDefinition()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertAnyType(child.getTypeDefinition()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } - - private void checkFalseResult() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); - - PSVIElementNSImpl child = super.getChild(1); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementNull(child.getElementDeclaration()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - - child = super.getChild(2); - assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child - .getValidationAttempted()); - assertElementName("A", child.getElementDeclaration().getName()); - assertTypeName("Y", child.getTypeDefinition().getName()); - assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/RootTypeDefinitionTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/RootTypeDefinitionTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import javax.xml.namespace.QName; -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class RootTypeDefinitionTest extends BaseTest { - private QName unknownType; - - private QName typeX; - - private QName typeY; - - private QName typeZ; - - private QName typeOtherNamespace; - - private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; - - private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; - - protected String getXMLDocument() { - return "base.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - protected String[] getRelevantErrorIDs() { - return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; - } - - public RootTypeDefinitionTest(String name) { - super(name); - unknownType = new QName("W"); - typeX = new QName("X"); - typeY = new QName("Y"); - typeZ = new QName("Z"); - typeOtherNamespace = new QName("xslt.unittests", "W", "unit"); - } - - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefault() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSettingNull() { - try { - reset(); - fValidator.setProperty(ROOT_TYPE, null); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSettingToUnknownType() { - try { - reset(); - fValidator.setProperty(ROOT_TYPE, unknownType); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertError(UNKNOWN_TYPE_ERROR); - checkDefault(); - } - - @Test - public void testSettingToEqualType() { - try { - reset(); - fValidator.setProperty(ROOT_TYPE, typeX); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - } - - @Test - public void testSettingToDerivedType() { - try { - reset(); - // this is required to make it a valid type Y node - ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, "attr", "typeY"); - fValidator.setProperty(ROOT_TYPE, typeY); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - } - - @Test - public void testSettingToNonDerivedType() { - try { - reset(); - fValidator.setProperty(ROOT_TYPE, typeZ); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Z", fRootNode.getTypeDefinition().getName()); - } - - @Test - public void testSettingToOtherSchemaType() { - try { - reset(); - ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI, - SchemaSymbols.XSI_SCHEMALOCATION, - "xslt.unittests otherNamespace.xsd"); - fValidator.setProperty(ROOT_TYPE, typeOtherNamespace); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("W", fRootNode.getTypeDefinition().getName()); - assertTypeNamespace("xslt.unittests", fRootNode.getTypeDefinition() - .getNamespace()); - } - - @Test - public void testSettingTypeAndXSIType() { - try { - reset(); - // this is required to make it a valid type Y node - ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, "attr", "typeY"); - ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI, - SchemaSymbols.XSI_TYPE, "Y"); - fValidator.setProperty(ROOT_TYPE, typeX); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Y", fRootNode.getTypeDefinition().getName()); - } - - @Test - public void testSettingTypeAndInvalidXSIType() { - try { - reset(); - ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI, - SchemaSymbols.XSI_TYPE, "Z"); - fValidator.setProperty(ROOT_TYPE, typeX); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertError(INVALID_DERIVATION_ERROR); - assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertTypeName("Z", fRootNode.getTypeDefinition().getName()); - } - - private void checkDefault() { - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/SpecialCaseErrorHandler.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/SpecialCaseErrorHandler.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.HashMap; - -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class SpecialCaseErrorHandler implements ErrorHandler { - public static final boolean DEBUG = false; - - private HashMap errors; - - public SpecialCaseErrorHandler(String[] specialCases) { - errors = new HashMap<>(); - for (int i = 0; i < specialCases.length; ++i) { - errors.put(specialCases[i], Boolean.FALSE); - } - } - - public void reset() { - errors.keySet().stream().forEach((error) -> { - errors.put(error, Boolean.FALSE); - }); - } - - @Override - public void warning(SAXParseException arg0) throws SAXException { - if (DEBUG) { - System.err.println(arg0.getMessage()); - } - } - - @Override - public void error(SAXParseException arg0) throws SAXException { - if (DEBUG) { - System.err.println(arg0.getMessage()); - } - errors.keySet().stream().filter((error) -> (arg0.getMessage().startsWith(error))).forEach((error) -> { - errors.put(error, Boolean.TRUE); - }); - } - - public void fatalError(SAXParseException arg0) throws SAXException { - throw arg0; - } - - public boolean specialCaseFound(String key) { - return ((Boolean) errors.get(key)).booleanValue(); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/TEST.properties --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/TEST.properties Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -# This file identifies root(s) of the test-ng hierarchy. - -TestNG.dirs = . diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/UnparsedEntityCheckingTest.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/UnparsedEntityCheckingTest.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class UnparsedEntityCheckingTest extends BaseTest { - public static final String UNDECLARED_ENTITY = "UndeclaredEntity"; - - protected String getXMLDocument() { - return "unparsedEntity.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - protected String[] getRelevantErrorIDs() { - return new String[] { UNDECLARED_ENTITY }; - } - - public UnparsedEntityCheckingTest(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test - public void testDefaultValid() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSetFalseValid() { - try { - reset(); - fValidator.setFeature(UNPARSED_ENTITY_CHECKING, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSetTrueValid() { - try { - reset(); - fValidator.setFeature(UNPARSED_ENTITY_CHECKING, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testDefaultInvalid() { - try { - reset(); - ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, - "unparsedEntityAttr", "invalid"); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkInvalid(); - } - - @Test - public void testSetFalseInvalid() { - try { - reset(); - ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, - "unparsedEntityAttr", "invalid"); - fValidator.setFeature(UNPARSED_ENTITY_CHECKING, false); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkDefault(); - } - - @Test - public void testSetTrueInvalid() { - try { - reset(); - ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, - "unparsedEntityAttr", "invalid"); - fValidator.setFeature(UNPARSED_ENTITY_CHECKING, true); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - checkInvalid(); - } - - private void checkDefault() { - assertNoError(UNDECLARED_ENTITY); - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - } - - private void checkInvalid() { - assertError(UNDECLARED_ENTITY); - assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertTypeName("X", fRootNode.getTypeDefinition().getName()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/UseGrammarPoolOnlyTest_False.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/UseGrammarPoolOnlyTest_False.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class UseGrammarPoolOnlyTest_False extends BaseTest { - private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; - - private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; - - protected String getXMLDocument() { - return "otherNamespace.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - protected String[] getRelevantErrorIDs() { - return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; - } - - protected boolean getUseGrammarPoolOnly() { - return false; - } - - public UseGrammarPoolOnlyTest_False(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - /** - * The purpose of this test is to check if setting the USE_GRAMMAR_POOL_ONLY - * feature to true causes external schemas to not be read. This - * functionality already existed prior to adding the XSLT 2.0 validation - * features; however, because the class that controlled it changed, this - * test simply ensures that the existing functionality did not disappear. - * -PM - */ - @Test - public void testUsingOnlyGrammarPool() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode - .getValidationAttempted()); - assertElementName("A", fRootNode.getElementDeclaration().getName()); - assertElementNamespace("xslt.unittests", fRootNode - .getElementDeclaration().getNamespace()); - assertTypeName("W", fRootNode.getTypeDefinition().getName()); - assertTypeNamespace("xslt.unittests", fRootNode.getTypeDefinition() - .getNamespace()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/UseGrammarPoolOnlyTest_True.java --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/UseGrammarPoolOnlyTest_True.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.sun.org.apache.xerces.internal.xs.ItemPSVI; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class UseGrammarPoolOnlyTest_True extends BaseTest { - - protected String getXMLDocument() { - return "otherNamespace.xml"; - } - - protected String getSchemaFile() { - return "base.xsd"; - } - - protected boolean getUseGrammarPoolOnly() { - return true; - } - - public UseGrammarPoolOnlyTest_True(String name) { - super(name); - } - - @BeforeClass - protected void setUp() throws Exception { - super.setUp(); - } - - @AfterClass - protected void tearDown() throws Exception { - super.tearDown(); - } - - /** - * The purpose of this test is to check if setting the USE_GRAMMAR_POOL_ONLY - * feature to true causes external schemas to not be read. This - * functionality already existed prior to adding the XSLT 2.0 validation - * features; however, because the class that controlled it changed, this - * test simply ensures that the existing functionality did not disappear. - * -PM - */ - @Test - public void testUsingOnlyGrammarPool() { - try { - reset(); - validateDocument(); - } catch (Exception e) { - fail("Validation failed: " + e.getMessage()); - } - - assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); - assertValidationAttempted(ItemPSVI.VALIDATION_NONE, fRootNode - .getValidationAttempted()); - assertElementNull(fRootNode.getElementDeclaration()); - assertAnyType(fRootNode.getTypeDefinition()); - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/base.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/base.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/base.xsd --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/base.xsd Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/fixedAttr.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/fixedAttr.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ - - - howdy - hey - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/idIdref.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/idIdref.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/idc.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/idc.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ - - - 1 - 2 - 2 - 3 - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/idc.xsd --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/idc.xsd Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/otherNamespace.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/otherNamespace.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/otherNamespace.xsd --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/otherNamespace.xsd Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/unparsedEntity.dtd --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/unparsedEntity.dtd Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/unparsedEntity.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/unparsedEntity.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_A_A.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_A_A.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_A_C.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_A_C.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_A.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_A.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_AC.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_AC.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ - - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_C.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_C.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_CA.xml --- a/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_CA.xml Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ - - - - - diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/BaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/BaseTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,326 @@ +package validation; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.URL; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; +import com.sun.org.apache.xerces.internal.xs.ElementPSVI; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; +import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; +import java.security.Policy; +import javax.xml.transform.stream.StreamSource; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +public abstract class BaseTest { + protected final static String ROOT_TYPE = Constants.XERCES_PROPERTY_PREFIX + + Constants.ROOT_TYPE_DEFINITION_PROPERTY; + + protected final static String IGNORE_XSI_TYPE = Constants.XERCES_FEATURE_PREFIX + + Constants.IGNORE_XSI_TYPE_FEATURE; + + protected final static String ID_IDREF_CHECKING = Constants.XERCES_FEATURE_PREFIX + + Constants.ID_IDREF_CHECKING_FEATURE; + + protected final static String IDC_CHECKING = Constants.XERCES_FEATURE_PREFIX + + Constants.IDC_CHECKING_FEATURE; + + protected final static String UNPARSED_ENTITY_CHECKING = Constants.XERCES_FEATURE_PREFIX + + Constants.UNPARSED_ENTITY_CHECKING_FEATURE; + + protected final static String USE_GRAMMAR_POOL_ONLY = Constants.XERCES_FEATURE_PREFIX + + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE; + + protected final static String DYNAMIC_VALIDATION = Constants.XERCES_FEATURE_PREFIX + + Constants.DYNAMIC_VALIDATION_FEATURE; + + protected final static String DOCUMENT_CLASS_NAME = Constants.XERCES_PROPERTY_PREFIX + + Constants.DOCUMENT_CLASS_NAME_PROPERTY; + + public static boolean isWindows = false; + static { + if (System.getProperty("os.name").indexOf("Windows")>-1) { + isWindows = true; + } + }; + + protected Schema schema; + protected Validator fValidator; + + protected SpecialCaseErrorHandler fErrorHandler; + + protected DocumentBuilder builder; + protected Document fDocument; + + protected ElementPSVI fRootNode; + protected URL fDocumentURL; + protected URL fSchemaURL; + + static String errMessage; + + int passed = 0, failed = 0; + private boolean hasSM; + private Policy orig; + + protected abstract String getSchemaFile(); + + protected abstract String getXMLDocument(); + + public BaseTest(String name) { + fErrorHandler = new SpecialCaseErrorHandler(getRelevantErrorIDs()); + } + + protected void setUp() throws Exception { + if (System.getSecurityManager() != null) { + hasSM = true; + System.setSecurityManager(null); + } + + orig = Policy.getPolicy(); + + DocumentBuilderFactory docFactory = DocumentBuilderFactory + .newInstance(); + docFactory.setAttribute(DOCUMENT_CLASS_NAME, + "com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl"); + docFactory.setNamespaceAware(true); + builder = docFactory.newDocumentBuilder(); + // build the location URL of the document + String filepath = System.getProperty("test.src", "."); + String packageDir = this.getClass().getPackage().getName().replace('.', + '/'); + String documentPath = filepath + "/" + packageDir + "/" + getXMLDocument(); + String schemaPath = filepath + "/" + packageDir + "/" + getSchemaFile(); + + if (isWindows) { + fDocumentURL = new URL("file:/" + documentPath); + fSchemaURL = new URL("file:/" + schemaPath); + } else { + fDocumentURL = new URL("file:" + documentPath); + fSchemaURL = new URL("file:" + schemaPath); + } + if (fDocumentURL == null) { + throw new FileNotFoundException("Couldn't find xml file for test: " + documentPath); + } + + SchemaFactory sf = SchemaFactory + .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + sf.setFeature(USE_GRAMMAR_POOL_ONLY, getUseGrammarPoolOnly()); + + if (fSchemaURL == null) { + throw new FileNotFoundException("Couldn't find schema file for test: " + schemaPath); + } + schema = sf.newSchema(fSchemaURL); + +// String schemaPath = "./jaxp-ri/src/unit-test/apache/xerces/jdk8037819/" + getSchemaFile(); +// Schema schema = sf.newSchema(new StreamSource(new File(schemaPath))); + } + + protected void tearDown() throws Exception { + System.setSecurityManager(null); + Policy.setPolicy(orig); + if (hasSM) { + System.setSecurityManager(new SecurityManager()); + } + + builder = null; + schema = null; + fRootNode = null; + fErrorHandler.reset(); + System.out.println("\nNumber of tests passed: " + passed); + System.out.println("Number of tests failed: " + failed + "\n"); + + if (errMessage != null) { + throw new RuntimeException(errMessage); + } + } + + protected void validateDocument() throws Exception { + Source source = new DOMSource(fDocument); + source.setSystemId(fDocumentURL.toExternalForm()); + Result result = new DOMResult(fDocument); + + fValidator.validate(source, result); + } + + protected void validateFragment() throws Exception { + Source source = new DOMSource((Node) fRootNode); + source.setSystemId(fDocumentURL.toExternalForm()); + Result result = new DOMResult((Node) fRootNode); + fValidator.validate(source, result); + } + + protected void reset() throws Exception { +// fDocument = builder.parse(new File("./jaxp-ri/src/unit-test/apache/xerces/jdk8037819/" + getXMLDocument())); + fDocument = builder.parse(fDocumentURL.toExternalForm()); + fRootNode = (ElementPSVI) fDocument.getDocumentElement(); + fValidator = schema.newValidator(); + fErrorHandler.reset(); + fValidator.setErrorHandler(fErrorHandler); + fValidator.setFeature(DYNAMIC_VALIDATION, false); + } + + protected PSVIElementNSImpl getChild(int n) { + int numFound = 0; + Node child = ((Node) fRootNode).getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + numFound++; + if (numFound == n) { + return (PSVIElementNSImpl) child; + } + } + child = child.getNextSibling(); + } + return null; + } + + protected String[] getRelevantErrorIDs() { + return new String[] {}; + } + + protected boolean getUseGrammarPoolOnly() { + return false; + } + + // specialized asserts + + protected void assertValidity(short expectedValidity, short actualValidity) { + String expectedString = expectedValidity == ItemPSVI.VALIDITY_VALID ? "valid" + : (expectedValidity == ItemPSVI.VALIDITY_INVALID ? "invalid" + : "notKnown"); + String actualString = actualValidity == ItemPSVI.VALIDITY_VALID ? "valid" + : (actualValidity == ItemPSVI.VALIDITY_INVALID ? "invalid" + : "notKnown"); + String message = "{validity} was <" + actualString + + "> but it should have been <" + expectedString + ">"; + assertEquals(message, expectedValidity, actualValidity); + } + + protected void assertValidationAttempted(short expectedAttempted, + short actualAttempted) { + String expectedString = expectedAttempted == ItemPSVI.VALIDATION_FULL ? "full" + : (expectedAttempted == ItemPSVI.VALIDATION_PARTIAL ? "partial" + : "none"); + String actualString = actualAttempted == ItemPSVI.VALIDATION_FULL ? "full" + : (actualAttempted == ItemPSVI.VALIDATION_PARTIAL ? "partial" + : "none"); + String message = "{validity} was <" + actualString + + "> but it should have been <" + expectedString + ">"; + assertEquals(message, expectedAttempted, actualAttempted); + } + + protected void assertElementName(String expectedName, String actualName) { + assertEquals("Local name of element declaration is wrong.", + expectedName, actualName); + } + + protected void assertElementNull(XSElementDeclaration elem) { + assertNull("Element declaration should be null.", elem); + } + + protected void assertElementNamespace(String expectedName, String actualName) { + assertEquals("Namespace of element declaration is wrong.", + expectedName, actualName); + } + + protected void assertElementNamespaceNull(String actualName) { + assertNull("Local name of element declaration should be null.", + actualName); + } + + protected void assertTypeName(String expectedName, String actualName) { + assertEquals("Local name of type definition is wrong.", expectedName, + actualName); + } + + protected void assertTypeNull(XSTypeDefinition type) { + assertNull("Type definition should be null.", type); + } + + protected void assertTypeNamespace(String expectedName, String actualName) { + assertEquals("Namespace of type definition is wrong.", expectedName, + actualName); + } + + protected void assertTypeNamespaceNull(String actualName) { + assertNull("Namespace of type definition should be null.", actualName); + } + + protected void assertError(String error) { + assertTrue("Error <" + error + "> should have occured, but did not.", + fErrorHandler.specialCaseFound(error)); + } + + protected void assertNoError(String error) { + assertFalse("Error <" + error + + "> should not have occured (but it did)", fErrorHandler + .specialCaseFound(error)); + } + + protected void assertAnyType(XSTypeDefinition type) { + assertEquals("Type is supposed to be anyType", SchemaGrammar.fAnyType, + type); + } + + void assertEquals(String msg, Object expected, Object actual) { + if (!expected.equals(actual)) { + fail(msg + " Expected: " + expected + " Actual: " + actual); + } else { + success(null); + } + } + void assertNull(String msg, Object value) { + if (value != null) { + fail(msg); + } else { + success(null); + } + } + public void assertTrue(String msg, boolean value) { + if (!value) { + fail(msg); + } else { + success(null); + } + } + public void assertFalse(String msg, boolean value) { + if (value) { + fail(msg); + } else { + success(null); + } + } + public void fail(String errMsg) { + if (errMessage == null) { + errMessage = errMsg; + } else { + errMessage = errMessage + "\n" + errMsg; + } + failed++; + } + + public void success(String msg) { + passed++; + if (msg != null) { + if (msg.length() != 0) { + System.out.println(msg); + } + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/SpecialCaseErrorHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/SpecialCaseErrorHandler.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,54 @@ +package validation; + +import java.util.HashMap; +import java.util.Iterator; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class SpecialCaseErrorHandler implements ErrorHandler { + public static final boolean DEBUG = false; + + private HashMap errors; + + public SpecialCaseErrorHandler(String[] specialCases) { + errors = new HashMap(); + for (int i = 0; i < specialCases.length; ++i) { + errors.put(specialCases[i], Boolean.FALSE); + } + } + + public void reset() { + for (Iterator iter = errors.keySet().iterator(); iter.hasNext();) { + String error = (String) iter.next(); + errors.put(error, Boolean.FALSE); + } + } + + public void warning(SAXParseException arg0) throws SAXException { + if (DEBUG) { + System.err.println(arg0.getMessage()); + } + } + + public void error(SAXParseException arg0) throws SAXException { + if (DEBUG) { + System.err.println(arg0.getMessage()); + } + for (Iterator iter = errors.keySet().iterator(); iter.hasNext();) { + String error = (String) iter.next(); + if (arg0.getMessage().startsWith(error)) { + errors.put(error, Boolean.TRUE); + } + } + } + + public void fatalError(SAXParseException arg0) throws SAXException { + throw arg0; + } + + public boolean specialCaseFound(String key) { + return ((Boolean) errors.get(key)).booleanValue(); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/filelist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/filelist Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,1 @@ +jdk8037819/BasicTest1.java diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/FeaturePropagationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/FeaturePropagationTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,196 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8036951; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.URL; +import javax.xml.XMLConstants; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import validation.BaseTest; + +/** + * @author Peter McCracken, IBM + * @version $Id$ + */ +public class FeaturePropagationTest extends BaseTest { + + public final String FEATURE_STRING_DEFAULT_FALSE = "http://apache.org/xml/features/honour-all-schemaLocations"; + public final String FEATURE_STRING_DEFAULT_TRUE = "http://apache.org/xml/features/validation/schema-full-checking"; + public final String SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager"; + + public FeaturePropagationTest(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testPropertyReset() throws Exception { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = makeSchema(factory, null); + Validator validator = schema.newValidator(); + Object beforeReset = validator.getProperty(SECURITY_MANAGER); + validator.setProperty(SECURITY_MANAGER, null); + Object changed = validator.getProperty(SECURITY_MANAGER); + //for JDK, this is changed since by default the security manager is set + assertTrue("Property value should have changed after calling setProperty().", beforeReset != changed); + validator.reset(); + Object afterReset = validator.getProperty(SECURITY_MANAGER); + assertTrue("Property value should be the same after calling reset()", beforeReset == afterReset); + } + + @Test + public void testFeatureReset() throws Exception { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = makeSchema(factory, null); + Validator validator = schema.newValidator(); + validator.setFeature(FEATURE_STRING_DEFAULT_TRUE, false); + validator.setFeature(FEATURE_STRING_DEFAULT_FALSE, true); + validator.reset(); + boolean value = validator.getFeature(FEATURE_STRING_DEFAULT_TRUE); + assertTrue("After reset, value of feature on Validator should be true.", value); + value = validator.getFeature(FEATURE_STRING_DEFAULT_FALSE); + assertFalse("After reset, value of feature on Validator should be false.", value); + } + + @Test + public void testSecureProcessingFeaturePropagationAndReset() throws Exception { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + boolean value; + value = factory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); + //default is true for JDK + //assertFalse("Default value of feature on SchemaFactory should have been false.", value); + assertTrue("Default value of feature on SchemaFactory should have been false.", value); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + Schema schema = makeSchema(factory, null); + Validator validator = schema.newValidator(); + value = validator.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); + assertTrue("Value of feature on Validator should have been true.", value); + validator.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); + value = validator.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); + assertFalse("Value of feature on Validator should have been false.", value); + validator.reset(); + value = validator.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); + assertTrue("After reset, value of feature on Validator should be true.", value); + } + /* + * Using four basically identical tests to try out the different + * instance classes of Schema. They shouldn't differ, because the relevant + * code is in a common base class. + */ + + @Test + public void testFeaturePropagationNull() throws Exception { + checkFeaturesOnValidator(null); + } + + @Test + public void testFeaturePropagationEmpty() throws Exception { + checkFeaturesOnValidator(new Source[] {}); + } + + @Test + public void testFeaturePropagationSingle() throws Exception { + checkFeaturesOnValidator(new Source[] {makeSource("base.xsd")}); + } + + @Test + public void testFeaturePropagationMultiple() throws Exception { + checkFeaturesOnValidator(new Source[] {makeSource("base.xsd"), makeSource("idc.xsd")}); + } + + private void checkFeaturesOnValidator(Source[] sources) throws Exception { + try { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = makeSchema(factory, sources); + Validator validator = schema.newValidator(); + boolean value; + value = validator.getFeature(FEATURE_STRING_DEFAULT_TRUE); + assertTrue("Default value of feature on Validator should have been true.", value); + value = validator.getFeature(FEATURE_STRING_DEFAULT_FALSE); + assertFalse("Default value of feature on Validator should have been false.", value); + + // checking that the value propagates to the validator + factory.setFeature(FEATURE_STRING_DEFAULT_TRUE, false); + factory.setFeature(FEATURE_STRING_DEFAULT_FALSE, true); + schema = makeSchema(factory, sources); + validator = schema.newValidator(); + value = validator.getFeature(FEATURE_STRING_DEFAULT_TRUE); + assertFalse("Value of feature on Validator should have been false.", value); + value = validator.getFeature(FEATURE_STRING_DEFAULT_FALSE); + assertTrue("Value of feature on Validator should have been true.", value); + + // checking that the validator contains a copy of the features, not a reference + factory.setFeature(FEATURE_STRING_DEFAULT_TRUE, true); + factory.setFeature(FEATURE_STRING_DEFAULT_FALSE, false); + value = validator.getFeature(FEATURE_STRING_DEFAULT_TRUE); + assertFalse("Value of feature on Validator should have stayed false.", value); + value = validator.getFeature(FEATURE_STRING_DEFAULT_FALSE); + assertTrue("Value of feature on Validator should have stayed true.", value); + } + catch (SAXNotRecognizedException e) { + fail(e.getMessage()); + } + catch (SAXNotSupportedException e) { + fail(e.getMessage()); + } + } + + private Schema makeSchema(SchemaFactory factory, Source[] sources) throws SAXException { + if (sources == null) { + return factory.newSchema(); + } + else { + return factory.newSchema(sources); + } + } + + private Source makeSource(String xsd) throws FileNotFoundException { + return new StreamSource(fSchemaURL.toExternalForm()); + } + + @Override + protected String getSchemaFile() { + return "base.xsd"; + } + + @Override + protected String getXMLDocument() { + //not needed + return null; + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/RootSimpleTypeDefinitionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/RootSimpleTypeDefinitionTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8036951; + +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.xml.sax.SAXException; +import validation.BaseTest; + +/** + * @author Peter McCracken, IBM + * @version $Id$ + */ +public class RootSimpleTypeDefinitionTest extends BaseTest { + + private QName typeString; + private QName typeNonNegInt; + + private final static String INVALID_TYPE_ERROR = "cvc-type.3.1.3"; + private final static String MININCLUSIVE_DERIVATION_ERROR = "cvc-minInclusive-valid"; + + protected String getXMLDocument() { + return "simpleType.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { INVALID_TYPE_ERROR, MININCLUSIVE_DERIVATION_ERROR }; + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + public RootSimpleTypeDefinitionTest(String name) { + super(name); + // This is a roundabout way of making sure that we're not using an + // interned string (so that == doesn't work) + String ns = "x" + XMLConstants.W3C_XML_SCHEMA_NS_URI; + ns = ns.substring(1); + typeString = new QName(ns, "string", "xsd"); + typeNonNegInt = new QName(ns, "nonNegativeInteger", "xsd"); + } + + @Test + public void testSettingSimpleType() throws Exception { + try { + reset(); + fValidator.setProperty(ROOT_TYPE, typeString); + } catch (SAXException e1) { + fail("Problem setting property: " + e1.getMessage()); + } + + try { + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("string", fRootNode.getTypeDefinition().getName()); + } + + @Test + public void testSettingInvalidSimpleType() throws Exception { + try { + reset(); + fValidator.setProperty(ROOT_TYPE, typeNonNegInt); + } catch (SAXException e1) { + fail("Problem setting property: " + e1.getMessage()); + } + + try { + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertError(INVALID_TYPE_ERROR); + assertError(MININCLUSIVE_DERIVATION_ERROR); + assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("nonNegativeInteger", fRootNode.getTypeDefinition().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/RootTypeDefinitionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/RootTypeDefinitionTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8036951; + + +import com.sun.org.apache.xerces.internal.xs.ElementPSVI; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.validation.SchemaFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import validation.BaseTest; + +/** + * @author Peter McCracken, IBM + * @version $Id$ + */ +public class RootTypeDefinitionTest extends BaseTest { + + private QName unknownType; + private QName typeX; + private QName typeY; + private QName typeZ; + private QName typeOtherNamespace; + + private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; + + private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + protected String getXMLDocument() { + return "base.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; + } + + public RootTypeDefinitionTest(String name) { + super(name); + unknownType = new QName("W"); + typeX = new QName("X"); + typeY = new QName("Y"); + typeZ = new QName("Z"); + typeOtherNamespace = new QName("xslt.unittests", "W", "unit"); + } + + + /** + * XERCESJ-1141 root-type-definition property not read by XMLSchemaValidator during reset() + */ + @Test + public void testUsingDocumentBuilderFactory() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setAttribute(ROOT_TYPE, typeX); + dbf.setAttribute(DOCUMENT_CLASS_NAME,"com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl"); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + dbf.setSchema(sf.newSchema(fSchemaURL)); + + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(fDocumentURL.toExternalForm()); + ElementPSVI rootNode = (ElementPSVI) document.getDocumentElement(); + + assertValidity(ItemPSVI.VALIDITY_VALID, rootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, rootNode + .getValidationAttempted()); + assertElementNull(rootNode.getElementDeclaration()); + assertTypeName("X", rootNode.getTypeDefinition().getName()); + } + + private void checkDefault() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/Xerces1128doc1Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/Xerces1128doc1Test.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8036951; + + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class Xerces1128doc1Test extends BaseTest { + + private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; + + private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + protected String getXMLDocument() { + return "xerces1128_1.xml"; + } + + protected String getSchemaFile() { + return "xerces1128.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; + } + + public Xerces1128doc1Test(String name) { + super(name); + } + + + /** + * XERCESJ-1128 values for {validation attempted} property in PSVI + */ + @Test + public void testDocument1() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkResult(); + } + + private void checkResult() { + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("anyType", child.getTypeDefinition().getName()); + assertTypeNamespace("http://www.w3.org/2001/XMLSchema", + child.getTypeDefinition().getNamespace()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("X", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/Xerces1128doc2Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/Xerces1128doc2Test.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8036951; + + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class Xerces1128doc2Test extends BaseTest { + + private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; + + private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + protected String getXMLDocument() { + return "xerces1128_2.xml"; + } + + protected String getSchemaFile() { + return "xerces1128.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; + } + + public Xerces1128doc2Test(String name) { + super(name); + } + + + /** + * XERCESJ-1128 values for {validation attempted} property in PSVI + */ + @Test + public void testDocument1() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkResult(); + } + + private void checkResult() { + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("X", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("anyType", child.getTypeDefinition().getName()); + assertTypeNamespace("http://www.w3.org/2001/XMLSchema", + child.getTypeDefinition().getNamespace()); + + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/base.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/base.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,3 @@ + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/base.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/base.xsd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/idc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/idc.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,7 @@ + + + 1 + 2 + 2 + 3 + \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/idc.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/idc.xsd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/simpleType.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/simpleType.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,2 @@ + +-12345 \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/xerces1128.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/xerces1128.xsd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/xerces1128_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/xerces1128_1.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/xerces1128_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8036951/xerces1128_2.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/BasicTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/BasicTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class BasicTest extends BaseTest { + + protected String getXMLDocument() { + return "base.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public BasicTest(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testSimpleValidation() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + doValidityAsserts(); + } + + @Test + public void testSimpleValidationWithTrivialXSIType() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS( + "http://www.w3.org/2001/XMLSchema-instance", "type", "X"); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + doValidityAsserts(); + } + + private void doValidityAsserts() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertElementNamespaceNull(fRootNode.getElementDeclaration() + .getNamespace()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/BasicTest1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/BasicTest1.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,68 @@ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import validation.BaseTest; + +public class BasicTest1 extends BaseTest { + public static void main(String[] args) throws Exception { + BasicTest1 test = new BasicTest1(); + test.setUp(); + test.testSimpleValidation(); + test.testSimpleValidationWithTrivialXSIType(); + test.tearDown(); + } + + protected String getXMLDocument() { + return "base.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public BasicTest1() { + super("BasicTest1"); + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testSimpleValidation() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + doValidityAsserts(); + } + + public void testSimpleValidationWithTrivialXSIType() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS( + "http://www.w3.org/2001/XMLSchema-instance", "type", "X"); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + doValidityAsserts(); + } + + private void doValidityAsserts() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertElementNamespaceNull(fRootNode.getElementDeclaration() + .getNamespace()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/FixedAttrTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/FixedAttrTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +/** + * The purpose of this test is to execute all of the isComparable calls in + * XMLSchemaValidator. There are two calls in processElementContent and two + * calls in processOneAttribute. + * + * @author peterjm + */ +public class FixedAttrTest extends BaseTest { + + protected String getXMLDocument() { + return "fixedAttr.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public FixedAttrTest(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefault() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("B", child.getElementDeclaration().getName()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("D", child.getElementDeclaration().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IdIdrefCheckingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IdIdrefCheckingTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.xml.sax.SAXException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +// duplicate IDs +// reference to non-existent ID + +public class IdIdrefCheckingTest extends BaseTest { + public static final String DUPLICATE_ID = "cvc-id.2"; + + public static final String NO_ID_BINDING = "cvc-id.1"; + + protected String getXMLDocument() { + return "idIdref.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { DUPLICATE_ID, NO_ID_BINDING }; + } + + public IdIdrefCheckingTest(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefault() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSetFalse() { + try { + reset(); + fValidator.setFeature(ID_IDREF_CHECKING, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkValidResult(); + } + + @Test + public void testSetTrue() { + try { + reset(); + fValidator.setFeature(ID_IDREF_CHECKING, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + private void checkDefault() { + assertError(DUPLICATE_ID); + assertError(NO_ID_BINDING); + + assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("idType", child.getTypeDefinition().getName()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("idType", child.getTypeDefinition().getName()); + + child = super.getChild(3); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("idrefType", child.getTypeDefinition().getName()); + } + + private void checkValidResult() { + assertNoError(DUPLICATE_ID); + assertNoError(NO_ID_BINDING); + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("idType", child.getTypeDefinition().getName()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("idType", child.getTypeDefinition().getName()); + + child = super.getChild(3); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("idrefType", child.getTypeDefinition().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IdentityConstraintCheckingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IdentityConstraintCheckingTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.xml.sax.SAXException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IdentityConstraintCheckingTest extends BaseTest { + // These values are unstable, since they're not actually error keys, but + // simply + // the first part of the error message. + public static final String DUPLICATE_UNIQUE = "cvc-identity-constraint.4.1"; + + public static final String DUPLICATE_KEY = "cvc-identity-constraint.4.2.2"; + + public static final String INVALID_KEYREF = "cvc-identity-constraint.4.3"; + + protected String getXMLDocument() { + return "idc.xml"; + } + + protected String getSchemaFile() { + return "idc.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { DUPLICATE_UNIQUE, DUPLICATE_KEY, INVALID_KEYREF }; + } + + public IdentityConstraintCheckingTest(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefault() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSetFalse() { + try { + reset(); + fValidator.setFeature(IDC_CHECKING, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkValidResult(); + } + + @Test + public void testSetTrue() { + try { + reset(); + fValidator.setFeature(IDC_CHECKING, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + private void checkDefault() { + assertError(DUPLICATE_UNIQUE); + assertError(DUPLICATE_KEY); + assertError(INVALID_KEYREF); + + assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("itemList", fRootNode.getElementDeclaration() + .getName()); + assertTypeName("itemListType", fRootNode.getTypeDefinition().getName()); + + // this one is valid because it's the first one to define the unique + // value + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("item", child.getElementDeclaration().getName()); + assertTypeName("itemType", child.getTypeDefinition().getName()); + + // invalid because it repeats the unique value + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("item", child.getElementDeclaration().getName()); + assertTypeName("itemType", child.getTypeDefinition().getName()); + + // invalid because it repeats the key + child = super.getChild(3); + assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("item", child.getElementDeclaration().getName()); + assertTypeName("itemType", child.getTypeDefinition().getName()); + + // valid because key references aren't figured out until the validation + // root + child = super.getChild(4); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("itemRef", child.getElementDeclaration().getName()); + assertTypeName("string", child.getTypeDefinition().getName()); + } + + private void checkValidResult() { + assertNoError(DUPLICATE_UNIQUE); + assertNoError(DUPLICATE_KEY); + assertNoError(INVALID_KEYREF); + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("itemList", fRootNode.getElementDeclaration() + .getName()); + assertTypeName("itemListType", fRootNode.getTypeDefinition().getName()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("item", child.getElementDeclaration().getName()); + assertTypeName("itemType", child.getTypeDefinition().getName()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("item", child.getElementDeclaration().getName()); + assertTypeName("itemType", child.getTypeDefinition().getName()); + + child = super.getChild(3); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("item", child.getElementDeclaration().getName()); + assertTypeName("itemType", child.getTypeDefinition().getName()); + + child = super.getChild(4); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("itemRef", child.getElementDeclaration().getName()); + assertTypeName("string", child.getTypeDefinition().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_A_A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_A_A.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IgnoreXSITypeTest_A_A extends BaseTest { + + protected String getXMLDocument() { + return "xsitype_A_A.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public IgnoreXSITypeTest_A_A(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultDocument() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testDefaultFragment() { + try { + reset(); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testSetFalseDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetFalseFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetTrueDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + @Test + public void testSetTrueFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + private void checkTrueResult() { + checkResult(); + } + + private void checkFalseResult() { + checkResult(); + } + + private void checkResult() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_A_C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_A_C.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IgnoreXSITypeTest_A_C extends BaseTest { + + protected String getXMLDocument() { + return "xsitype_A_C.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public IgnoreXSITypeTest_A_C(String name) { + super(name); + } + + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultDocument() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testDefaultFragment() { + try { + reset(); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testSetFalseDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetFalseFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetTrueDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + @Test + public void testSetTrueFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + private void checkTrueResult() { + checkResult(); + } + + private void checkFalseResult() { + checkResult(); + } + + private void checkResult() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_A.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IgnoreXSITypeTest_C_A extends BaseTest { + + protected String getXMLDocument() { + return "xsitype_C_A.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public IgnoreXSITypeTest_C_A(String name) { + super(name); + } + + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultDocument() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testDefaultFragment() { + try { + reset(); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testSetFalseDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetFalseFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetTrueDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + @Test + public void testSetTrueFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + private void checkTrueResult() { + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertAnyType(fRootNode.getTypeDefinition()); + + checkChild(); + } + + private void checkFalseResult() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + + checkChild(); + } + + private void checkChild() { + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_AC.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_AC.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IgnoreXSITypeTest_C_AC extends BaseTest { + + protected String getXMLDocument() { + return "xsitype_C_AC.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public IgnoreXSITypeTest_C_AC(String name) { + super(name); + } + + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultDocument() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testDefaultFragment() { + try { + reset(); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testSetFalseDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetFalseFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetTrueDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + @Test + public void testSetTrueFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + private void checkTrueResult() { + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertAnyType(fRootNode.getTypeDefinition()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertAnyType(child.getTypeDefinition()); + } + + private void checkFalseResult() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_C.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IgnoreXSITypeTest_C_C extends BaseTest { + + protected String getXMLDocument() { + return "xsitype_C_C.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public IgnoreXSITypeTest_C_C(String name) { + super(name); + } + + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultDocument() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testDefaultFragment() { + try { + reset(); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testSetFalseDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetFalseFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetTrueDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + @Test + public void testSetTrueFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + private void checkTrueResult() { + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertAnyType(fRootNode.getTypeDefinition()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertAnyType(child.getTypeDefinition()); + } + + private void checkFalseResult() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_CA.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/IgnoreXSITypeTest_C_CA.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class IgnoreXSITypeTest_C_CA extends BaseTest { + + protected String getXMLDocument() { + return "xsitype_C_CA.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + public IgnoreXSITypeTest_C_CA(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultDocument() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testDefaultFragment() { + try { + reset(); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + // default value of the feature is false + checkFalseResult(); + } + + @Test + public void testSetFalseDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetFalseFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, false); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkFalseResult(); + } + + @Test + public void testSetTrueDocument() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + @Test + public void testSetTrueFragment() { + try { + reset(); + fValidator.setFeature(IGNORE_XSI_TYPE, true); + validateFragment(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkTrueResult(); + } + + private void checkTrueResult() { + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertAnyType(fRootNode.getTypeDefinition()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertAnyType(child.getTypeDefinition()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } + + private void checkFalseResult() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace()); + + PSVIElementNSImpl child = super.getChild(1); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementNull(child.getElementDeclaration()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + + child = super.getChild(2); + assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child + .getValidationAttempted()); + assertElementName("A", child.getElementDeclaration().getName()); + assertTypeName("Y", child.getTypeDefinition().getName()); + assertTypeNamespaceNull(child.getTypeDefinition().getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/RootTypeDefinitionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/RootTypeDefinitionTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import javax.xml.namespace.QName; +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class RootTypeDefinitionTest extends BaseTest { + private QName unknownType; + + private QName typeX; + + private QName typeY; + + private QName typeZ; + + private QName typeOtherNamespace; + + private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; + + private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; + + protected String getXMLDocument() { + return "base.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; + } + + public RootTypeDefinitionTest(String name) { + super(name); + unknownType = new QName("W"); + typeX = new QName("X"); + typeY = new QName("Y"); + typeZ = new QName("Z"); + typeOtherNamespace = new QName("xslt.unittests", "W", "unit"); + } + + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefault() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSettingNull() { + try { + reset(); + fValidator.setProperty(ROOT_TYPE, null); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSettingToUnknownType() { + try { + reset(); + fValidator.setProperty(ROOT_TYPE, unknownType); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertError(UNKNOWN_TYPE_ERROR); + checkDefault(); + } + + @Test + public void testSettingToEqualType() { + try { + reset(); + fValidator.setProperty(ROOT_TYPE, typeX); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + } + + @Test + public void testSettingToDerivedType() { + try { + reset(); + // this is required to make it a valid type Y node + ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, "attr", "typeY"); + fValidator.setProperty(ROOT_TYPE, typeY); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + } + + @Test + public void testSettingToNonDerivedType() { + try { + reset(); + fValidator.setProperty(ROOT_TYPE, typeZ); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Z", fRootNode.getTypeDefinition().getName()); + } + + @Test + public void testSettingToOtherSchemaType() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI, + SchemaSymbols.XSI_SCHEMALOCATION, + "xslt.unittests otherNamespace.xsd"); + fValidator.setProperty(ROOT_TYPE, typeOtherNamespace); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("W", fRootNode.getTypeDefinition().getName()); + assertTypeNamespace("xslt.unittests", fRootNode.getTypeDefinition() + .getNamespace()); + } + + @Test + public void testSettingTypeAndXSIType() { + try { + reset(); + // this is required to make it a valid type Y node + ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, "attr", "typeY"); + ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI, + SchemaSymbols.XSI_TYPE, "Y"); + fValidator.setProperty(ROOT_TYPE, typeX); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Y", fRootNode.getTypeDefinition().getName()); + } + + @Test + public void testSettingTypeAndInvalidXSIType() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI, + SchemaSymbols.XSI_TYPE, "Z"); + fValidator.setProperty(ROOT_TYPE, typeX); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertError(INVALID_DERIVATION_ERROR); + assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertTypeName("Z", fRootNode.getTypeDefinition().getName()); + } + + private void checkDefault() { + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/UnparsedEntityCheckingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/UnparsedEntityCheckingTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class UnparsedEntityCheckingTest extends BaseTest { + public static final String UNDECLARED_ENTITY = "UndeclaredEntity"; + + protected String getXMLDocument() { + return "unparsedEntity.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { UNDECLARED_ENTITY }; + } + + public UnparsedEntityCheckingTest(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void testDefaultValid() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSetFalseValid() { + try { + reset(); + fValidator.setFeature(UNPARSED_ENTITY_CHECKING, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSetTrueValid() { + try { + reset(); + fValidator.setFeature(UNPARSED_ENTITY_CHECKING, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testDefaultInvalid() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, + "unparsedEntityAttr", "invalid"); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkInvalid(); + } + + @Test + public void testSetFalseInvalid() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, + "unparsedEntityAttr", "invalid"); + fValidator.setFeature(UNPARSED_ENTITY_CHECKING, false); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkDefault(); + } + + @Test + public void testSetTrueInvalid() { + try { + reset(); + ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, + "unparsedEntityAttr", "invalid"); + fValidator.setFeature(UNPARSED_ENTITY_CHECKING, true); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + checkInvalid(); + } + + private void checkDefault() { + assertNoError(UNDECLARED_ENTITY); + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + } + + private void checkInvalid() { + assertError(UNDECLARED_ENTITY); + assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertTypeName("X", fRootNode.getTypeDefinition().getName()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/UseGrammarPoolOnlyTest_False.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/UseGrammarPoolOnlyTest_False.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class UseGrammarPoolOnlyTest_False extends BaseTest { + private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1"; + + private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3"; + + protected String getXMLDocument() { + return "otherNamespace.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected String[] getRelevantErrorIDs() { + return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR }; + } + + protected boolean getUseGrammarPoolOnly() { + return false; + } + + public UseGrammarPoolOnlyTest_False(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * The purpose of this test is to check if setting the USE_GRAMMAR_POOL_ONLY + * feature to true causes external schemas to not be read. This + * functionality already existed prior to adding the XSLT 2.0 validation + * features; however, because the class that controlled it changed, this + * test simply ensures that the existing functionality did not disappear. + * -PM + */ + @Test + public void testUsingOnlyGrammarPool() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode + .getValidationAttempted()); + assertElementName("A", fRootNode.getElementDeclaration().getName()); + assertElementNamespace("xslt.unittests", fRootNode + .getElementDeclaration().getNamespace()); + assertTypeName("W", fRootNode.getTypeDefinition().getName()); + assertTypeNamespace("xslt.unittests", fRootNode.getTypeDefinition() + .getNamespace()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/UseGrammarPoolOnlyTest_True.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/UseGrammarPoolOnlyTest_True.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package validation.jdk8037819; + +import com.sun.org.apache.xerces.internal.xs.ItemPSVI; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import validation.BaseTest; + +public class UseGrammarPoolOnlyTest_True extends BaseTest { + + protected String getXMLDocument() { + return "otherNamespace.xml"; + } + + protected String getSchemaFile() { + return "base.xsd"; + } + + protected boolean getUseGrammarPoolOnly() { + return true; + } + + public UseGrammarPoolOnlyTest_True(String name) { + super(name); + } + + @BeforeClass + protected void setUp() throws Exception { + super.setUp(); + } + + @AfterClass + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * The purpose of this test is to check if setting the USE_GRAMMAR_POOL_ONLY + * feature to true causes external schemas to not be read. This + * functionality already existed prior to adding the XSLT 2.0 validation + * features; however, because the class that controlled it changed, this + * test simply ensures that the existing functionality did not disappear. + * -PM + */ + @Test + public void testUsingOnlyGrammarPool() { + try { + reset(); + validateDocument(); + } catch (Exception e) { + fail("Validation failed: " + e.getMessage()); + } + + assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity()); + assertValidationAttempted(ItemPSVI.VALIDATION_NONE, fRootNode + .getValidationAttempted()); + assertElementNull(fRootNode.getElementDeclaration()); + assertAnyType(fRootNode.getTypeDefinition()); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/base.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/base.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,3 @@ + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/base.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/base.xsd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/fixedAttr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/fixedAttr.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,5 @@ + + + howdy + hey + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/idIdref.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/idIdref.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/idc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/idc.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,7 @@ + + + 1 + 2 + 2 + 3 + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/idc.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/idc.xsd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/otherNamespace.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/otherNamespace.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/otherNamespace.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/otherNamespace.xsd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/unparsedEntity.dtd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/unparsedEntity.dtd Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,2 @@ + + \ No newline at end of file diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/unparsedEntity.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/unparsedEntity.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,4 @@ + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_A_A.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_A_A.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_A_C.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_A_C.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_A.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_A.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_AC.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_AC.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,7 @@ + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_C.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_C.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,6 @@ + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_CA.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/jaxp/testng/validation/jdk8037819/xsitype_C_CA.xml Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,7 @@ + + + + + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8058473 + @summary "Comparison method violates its general contract" when using Clipboard + Ensure that DataFlavorComparator conforms to Comparator contract + @author Anton Nashatyrev + @run main DataFlavorComparatorTest1 +*/ +import sun.datatransfer.DataFlavorUtil; + +import java.awt.datatransfer.DataFlavor; +import java.util.Comparator; + +public class DataFlavorComparatorTest1 { + + public static void main(String[] args) throws Exception { + String[] mimes = new String[] { + "text/plain", + "text/plain; charset=unicode", + "text/plain; charset=cp1251", + "text/plain; charset=unicode; class=java.io.InputStream", + "text/plain; charset=unicode; class=java.io.Serializable", + "text/plain; charset=unicode; class=java.lang.Object", + "text/plain; class=java.lang.String", + "text/plain; class=java.io.Reader", + "text/plain; class=java.lang.Object", + "text/html", + "text/html; charset=unicode", + "text/html; charset=cp1251", + "text/html; charset=unicode; class=java.io.InputStream", + "text/html; charset=unicode; class=java.io.Serializable", + "text/html; charset=unicode; class=java.lang.Object", + "text/html; class=java.lang.String", + "text/html; class=java.io.Reader", + "text/html; class=java.lang.Object", + "text/unknown", + "text/unknown; charset=unicode", + "text/unknown; charset=cp1251", + "text/unknown; charset=unicode; class=java.io.InputStream", + "text/unknown; charset=unicode; class=java.io.Serializable", + "text/unknown; charset=unicode; class=java.lang.Object", + "text/unknown; class=java.lang.String", + "text/unknown; class=java.io.Reader", + "text/unknown; class=java.lang.Object", + "application/unknown; class=java.io.InputStream", + "application/unknown; class=java.lang.Object", + "application/unknown", + "application/x-java-jvm-local-objectref; class=java.io.InputStream", + "application/x-java-jvm-local-objectref; class=java.lang.Object", + "application/x-java-jvm-local-objectref", + "unknown/flavor", + "unknown/flavor; class=java.io.InputStream", + "unknown/flavor; class=java.lang.Object", + }; + + DataFlavor[] flavors = new DataFlavor[mimes.length]; + for (int i = 0; i < flavors.length; i++) { + flavors[i] = new DataFlavor(mimes[i]); + } + + testComparator(DataFlavorUtil.getDataFlavorComparator(), flavors); + + System.out.println("Passed."); + } + + private static void testComparator(Comparator cmp, DataFlavor[] flavs) + throws ClassNotFoundException { + + for (DataFlavor x: flavs) { + for (DataFlavor y: flavs) { + if (Math.signum(cmp.compare(x,y)) != -Math.signum(cmp.compare(y,x))) { + throw new RuntimeException("Antisymmetry violated: " + x + ", " + y); + } + if (cmp.compare(x,y) == 0 && !x.equals(y)) { + throw new RuntimeException("Equals rule violated: " + x + ", " + y); + } + for (DataFlavor z: flavs) { + if (cmp.compare(x,y) == 0) { + if (Math.signum(cmp.compare(x, z)) != Math.signum(cmp.compare(y, z))) { + throw new RuntimeException("Transitivity (1) violated: " + x + ", " + y + ", " + z); + } + } else { + if (Math.signum(cmp.compare(x, y)) == Math.signum(cmp.compare(y, z))) { + if (Math.signum(cmp.compare(x, y)) != Math.signum(cmp.compare(x, z))) { + throw new RuntimeException("Transitivity (2) violated: " + x + ", " + y + ", " + z); + } + } + } + } + } + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/sun/security/krb5/auto/S4U2proxy.java --- a/jdk/test/sun/security/krb5/auto/S4U2proxy.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/sun/security/krb5/auto/S4U2proxy.java Wed Jul 05 20:04:43 2017 +0200 @@ -23,7 +23,7 @@ /* * @test - * @bug 6355584 + * @bug 6355584 8044215 * @summary Introduce constrained Kerberos delegation * @compile -XDignore.symbol.file S4U2proxy.java * @run main/othervm S4U2proxy krb5 @@ -69,6 +69,10 @@ Context p = s.delegated(); p.startAsClient(OneKDC.BACKEND, mech); + + // 8044215: requestCredDeleg is useless and harmless + p.x().requestCredDeleg(true); + b.startAsServer(mech); Context.handshake(p, b); diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/sun/security/tools/keytool/keyalg.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/tools/keytool/keyalg.sh Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,47 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8029659 +# @summary Keytool, print key algorithm of certificate or key entry +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +KS=ks +KEYTOOL="$TESTJAVA/bin/keytool ${TESTTOOLVMOPTS} -keystore ks -storepass changeit -keypass changeit" + +rm $KS 2> /dev/null + +$KEYTOOL -genkeypair -alias ca -dname CN=CA -keyalg EC || exit 1 +$KEYTOOL -genkeypair -alias user -dname CN=User -keyalg RSA -keysize 1024 || exit 2 +$KEYTOOL -certreq -alias user | + $KEYTOOL -gencert -alias ca -rfc -sigalg SHA1withECDSA | + $KEYTOOL -printcert > user.dump || exit 3 + +cat user.dump | grep "Signature algorithm name:" | grep SHA1withECDSA || exit 4 +cat user.dump | grep "Subject Public Key Algorithm:" | grep RSA | grep 1024 || exit 5 + diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/sun/util/logging/SourceClassName.java --- a/jdk/test/sun/util/logging/SourceClassName.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/sun/util/logging/SourceClassName.java Wed Jul 05 20:04:43 2017 +0200 @@ -54,7 +54,8 @@ plog.severe("Log message {0} {1}", (Object[]) params); // create a java.util.logging.Logger - // now java.util.logging.Logger should be created for each platform logger + // now java.util.logging.Logger should be created for each platform + // logger Logger logger = Logger.getLogger("test.log.bar"); logger.log(Level.SEVERE, "Log message {0} {1}", params); @@ -82,6 +83,19 @@ record[i++] = line; if (i == 2) { i = 0; + // check log message + if (!record[1].equals(EXPECTED_LOG)) { + // it can sometime happen that some static initializer + // in the system will log an error message - due to e.g. + // some kind of misconfiguration or system settings. + // For instance - somethink like: + // INFO: currency.properties entry for FR ignored + // because the value format is not recognized. + // instead of failing if we get such an unexpected + // message, we will simply print that out. + System.out.println("*** WARNING: Unexpected log: " + record[1]); + continue; + } count++; // check source class name and method String[] ss = record[0].split("\\s+"); @@ -92,10 +106,6 @@ ss[len-2] + " " + ss[len-1]); } - // check log message - if (!record[1].equals(EXPECTED_LOG)) { - throw new RuntimeException("Unexpected log: " + record[1]); - } } } if (count != 3) { diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/tools/jar/LeadingGarbage.java --- a/jdk/test/tools/jar/LeadingGarbage.java Thu Oct 16 14:55:17 2014 -0700 +++ b/jdk/test/tools/jar/LeadingGarbage.java Wed Jul 05 20:04:43 2017 +0200 @@ -30,7 +30,6 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Paths; -import sun.tools.jar.Main; import jdk.testlibrary.OutputAnalyzer; import jdk.testlibrary.ProcessTools; @@ -54,9 +53,9 @@ final File leadingGarbageZip = new File("leadingGarbage.zip"); void createFile(File f) throws IOException { - OutputStream fos = new FileOutputStream(f); - fos.write(f.getName().getBytes("UTF-8")); - fos.close(); + try (OutputStream fos = new FileOutputStream(f)) { + fos.write(f.getName().getBytes("UTF-8")); + } } void createFiles() throws IOException { @@ -88,8 +87,9 @@ void createZipWithLeadingGarbage() throws Throwable { createNormalZip(); createFile(leadingGarbageZip); - OutputStream fos = new FileOutputStream(leadingGarbageZip, true); - Files.copy(normalZip.toPath(), fos); + try (OutputStream fos = new FileOutputStream(leadingGarbageZip, true)) { + Files.copy(normalZip.toPath(), fos); + } assertTrue(normalZip.length() < leadingGarbageZip.length()); assertTrue(normalZip.delete()); } @@ -111,7 +111,7 @@ a.shouldHaveExitValue(0); StringBuilder expected = new StringBuilder(); for (File file : files) - expected.append(file.getName()).append('\n'); + expected.append(file.getName()).append(System.lineSeparator()); a.stdoutShouldMatch(expected.toString()); a.stderrShouldMatch("\\A\\Z"); } diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/tools/jar/normalize/TestNormal.java --- a/jdk/test/tools/jar/normalize/TestNormal.java Thu Oct 16 14:55:17 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* - * 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 - * @run main/timeout=600 TestNormal - * @bug 8020802 - * @summary Need an ability to create jar files that are invariant to the pack200 packing/unpacking - * @author Alexander Zuev - */ - -import java.io.*; -import java.util.Collections; -import java.util.Properties; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public class TestNormal { - private static String FS = File.separator; - - public static void main(String args[]) throws Exception { - Properties p = System.getProperties(); - String java_home = p.getProperty("test.jdk"); - String dtjar = java_home + File.separator + "lib" - + File.separator + "dt.jar"; - - File folder = new File("dt"); - if (folder.exists()) { - delete(folder); - } - folder.mkdir(); - - try { - extractJar(new JarFile(dtjar), folder); - execJavaCommand(java_home, "jar cnf normalized.jar -C dt ."); - execJavaCommand(java_home, "jar cf original.jar -C dt ."); - execJavaCommand(java_home, "pack200 -r repacked.jar original.jar"); - compareJars(new JarFile("normalized.jar"), new JarFile("repacked.jar")); - } finally { - String[] cleanupList = {"dt", "normalized.jar", "original.jar", "repacked.jar"}; - for (String s : cleanupList) { - delete(new File(s)); - } - } - } - - public static void execJavaCommand(String java_home, String cmd) throws Exception { - Process proc = Runtime.getRuntime().exec(java_home + FS + "bin" + FS + cmd); - String s; - BufferedReader stdInput = - new BufferedReader(new InputStreamReader(proc.getInputStream())); - BufferedReader stdError = - new BufferedReader(new InputStreamReader(proc.getErrorStream())); - while ((s = stdInput.readLine()) != null) { - System.out.println(s); - } - while ((s = stdError.readLine()) != null) { - System.err.println(s); - } - } - - public static void compareJars(JarFile jf1, JarFile jf2) throws Exception { - try { - if (jf1.size() != jf2.size()) { - throw new Exception("Jars " + jf1.getName() + " and " + jf2.getName() - + " have different number of entries"); - } - for (JarEntry elem1 : Collections.list(jf1.entries())) { - JarEntry elem2 = jf2.getJarEntry(elem1.getName()); - if (elem2 == null) { - throw new Exception("Element " + elem1.getName() + " is missing from " + jf2.getName()); - } - if (!elem1.isDirectory() && elem1.getCrc() != elem2.getCrc()) { - throw new Exception("The crc of " + elem1.getName() + " is different."); - } - } - } finally { - jf1.close(); - jf2.close(); - } - } - - public static void extractJar(JarFile jf, File where) throws Exception { - for (JarEntry file : Collections.list(jf.entries())) { - File out = new File(where, file.getName()); - if (file.isDirectory()) { - out.mkdirs(); - continue; - } - File parent = out.getParentFile(); - if (parent != null && !parent.exists()) { - parent.mkdirs(); - } - InputStream is = null; - OutputStream os = null; - try { - is = jf.getInputStream(file); - os = new FileOutputStream(out); - while (is.available() > 0) { - os.write(is.read()); - } - } finally { - if (is != null) { - is.close(); - } - if (os != null) { - os.close(); - } - } - } - } - - static void delete(File f) throws IOException { - if (!f.exists()) { - return; - } - if (f.isDirectory()) { - for (File c : f.listFiles()) { - delete(c); - } - } - if (!f.delete()) { - throw new FileNotFoundException("Failed to delete file: " + f); - } - } -} diff -r d1480cb49283 -r 98b357b2e8a6 jdk/test/tools/pack200/TestNormal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/TestNormal.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,147 @@ +/* + * 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 + * @run main/timeout=600 TestNormal + * @bug 8020802 + * @summary Need an ability to create jar files that are invariant to the pack200 packing/unpacking + * @author Alexander Zuev + */ + +import java.io.*; +import java.util.Collections; +import java.util.Properties; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public class TestNormal { + private static String FS = File.separator; + + public static void main(String args[]) throws Exception { + Properties p = System.getProperties(); + String java_home = p.getProperty("test.jdk"); + File testJar = new File("test.jar"); + Utils.jar("cvf", testJar.getName(), Utils.TEST_CLS_DIR.getAbsolutePath()); + + File folder = new File("testdir"); + if (folder.exists()) { + delete(folder); + } + folder.mkdir(); + + try { + extractJar(new JarFile(testJar), folder); + execJavaCommand(java_home, "jar cnf normalized.jar -C testdir ."); + execJavaCommand(java_home, "jar cf original.jar -C testdir ."); + execJavaCommand(java_home, "pack200 -r repacked.jar original.jar"); + compareJars(new JarFile("normalized.jar"), new JarFile("repacked.jar")); + } finally { + String[] cleanupList = {"testdir", "normalized.jar", "original.jar", "repacked.jar"}; + for (String s : cleanupList) { + delete(new File(s)); + } + } + } + + public static void execJavaCommand(String java_home, String cmd) throws Exception { + Process proc = Runtime.getRuntime().exec(java_home + FS + "bin" + FS + cmd); + String s; + BufferedReader stdInput = + new BufferedReader(new InputStreamReader(proc.getInputStream())); + BufferedReader stdError = + new BufferedReader(new InputStreamReader(proc.getErrorStream())); + while ((s = stdInput.readLine()) != null) { + System.out.println(s); + } + while ((s = stdError.readLine()) != null) { + System.err.println(s); + } + } + + public static void compareJars(JarFile jf1, JarFile jf2) throws Exception { + try { + if (jf1.size() != jf2.size()) { + throw new Exception("Jars " + jf1.getName() + " and " + jf2.getName() + + " have different number of entries"); + } + for (JarEntry elem1 : Collections.list(jf1.entries())) { + JarEntry elem2 = jf2.getJarEntry(elem1.getName()); + if (elem2 == null) { + throw new Exception("Element " + elem1.getName() + " is missing from " + jf2.getName()); + } + if (!elem1.isDirectory() && elem1.getCrc() != elem2.getCrc()) { + throw new Exception("The crc of " + elem1.getName() + " is different."); + } + } + } finally { + jf1.close(); + jf2.close(); + } + } + + public static void extractJar(JarFile jf, File where) throws Exception { + for (JarEntry file : Collections.list(jf.entries())) { + File out = new File(where, file.getName()); + if (file.isDirectory()) { + out.mkdirs(); + continue; + } + File parent = out.getParentFile(); + if (parent != null && !parent.exists()) { + parent.mkdirs(); + } + InputStream is = null; + OutputStream os = null; + try { + is = jf.getInputStream(file); + os = new FileOutputStream(out); + while (is.available() > 0) { + os.write(is.read()); + } + } finally { + if (is != null) { + is.close(); + } + if (os != null) { + os.close(); + } + } + } + } + + static void delete(File f) throws IOException { + if (!f.exists()) { + return; + } + if (f.isDirectory()) { + for (File c : f.listFiles()) { + delete(c); + } + } + if (!f.delete()) { + throw new FileNotFoundException("Failed to delete file: " + f); + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 make/MakeHelpers.gmk --- a/make/MakeHelpers.gmk Thu Oct 16 14:55:17 2014 -0700 +++ b/make/MakeHelpers.gmk Wed Jul 05 20:04:43 2017 +0200 @@ -324,9 +324,10 @@ +($(CD) $$(dir $$(firstword $$(wildcard $$(addsuffix /$$(strip $3)/$$(strip $4)-$$(strip $1).gmk, \ $(MAKE_DIR_LIST))))) \ && $(MAKE) $(MAKE_ARGS) \ - -f $$(strip $4)-$$(strip $1).gmk \ - $$(addprefix -I, $$(wildcard $(MAKE_DIR_LIST) \ - $$(addsuffix /$$(strip $3), $(MAKE_DIR_LIST))))) + -f $$(strip $4)-$$(strip $1).gmk \ + $$(addprefix -I, $$(wildcard $(MAKE_DIR_LIST) \ + $$(addsuffix /$$(strip $3), $(MAKE_DIR_LIST)))) \ + MODULE=$$(strip $1)) endef ################################################################################ diff -r d1480cb49283 -r 98b357b2e8a6 modules.xml --- a/modules.xml Thu Oct 16 14:55:17 2014 -0700 +++ b/modules.xml Wed Jul 05 20:04:43 2017 +0200 @@ -1491,16 +1491,6 @@
- jdk.compact3 - java.compact3 - java.smartcardio - jdk.httpserver - jdk.naming.dns - jdk.naming.rmi - jdk.sctp - jdk.security.auth - - jdk.compiler java.base java.compiler @@ -1735,7 +1725,6 @@ java.base java.desktop java.se - jdk.compact3 jdk.scripting.nashorn diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/.hgignore --- a/nashorn/.hgignore Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/.hgignore Wed Jul 05 20:04:43 2017 +0200 @@ -26,3 +26,5 @@ test/lib/testng.jar test/script/external/* .project +.externalToolBuilders/* +.settings/* diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/.hgtags --- a/nashorn/.hgtags Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/.hgtags Wed Jul 05 20:04:43 2017 +0200 @@ -268,3 +268,4 @@ 62ba20541b948fb98a7036d9f01baa54e95fb6fa jdk9-b32 b374d8910e7f8de2b7ecacee9ae4cad88f23feab jdk9-b33 4ece2dad8c37f520f1ccc1cf84870f362c8eb9d6 jdk9-b34 +63b8da4c958c3bbadfff082c547983f5daa50c0f jdk9-b35 diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/bin/runopt.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/bin/runopt.sh Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,137 @@ +#!/bin/sh +# +# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +########################################################################################### +# This is a helper script to evaluate nashorn with optimistic types +# it produces a flight recording for every run, and uses the best +# known flags for performance for the current configration +########################################################################################### + +# Flags to enable assertions, we need the system assertions too, since +# this script runs Nashorn in the BCP to override any nashorn.jar that might +# reside in your $JAVA_HOME/jre/lib/ext/nashorn.jar +# +ENABLE_ASSERTIONS_FLAGS="-ea -esa" + +# Flags to instrument lambdaform computation, caching, interpretation and compilation +# Default compile threshold for lambdaforms is 30 +# +#LAMBDAFORM_FLAGS="\ +# -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 \ +# -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true \ +# -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true \ +# -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true" + +# Flags to run trusted tests from the Nashorn test suite +# +#TRUSTED_TEST_FLAGS="\ +#-Djava.security.manager \ +#-Djava.security.policy=../build/nashorn.policy -Dnashorn.debug" + +# Testing out new code optimizations using the generic hotspot "new code" parameter +# +#USE_NEW_CODE_FLAGS=-XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode + +# +#-Dnashorn.typeInfo.disabled=false \ +# and for Nashorn options: +# --class-cache-size=0 --persistent-code-cache=false + +# Unique timestamped file name for JFR recordings. For JFR, we also have to +# crank up the stack cutoff depth to 1024, because of ridiculously long lambda form +# stack traces. +# +# It is also recommended that you go into $JAVA_HOME/jre/lib/jfr/default.jfc and +# set the "method-sampling-interval" Normal and Maximum sample time as low as you +# can go (10 ms on most platforms). The default is normally higher. The increased +# sampling overhead is usually negligible for Nashorn runs, but the data is better + +if [ -z $JFR_FILENAME ]; then + JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr" + echo "Using default JFR filename: ${JFR_FILENAME}..." +fi + +# Flight recorder +# +# see above - already in place, copy the flags down here to disable +ENABLE_FLIGHT_RECORDER_FLAGS="\ + -XX:+UnlockCommercialFeatures \ + -XX:+FlightRecorder \ + -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024" + +# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine, +# keeping this flag around for experimental reasons. Replace + with - to switch it off +# +#ENABLE_TYPE_SPECIALIZATION_FLAGS=-XX:+UseTypeSpeculation + +# Same with math intrinsics. They should be enabled by default in 8u20 and 9, so +# this disables them if needed +# +#DISABLE_MATH_INTRINSICS_FLAGS=-XX:-UseMathExactIntrinsics + +# Add timing to time the compilation phases. +#ENABLE_TIME_FLAGS=--log=time + +# Add ShowHiddenFrames to get lambda form internals on the stack traces +#ENABLE_SHOW_HIDDEN_FRAMES_FLAGS=-XX:+ShowHiddenFrames + +# Add print optoassembly to get an asm dump. This requires 1) a debug build, not product, +# That tired compilation is switched off, for C2 only output and that the number of +# compiler threads is set to 1 for determinsm. +# +#PRINT_ASM_FLAGS=-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \ + +# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments) +#TIER_COMPILATION_THRESHOLD_FLAGS=-XX:IncreaseFirstTierCompileThresholdAt=10 + +# Directory where to look for nashorn.jar in a dist folder. The default is "..", assuming +# that we run the script from the make dir +DIR=.. +NASHORN_JAR=$DIR/dist/nashorn.jar + + +# The built Nashorn jar is placed first in the bootclasspath to override the JDK +# nashorn.jar in $JAVA_HOME/jre/lib/ext. Thus, we also need -esa, as assertions in +# nashorn count as system assertions in this configuration + +# Type profiling default level is 111, 222 adds some compile time, but is faster + +$JAVA_HOME/bin/java \ +$ENABLE_ASSERTIONS_FLAGS \ +$LAMBDAFORM_FLAGS \ +$TRUSTED_FLAGS \ +$USE_NEW_CODE_FLAGS \ +$ENABLE_SHOW_HIDDEN_FRAMES_FLAGS \ +$ENABLE_FLIGHT_RECORDER_FLAGS \ +$ENABLE_TYPE_SPECIALIZATION_FLAGS \ +$TIERED_COMPILATION_THRESOLD_FLAGS \ +$DISABLE_MATH_INTRINSICS_FLAGS \ +$PRINT_ASM_FLAGS \ +-Xbootclasspath/p:$NASHORN_JAR \ +-Xms2G -Xmx2G \ +-XX:TypeProfileLevel=222 \ +-cp $CLASSPATH:../build/test/classes/ \ +jdk.nashorn.tools.Shell $ENABLE_TIME_FLAGS ${@} + + diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/make/build.xml --- a/nashorn/make/build.xml Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/make/build.xml Wed Jul 05 20:04:43 2017 +0200 @@ -408,7 +408,7 @@ - @@ -431,7 +431,7 @@ - @@ -457,9 +457,11 @@ + + @@ -467,9 +469,11 @@ + + diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Jul 05 20:04:43 2017 +0200 @@ -229,6 +229,8 @@ } private T getInterfaceInner(final Object thiz, final Class clazz) { + assert !(thiz instanceof ScriptObject) : "raw ScriptObject not expected here"; + if (clazz == null || !clazz.isInterface()) { throw new IllegalArgumentException(getMessage("interface.class.expected")); } @@ -254,17 +256,6 @@ if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } - } else if (thiz instanceof ScriptObject) { - // called from script code. - realSelf = (ScriptObject)thiz; - realGlobal = Context.getGlobal(); - if (realGlobal == null) { - throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); - } - - if (! isOfContext(realGlobal, nashornContext)) { - throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); - } } if (realSelf == null) { @@ -368,6 +359,7 @@ private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException { name.getClass(); // null check + assert !(selfObject instanceof ScriptObject) : "raw ScriptObject not expected here"; Global invokeGlobal = null; ScriptObjectMirror selfMirror = null; @@ -377,20 +369,6 @@ throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } invokeGlobal = selfMirror.getHomeGlobal(); - } else if (selfObject instanceof ScriptObject) { - // invokeMethod called from script code - in which case we may get 'naked' ScriptObject - // Wrap it with oldGlobal to make a ScriptObjectMirror for the same. - final Global oldGlobal = Context.getGlobal(); - invokeGlobal = oldGlobal; - if (oldGlobal == null) { - throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); - } - - if (! isOfContext(oldGlobal, nashornContext)) { - throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); - } - - selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal); } else if (selfObject == null) { // selfObject is null => global function call final Global ctxtGlobal = getNashornGlobalFrom(context); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java Wed Jul 05 20:04:43 2017 +0200 @@ -25,8 +25,6 @@ package jdk.nashorn.api.scripting; -import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; - import java.lang.invoke.MethodHandle; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.linker.LinkerServices; @@ -75,11 +73,8 @@ * @param sync the object to synchronize on * @return a synchronizing wrapper function */ - public static Object makeSynchronizedFunction(final Object func, final Object sync) { - if (func instanceof ScriptFunction) { - return ((ScriptFunction)func).makeSynchronizedFunction(sync); - } - throw typeError("not.a.function", ScriptRuntime.safeToString(func)); + public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) { + return func.makeSynchronizedFunction(unwrap(sync)); } /** @@ -88,12 +83,8 @@ * @param obj object to be wrapped * @return wrapped object */ - public static Object wrap(final Object obj) { - if (obj instanceof ScriptObject) { - return ScriptObjectMirror.wrap(obj, Context.getGlobal()); - } - - return obj; + public static ScriptObjectMirror wrap(final ScriptObject obj) { + return (ScriptObjectMirror) ScriptObjectMirror.wrap(obj, Context.getGlobal()); } /** @@ -160,14 +151,15 @@ } final LinkerServices linker = Bootstrap.getLinkerServices(); - final MethodHandle converter = linker.getTypeConverter(obj.getClass(), clazz); + final Object objToConvert = unwrap(obj); + final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(), clazz); if (converter == null) { // no supported conversion! throw new UnsupportedOperationException("conversion not supported"); } try { - return converter.invoke(obj); + return converter.invoke(objToConvert); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java Wed Jul 05 20:04:43 2017 +0200 @@ -511,16 +511,6 @@ thisProperties.push(new HashSet()); - if (functionNode.isDeclared()) { - // Can't use lc.getCurrentBlock() as we can have an outermost function in our lexical context that - // is not a program - it is a function being compiled on-demand. - final Iterator blocks = lc.getBlocks(); - if (blocks.hasNext()) { - final IdentNode ident = functionNode.getIdent(); - defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0)); - } - } - // Every function has a body, even the ones skipped on reparse (they have an empty one). We're // asserting this as even for those, enterBlock() must be invoked to correctly process symbols that // are used in them. @@ -532,14 +522,34 @@ @Override public boolean enterVarNode(final VarNode varNode) { start(varNode); + // Normally, a symbol assigned in a var statement is not live for its RHS. Since we also represent function + // declarations as VarNodes, they are exception to the rule, as they need to have the symbol visible to the + // body of the declared function for self-reference. + if (varNode.isFunctionDeclaration()) { + defineVarIdent(varNode); + } return true; } @Override public Node leaveVarNode(final VarNode varNode) { + if (!varNode.isFunctionDeclaration()) { + defineVarIdent(varNode); + } + return super.leaveVarNode(varNode); + } + + private void defineVarIdent(final VarNode varNode) { final IdentNode ident = varNode.getName(); - defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0)); - return super.leaveVarNode(varNode); + final int flags; + if (varNode.isAnonymousFunctionDeclaration()) { + flags = IS_INTERNAL; + } else if (lc.getCurrentFunction().isProgram()) { + flags = IS_SCOPE; + } else { + flags = 0; + } + defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags); } private Symbol exceptionSymbol() { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java Wed Jul 05 20:04:43 2017 +0200 @@ -410,10 +410,29 @@ baseName = baseName + installer.getUniqueScriptId(); } - final String mangled = NameCodec.encode(baseName); + // ASM's bytecode verifier does not allow JVM allowed safe escapes using '\' as escape char. + // While ASM accepts such escapes for method names, field names, it enforces Java identifier + // for class names. Workaround that ASM bug here by replacing JVM 'dangerous' chars with '_' + // rather than safe encoding using '\'. + final String mangled = env._verify_code? replaceDangerChars(baseName) : NameCodec.encode(baseName); return mangled != null ? mangled : baseName; } + private static final String DANGEROUS_CHARS = "\\/.;:$[]<>"; + private static String replaceDangerChars(final String name) { + final int len = name.length(); + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < len; i++) { + final char ch = name.charAt(i); + if (DANGEROUS_CHARS.indexOf(ch) != -1) { + buf.append('_'); + } else { + buf.append(ch); + } + } + return buf.toString(); + } + private String firstCompileUnitName() { final StringBuilder sb = new StringBuilder(SCRIPTS_PACKAGE). append('/'). diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java Wed Jul 05 20:04:43 2017 +0200 @@ -98,6 +98,7 @@ import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.ir.TryNode; +import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.runtime.ArgumentSetter; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Debug; @@ -2125,7 +2126,14 @@ int pos = 0; for (int i = argCount - 1; i >= 0; i--) { - paramTypes[i] = stack.peek(pos++); + Type pt = stack.peek(pos++); + // "erase" specific ScriptObject subtype info - except for NativeArray. + // NativeArray is used for array/List/Deque conversion for Java calls. + if (ScriptObject.class.isAssignableFrom(pt.getTypeClass()) && + !NativeArray.class.isAssignableFrom(pt.getTypeClass())) { + pt = Type.SCRIPT_OBJECT; + } + paramTypes[i] = pt; } final String descriptor = Type.getMethodDescriptor(returnType, paramTypes); for (int i = 0; i < argCount; i++) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java Wed Jul 05 20:04:43 2017 +0200 @@ -29,16 +29,22 @@ import static jdk.nashorn.internal.runtime.Property.NOT_ENUMERABLE; import static jdk.nashorn.internal.runtime.Property.NOT_WRITABLE; +import java.lang.invoke.MethodType; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.AccessNode; +import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.Expression; +import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.IndexNode; import jdk.nashorn.internal.ir.Optimistic; +import jdk.nashorn.internal.objects.ArrayBufferView; import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.runtime.FindProperty; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; +import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -47,6 +53,13 @@ * Used during recompilation. */ final class TypeEvaluator { + /** + * Type signature for invocation of functions without parameters: we must pass (callee, this) of type + * (ScriptFunction, Object) respectively. We also use Object as the return type (we must pass something, + * but it'll be ignored; it can't be void, though). + */ + private static final MethodType EMPTY_INVOCATION_TYPE = MethodType.methodType(Object.class, ScriptFunction.class, Object.class); + private final Compiler compiler; private final ScriptObject runtimeScope; @@ -190,30 +203,46 @@ return null; } return getPropertyType(runtimeScope, ((IdentNode)expr).getName()); - } - - if (expr instanceof AccessNode) { + } else if (expr instanceof AccessNode) { final AccessNode accessNode = (AccessNode)expr; final Object base = evaluateSafely(accessNode.getBase()); if (!(base instanceof ScriptObject)) { return null; } return getPropertyType((ScriptObject)base, accessNode.getProperty()); - } - - if (expr instanceof IndexNode) { + } else if (expr instanceof IndexNode) { final IndexNode indexNode = (IndexNode)expr; final Object base = evaluateSafely(indexNode.getBase()); - if(!(base instanceof NativeArray)) { - // We only know how to deal with NativeArray. TODO: maybe manage buffers too - return null; + if(base instanceof NativeArray || base instanceof ArrayBufferView) { + // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their + // underlying array storage, not based on values of individual elements. Thus, a LongArrayData will + // throw UOE for every optimistic int linkage attempt, even if the long value being returned in the + // first invocation would be representable as int. That way, we can presume that the array's optimistic + // type is the most optimistic type for which an element getter has a chance of executing successfully. + return ((ScriptObject)base).getArray().getOptimisticType(); } - // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their underlying - // array storage, not based on values of individual elements. Thus, a LongArrayData will throw UOE for every - // optimistic int linkage attempt, even if the long value being returned in the first invocation would be - // representable as int. That way, we can presume that the array's optimistic type is the most optimistic - // type for which an element getter has a chance of executing successfully. - return ((NativeArray)base).getArray().getOptimisticType(); + } else if (expr instanceof CallNode) { + // Currently, we'll only try to guess the return type of immediately invoked function expressions with no + // parameters, that is (function() { ... })(). We could do better, but these are all heuristics and we can + // gradually introduce them as needed. An easy one would be to do the same for .call(this) idiom. + final CallNode callExpr = (CallNode)expr; + final Expression fnExpr = callExpr.getFunction(); + if (fnExpr instanceof FunctionNode) { + final FunctionNode fn = (FunctionNode)fnExpr; + if (callExpr.getArgs().isEmpty()) { + final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(fn.getId()); + if (data != null) { + final Type returnType = Type.typeFor(data.getReturnType(EMPTY_INVOCATION_TYPE, runtimeScope)); + if (returnType == Type.BOOLEAN) { + // We don't have optimistic booleans. In fact, optimistic call sites getting back boolean + // currently deoptimize all the way to Object. + return Type.OBJECT; + } + assert returnType == Type.INT || returnType == Type.LONG || returnType == Type.NUMBER || returnType == Type.OBJECT; + return returnType; + } + } + } } return null; diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java Wed Jul 05 20:04:43 2017 +0200 @@ -80,11 +80,12 @@ /** * Constructor * - * @param token token - * @param finish finish - * @param statements statements + * @param token The first token of the block + * @param finish The index of the last character + * @param flags The flags of the block + * @param statements All statements in the block */ - public Block(final long token, final int finish, final Statement... statements) { + public Block(final long token, final int finish, final int flags, final Statement... statements) { super(token, finish); this.statements = Arrays.asList(statements); @@ -92,29 +93,52 @@ this.entryLabel = new Label("block_entry"); this.breakLabel = new Label("block_break"); final int len = statements.length; - this.flags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0; + final int terminalFlags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0; + this.flags = terminalFlags | flags; this.conversion = null; } /** + * Constructs a new block + * + * @param token The first token of the block + * @param finish The index of the last character + * @param statements All statements in the block + */ + public Block(final long token, final int finish, final Statement...statements){ + this(token, finish, 0, statements); + } + + /** + * Constructs a new block + * + * @param token The first token of the block + * @param finish The index of the last character + * @param statements All statements in the block + */ + public Block(final long token, final int finish, final List statements){ + this(token, finish, 0, statements); + } + + /** * Constructor * - * @param token token - * @param finish finish - * @param statements statements + * @param token The first token of the block + * @param finish The index of the last character + * @param flags The flags of the block + * @param statements All statements in the block */ - public Block(final long token, final int finish, final List statements) { - this(token, finish, statements.toArray(new Statement[statements.size()])); + public Block(final long token, final int finish, final int flags, final List statements) { + this(token, finish, flags, statements.toArray(new Statement[statements.size()])); } private Block(final Block block, final int finish, final List statements, final int flags, final Map symbols, final LocalVariableConversion conversion) { - super(block); + super(block, finish); this.statements = statements; this.flags = flags; this.symbols = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now this.entryLabel = new Label(block.entryLabel); this.breakLabel = new Label(block.breakLabel); - this.finish = finish; this.conversion = conversion; } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -55,19 +55,36 @@ private final int flags; /** + * Constructs a ForNode + * + * @param lineNumber The line number of header + * @param token The for token + * @param finish The last character of the for node + * @param body The body of the for node + * @param flags The flags + */ + public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags){ + this(lineNumber, token, finish, body, flags, null, null, null); + } + + /** * Constructor * - * @param lineNumber line number - * @param token token - * @param finish finish - * @param body body - * @param flags flags + * @param lineNumber The line number of header + * @param token The for token + * @param finish The last character of the for node + * @param body The body of the for node + * @param flags The flags + * @param init The initial expression + * @param test The test expression + * @param modify The modify expression */ - public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags) { - super(lineNumber, token, finish, body, false); + public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags, final Expression init, final JoinPredecessorExpression test, final JoinPredecessorExpression modify) { + super(lineNumber, token, finish, body, test, false); this.flags = flags; - this.init = null; - this.modify = null; + this.init = init; + this.modify = modify; + } private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test, @@ -166,16 +183,6 @@ public boolean isForIn() { return (flags & IS_FOR_IN) != 0; } - - /** - * Flag this to be a for in construct - * @param lc lexical context - * @return new for node if changed or existing if not - */ - public ForNode setIsForIn(final LexicalContext lc) { - return setFlags(lc, flags | IS_FOR_IN); - } - /** * Is this a for each construct, known from e.g. Rhino. This will be a for of construct * in ECMAScript 6 @@ -186,15 +193,6 @@ } /** - * Flag this to be a for each construct - * @param lc lexical context - * @return new for node if changed or existing if not - */ - public ForNode setIsForEach(final LexicalContext lc) { - return setFlags(lc, flags | IS_FOR_EACH); - } - - /** * If this is a for in or for each construct, there is an iterator symbol * @return the symbol for the iterator to be used, or null if none exists */ @@ -260,13 +258,6 @@ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); } - private ForNode setFlags(final LexicalContext lc, final int flags) { - if (this.flags == flags) { - return this; - } - return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); - } - @Override JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) { return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -31,7 +31,6 @@ import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES; - import java.util.Collections; import java.util.EnumSet; import java.util.Iterator; @@ -46,6 +45,7 @@ import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.Source; @@ -299,12 +299,16 @@ * @param token token * @param finish finish * @param firstToken first token of the function node (including the function declaration) + * @param lastToken lastToken * @param namespace the namespace * @param ident the identifier * @param name the name of the function * @param parameters parameter list * @param kind kind of function as in {@link FunctionNode.Kind} * @param flags initial flags + * @param body body of the function + * @param state The initial state from the parser. Must be one of {@link CompilationState#PARSED} and {@link CompilationState#PARSE_ERROR} + * @param endParserState The parser state at the end of the parsing. */ public FunctionNode( final Source source, @@ -312,12 +316,16 @@ final long token, final int finish, final long firstToken, + final long lastToken, final Namespace namespace, final IdentNode ident, final String name, final List parameters, final FunctionNode.Kind kind, - final int flags) { + final int flags, + final Block body, + final CompilationState state, + final Object endParserState) { super(token, finish); this.source = source; @@ -327,15 +335,15 @@ this.kind = kind; this.parameters = parameters; this.firstToken = firstToken; - this.lastToken = token; + this.lastToken = lastToken; this.namespace = namespace; - this.compilationState = EnumSet.of(CompilationState.INITIALIZED); + this.compilationState = EnumSet.of(CompilationState.INITIALIZED, state); this.flags = flags; this.compileUnit = null; - this.body = null; + this.body = body; this.thisProperties = 0; this.rootClass = null; - this.endParserState = null; + this.endParserState = endParserState; } private FunctionNode( @@ -439,7 +447,7 @@ * @return the id */ public int getId() { - return position(); + return isProgram() ? -1: Token.descPosition(firstToken); } /** @@ -903,34 +911,6 @@ } /** - * Set the last token for this function's code - * @param lc lexical context - * @param lastToken the last token - * @return function node or a new one if state was changed - */ - public FunctionNode setLastToken(final LexicalContext lc, final long lastToken) { - if (this.lastToken == lastToken) { - return this; - } - return Node.replaceInLexicalContext( - lc, - this, - new FunctionNode( - this, - lastToken, - endParserState, - flags, - name, - returnType, - compileUnit, - compilationState, - body, - parameters, - thisProperties, - rootClass)); - } - - /** * Returns the end parser state for this function. * @return the end parser state for this function. */ @@ -939,33 +919,6 @@ } /** - * Set the end parser state for this function. - * @param lc lexical context - * @param endParserState the parser state to set - * @return function node or a new one if state was changed - */ - public FunctionNode setEndParserState(final LexicalContext lc, final Object endParserState) { - if (this.endParserState == endParserState) { - return this; - } - return Node.replaceInLexicalContext( - lc, - this, - new FunctionNode( - this, - lastToken, - endParserState, - flags, - name, - returnType, - compileUnit, - compilationState, - body, - parameters, - thisProperties, rootClass)); - } - - /** * Get the name of this function * @return the name */ diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LoopNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -53,14 +53,15 @@ * @param token token * @param finish finish * @param body loop body + * @param test test * @param controlFlowEscapes controlFlowEscapes */ - protected LoopNode(final int lineNumber, final long token, final int finish, final Block body, final boolean controlFlowEscapes) { + protected LoopNode(final int lineNumber, final long token, final int finish, final Block body, final JoinPredecessorExpression test, final boolean controlFlowEscapes) { super(lineNumber, token, finish, new Label("while_break")); this.continueLabel = new Label("while_continue"); - this.test = null; this.body = body; this.controlFlowEscapes = controlFlowEscapes; + this.test = test; } /** diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Node.java Wed Jul 05 20:04:43 2017 +0200 @@ -39,7 +39,7 @@ protected final int start; /** End of source range. */ - protected int finish; + protected final int finish; /** Token descriptor. */ private final long token; @@ -81,6 +81,18 @@ } /** + * Copy constructor that overrides finish + * + * @param node source node + * @param finish Last character + */ + protected Node(final Node node, final int finish) { + this.token = node.token; + this.start = node.start; + this.finish = finish; + } + + /** * Is this a loop node? * * @return true if atom @@ -152,14 +164,6 @@ } /** - * Set finish position for this node in the source string - * @param finish finish - */ - public void setFinish(final int finish) { - this.finish = finish; - } - - /** * Get start position for node * @return start position */ diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -272,4 +272,12 @@ public boolean isFunctionDeclaration() { return init instanceof FunctionNode && ((FunctionNode)init).isDeclared(); } + + /** + * Returns true if this is an anonymous function declaration. + * @return true if this is an anonymous function declaration. + */ + public boolean isAnonymousFunctionDeclaration() { + return isFunctionDeclaration() && ((FunctionNode)init).isAnonymous(); + } } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WhileNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -45,9 +45,11 @@ * @param token token * @param finish finish * @param isDoWhile is this a do while loop? + * @param test test expression + * @param body body of the while loop */ - public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile) { - super(lineNumber, token, finish, null, false); + public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile, final JoinPredecessorExpression test, final Block body) { + super(lineNumber, token, finish, body, test, false); this.isDoWhile = isDoWhile; } @@ -55,10 +57,10 @@ * Internal copy constructor * * @param whileNode while node - * @param test test - * @param body body + * @param test Test expression + * @param body body of the while loop * @param controlFlowEscapes control flow escapes? - * @param conversion TODO + * @param conversion local variable conversion info */ private WhileNode(final WhileNode whileNode, final JoinPredecessorExpression test, final Block body, final boolean controlFlowEscapes, final LocalVariableConversion conversion) { super(whileNode, test, body, controlFlowEscapes, conversion); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/WithNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -42,14 +42,16 @@ /** * Constructor * - * @param lineNumber line number - * @param token token - * @param finish finish + * @param lineNumber Line number of the header + * @param token First token + * @param finish Character index of the last token + * @param expression With expression + * @param body Body of with node */ - public WithNode(final int lineNumber, final long token, final int finish) { + public WithNode(final int lineNumber, final long token, final int finish, final Expression expression, final Block body) { super(lineNumber, token, finish); - this.expression = null; - this.body = null; + this.expression = expression; + this.body = body; } private WithNode(final WithNode node, final Expression expression, final Block body) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayBufferView.java Wed Jul 05 20:04:43 2017 +0200 @@ -31,7 +31,6 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; - import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; @@ -46,7 +45,7 @@ import jdk.nashorn.internal.runtime.arrays.TypedArrayData; @ScriptClass("ArrayBufferView") -abstract class ArrayBufferView extends ScriptObject { +public abstract class ArrayBufferView extends ScriptObject { private final NativeArrayBuffer buffer; private final int byteOffset; diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java Wed Jul 05 20:04:43 2017 +0200 @@ -561,7 +561,6 @@ * * @param engine ScriptEngine to initialize */ - @SuppressWarnings("hiding") public void initBuiltinObjects(final ScriptEngine engine) { if (this.builtinObject != null) { // already initialized, just return @@ -1718,7 +1717,6 @@ return func; } - @SuppressWarnings("hiding") private void init(final ScriptEngine engine) { assert Context.getGlobal() == this : "this global is not set as current"; diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeError.java Wed Jul 05 20:04:43 2017 +0200 @@ -27,7 +27,6 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import jdk.nashorn.api.scripting.NashornException; @@ -131,7 +130,6 @@ // This is called NativeError, NativeTypeError etc. to // associate a ECMAException with the ECMA Error object. - @SuppressWarnings("unused") static void initException(final ScriptObject self) { // ECMAException constructor has side effects new ECMAException(self, null); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -141,6 +142,11 @@ } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getDouble(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -141,6 +142,11 @@ } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getDouble(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -124,16 +125,31 @@ } @Override + public int getIntOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public long getLong(final int index) { return getInt(index); } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getInt(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getInt(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -122,16 +123,31 @@ } @Override + public int getIntOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public long getLong(final int index) { return getInt(index); } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getInt(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getInt(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -122,16 +123,31 @@ } @Override + public int getIntOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public long getLong(final int index) { return getInt(index); } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getInt(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getInt(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java Wed Jul 05 20:04:43 2017 +0200 @@ -27,7 +27,6 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; - import java.lang.invoke.MethodHandles; import java.lang.reflect.Array; import java.util.Collection; @@ -36,7 +35,6 @@ import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.TypeUtilities; import jdk.nashorn.api.scripting.JSObject; -import jdk.nashorn.api.scripting.ScriptUtils; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; @@ -90,7 +88,11 @@ */ @Function(name="synchronized", attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object synchronizedFunc(final Object self, final Object func, final Object obj) { - return ScriptUtils.makeSynchronizedFunction(func, obj); + if (func instanceof ScriptFunction) { + return ((ScriptFunction)func).makeSynchronizedFunction(obj); + } + + throw typeError("not.a.function", ScriptRuntime.safeToString(func)); } /** diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJavaImporter.java Wed Jul 05 20:04:43 2017 +0200 @@ -25,6 +25,7 @@ package jdk.nashorn.internal.objects; +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; import jdk.internal.dynalink.CallSiteDescriptor; @@ -36,9 +37,11 @@ import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.NativeJavaPackage; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; /** @@ -94,33 +97,30 @@ } /** - * "No such property" call placeholder. - * - * This can never be called as we override {@link ScriptObject#noSuchProperty}. We do declare it here as it's a signal - * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a {@code noSuchProperty} on this object. + * "No such property" handler. * * @param self self reference * @param name property name - * @return never returns + * @return value of the missing property */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object __noSuchProperty__(final Object self, final Object name) { - throw new AssertionError("__noSuchProperty__ placeholder called"); + if (! (self instanceof NativeJavaImporter)) { + throw typeError("not.a.java.importer", ScriptRuntime.safeToString(self)); + } + return ((NativeJavaImporter)self).createProperty(JSType.toString(name)); } /** - * "No such method call" placeholder - * - * This can never be called as we override {@link ScriptObject#noSuchMethod}. We do declare it here as it's a signal - * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a noSuchProperty on this object. + * "No such method call" handler * * @param self self reference * @param args arguments to method - * @return never returns + * @return never returns always throw TypeError */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object __noSuchMethod__(final Object self, final Object... args) { - throw new AssertionError("__noSuchMethod__ placeholder called"); + throw typeError("not.a.function", ScriptRuntime.safeToString(args[0])); } @Override diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -128,16 +129,31 @@ } @Override + public int getIntOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public long getLong(final int index) { return getInt(index); } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getInt(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getInt(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -128,7 +129,7 @@ @Override public Class getElementType() { - return int.class; + return long.class; } @Override @@ -142,11 +143,21 @@ } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getLong(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getLong(index); + } + + @Override public Object getObject(final int index) { return getLong(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,6 +26,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -128,16 +129,31 @@ } @Override + public int getIntOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public long getLong(final int index) { return getInt(index); } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getInt(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getInt(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Jul 05 20:04:43 2017 +0200 @@ -28,6 +28,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.lookup.Lookup.MH; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; @@ -158,16 +159,31 @@ } @Override + public int getIntOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public long getLong(final int index) { return getInt(index); } @Override + public long getLongOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public double getDouble(final int index) { return getInt(index); } @Override + public double getDoubleOptimistic(final int index, final int programPoint) { + return getElem(index); + } + + @Override public Object getObject(final int index) { return getInt(index); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Wed Jul 05 20:04:43 2017 +0200 @@ -53,7 +53,6 @@ import static jdk.nashorn.internal.parser.TokenType.SEMICOLON; import static jdk.nashorn.internal.parser.TokenType.TERNARY; import static jdk.nashorn.internal.parser.TokenType.WHILE; - import java.io.Serializable; import java.util.ArrayDeque; import java.util.ArrayList; @@ -71,10 +70,8 @@ import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.BlockLexicalContext; import jdk.nashorn.internal.ir.BlockStatement; import jdk.nashorn.internal.ir.BreakNode; -import jdk.nashorn.internal.ir.BreakableNode; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; @@ -90,9 +87,7 @@ import jdk.nashorn.internal.ir.IndexNode; import jdk.nashorn.internal.ir.JoinPredecessorExpression; import jdk.nashorn.internal.ir.LabelNode; -import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.LoopNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; import jdk.nashorn.internal.ir.PropertyKey; @@ -138,8 +133,8 @@ private List functionDeclarations; - private final BlockLexicalContext lc = new BlockLexicalContext(); - private final Deque defaultNames = new ArrayDeque<>(); + private final ParserContext lc; + private final Deque defaultNames; /** Namespace for function names where not explicitly given */ private final Namespace namespace; @@ -187,6 +182,8 @@ */ public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int lineOffset, final DebugLogger log) { super(source, errors, strict, lineOffset); + this.lc = new ParserContext(); + this.defaultNames = new ArrayDeque<>(); this.env = env; this.namespace = new Namespace(env.getNamespace()); this.scripting = env._scripting; @@ -344,26 +341,35 @@ final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength()); // Set up the function to append elements. - FunctionNode function = newFunctionNode( - functionToken, - new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName()), - new ArrayList(), - FunctionNode.Kind.NORMAL, - functionLine); + final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName()); + final ParserContextFunctionNode function = createParserContextFunctionNode(ident, functionToken, FunctionNode.Kind.NORMAL, functionLine, Collections.emptyList()); + lc.push(function); + + final ParserContextBlockNode body = newBlock(); functionDeclarations = new ArrayList<>(); sourceElements(false); addFunctionDeclarations(function); functionDeclarations = null; + restoreBlock(body); + body.setFlag(Block.NEEDS_SCOPE); + + final Block functionBody = new Block(functionToken, source.getLength() - 1, body.getFlags(), body.getStatements()); + lc.pop(function); + expect(EOF); - function.setFinish(source.getLength() - 1); - function = restoreFunctionNode(function, token); //commit code - function = function.setBody(lc, function.getBody().setNeedsScope(lc)); - - printAST(function); - return function; + final FunctionNode functionNode = createFunctionNode( + function, + functionToken, + ident, + Collections.emptyList(), + FunctionNode.Kind.NORMAL, + functionLine, + functionBody); + printAST(functionNode); + return functionNode; } catch (final Exception e) { handleParseException(e); return null; @@ -444,21 +450,15 @@ * * @return New block. */ - private Block newBlock() { - return lc.push(new Block(token, Token.descPosition(token))); + private ParserContextBlockNode newBlock() { + return lc.push(new ParserContextBlockNode(token)); } - /** - * Set up a new function block. - * - * @param ident Name of function. - * @return New block. - */ - private FunctionNode newFunctionNode(final long startToken, final IdentNode ident, final List parameters, final FunctionNode.Kind kind, final int functionLine) { + private ParserContextFunctionNode createParserContextFunctionNode(final IdentNode ident, final long functionToken, final FunctionNode.Kind kind, final int functionLine, final List parameters) { // Build function name. final StringBuilder sb = new StringBuilder(); - final FunctionNode parentFunction = lc.getCurrentFunction(); + final ParserContextFunctionNode parentFunction = lc.getCurrentFunction(); if (parentFunction != null && !parentFunction.isProgram()) { sb.append(parentFunction.getName()).append('$'); } @@ -477,25 +477,33 @@ flags |= FunctionNode.IS_PROGRAM; } + final ParserContextFunctionNode functionNode = new ParserContextFunctionNode(functionToken, ident, name, namespace, functionLine, kind, parameters); + functionNode.setFlag(flags); + return functionNode; + } + + private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List parameters, final FunctionNode.Kind kind, final int functionLine, final Block body){ + final CompilationState state = errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED; // Start new block. final FunctionNode functionNode = new FunctionNode( source, functionLine, - token, - Token.descPosition(token), + body.getToken(), + Token.descPosition(body.getToken()), startToken, + function.getLastToken(), namespace, ident, - name, + function.getName(), parameters, kind, - flags); - - lc.push(functionNode); - // Create new block, and just put it on the context stack, restoreFunctionNode() will associate it with the - // FunctionNode. - newBlock(); + function.getFlags(), + body, + state, + function.getEndParserState()); + + printAST(functionNode); return functionNode; } @@ -503,27 +511,17 @@ /** * Restore the current block. */ - private Block restoreBlock(final Block block) { + private ParserContextBlockNode restoreBlock(final ParserContextBlockNode block) { return lc.pop(block); } - - private FunctionNode restoreFunctionNode(final FunctionNode functionNode, final long lastToken) { - final Block newBody = restoreBlock(lc.getFunctionBody(functionNode)); - - return lc.pop(functionNode). - setBody(lc, newBody). - setLastToken(lc, lastToken). - setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED); - } - /** * Get the statements in a block. * @return Block statements. */ private Block getBlock(final boolean needsBraces) { - // Set up new block. Captures LBRACE. - Block newBlock = newBlock(); + final long blockToken = token; + final ParserContextBlockNode newBlock = newBlock(); try { // Block opening brace. if (needsBraces) { @@ -533,21 +531,18 @@ statementList(); } finally { - newBlock = restoreBlock(newBlock); + restoreBlock(newBlock); } - final int possibleEnd = Token.descPosition(token) + Token.descLength(token); - // Block closing brace. if (needsBraces) { expect(RBRACE); } - newBlock.setFinish(possibleEnd); - - return newBlock; + return new Block(blockToken, finish, newBlock.getFlags(), newBlock.getStatements()); } + /** * Get all the statements generated by a single statement. * @return Statements. @@ -557,13 +552,13 @@ return getBlock(true); } // Set up new block. Captures first token. - Block newBlock = newBlock(); + final ParserContextBlockNode newBlock = newBlock(); try { statement(); } finally { - newBlock = restoreBlock(newBlock); + restoreBlock(newBlock); } - return newBlock; + return new Block(newBlock.getToken(), finish, newBlock.getFlags(), newBlock.getStatements()); } /** @@ -584,7 +579,7 @@ */ private void detectSpecialProperty(final IdentNode ident) { if (isArguments(ident)) { - lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_ARGUMENTS); + lc.getCurrentFunction().setFlag(FunctionNode.USES_ARGUMENTS); } } @@ -698,18 +693,19 @@ // Make a pseudo-token for the script holding its start and length. final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength()); final int functionLine = line; - // Set up the script to append elements. - - FunctionNode script = newFunctionNode( - functionToken, - new IdentNode(functionToken, Token.descPosition(functionToken), scriptName), - new ArrayList(), - FunctionNode.Kind.SCRIPT, - functionLine); - + + final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), scriptName); + final ParserContextFunctionNode script = createParserContextFunctionNode( + ident, + functionToken, + FunctionNode.Kind.SCRIPT, + functionLine, + Collections.emptyList()); + lc.push(script); + final ParserContextBlockNode body = newBlock(); // If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations. final int startLine = start; - Block outer = useBlockScope() ? newBlock() : null; + final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null; functionDeclarations = new ArrayList<>(); try { @@ -717,20 +713,25 @@ addFunctionDeclarations(script); } finally { if (outer != null) { - outer = restoreBlock(outer); - appendStatement(new BlockStatement(startLine, outer)); + restoreBlock(outer); + appendStatement(new BlockStatement( + startLine, + new Block( + functionToken, + startLine, outer.getFlags(), + outer.getStatements()))); } } functionDeclarations = null; + restoreBlock(body); + body.setFlag(Block.NEEDS_SCOPE); + final Block programBody = new Block(functionToken, functionLine, body.getFlags(), body.getStatements()); + lc.pop(script); + script.setLastToken(token); expect(EOF); - script.setFinish(source.getLength() - 1); - - script = restoreFunctionNode(script, token); //commit code - script = script.setBody(lc, script.getBody().setNeedsScope(lc)); - - return script; + return createFunctionNode(script, functionToken, ident, Collections.emptyList(), FunctionNode.Kind.SCRIPT, functionLine, programBody); } /** @@ -789,7 +790,7 @@ // check for directive prologues if (checkDirective) { // skip any debug statement like line number to get actual first line - final Node lastStatement = lc.getLastStatement(); + final Statement lastStatement = lc.getLastStatement(); // get directive prologue, if any final String directive = getDirective(lastStatement); @@ -809,8 +810,8 @@ // handle use strict directive if ("use strict".equals(directive)) { isStrictMode = true; - final FunctionNode function = lc.getCurrentFunction(); - lc.setFlag(lc.getCurrentFunction(), FunctionNode.IS_STRICT); + final ParserContextFunctionNode function = lc.getCurrentFunction(); + function.setFlag(FunctionNode.IS_STRICT); // We don't need to check these, if lexical environment is already strict if (!oldStrictMode && directiveStmts != null) { @@ -831,8 +832,8 @@ } else if (Context.DEBUG) { final int flag = FunctionNode.getDirectiveFlag(directive); if (flag != 0) { - final FunctionNode function = lc.getCurrentFunction(); - lc.setFlag(function, flag); + final ParserContextFunctionNode function = lc.getCurrentFunction(); + function.setFlag(flag); } } } @@ -1114,11 +1115,7 @@ // If is a statement then handle end of line. if (isStatement) { - final boolean semicolon = type == SEMICOLON; endOfLine(); - if (semicolon) { - lc.getCurrentBlock().setFinish(finish); - } } return vars; @@ -1166,11 +1163,6 @@ } endOfLine(); - - if (expressionStatement != null) { - expressionStatement.setFinish(finish); - lc.getCurrentBlock().setFinish(finish); - } } /** @@ -1216,13 +1208,23 @@ * Parse a FOR statement. */ private void forStatement() { + final long forToken = token; + final int forLine = line; // When ES6 for-let is enabled we create a container block to capture the LET. final int startLine = start; - Block outer = useBlockScope() ? newBlock() : null; + final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null; + // Create FOR node, capturing FOR token. - ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR); + final ParserContextLoopNode forNode = new ParserContextLoopNode(); lc.push(forNode); + Block body = null; + List vars = null; + Expression init = null; + JoinPredecessorExpression test = null; + JoinPredecessorExpression modify = null; + + int flags = 0; try { // FOR tested in caller. @@ -1231,13 +1233,12 @@ // Nashorn extension: for each expression. // iterate property values rather than property names. if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) { - forNode = forNode.setIsForEach(lc); + flags |= ForNode.IS_FOR_EACH; next(); } expect(LPAREN); - List vars = null; switch (type) { case VAR: @@ -1258,8 +1259,7 @@ break; } - final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true); - forNode = forNode.setInit(lc, expression); + init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true); break; } @@ -1268,26 +1268,27 @@ // for (init; test; modify) // for each (init; test; modify) is invalid - if (forNode.isForEach()) { + if ((flags & ForNode.IS_FOR_EACH) != 0) { throw error(AbstractParser.message("for.each.without.in"), token); } expect(SEMICOLON); if (type != SEMICOLON) { - forNode = forNode.setTest(lc, joinPredecessorExpression()); + test = joinPredecessorExpression(); } expect(SEMICOLON); if (type != RPAREN) { - forNode = forNode.setModify(lc, joinPredecessorExpression()); + modify = joinPredecessorExpression(); } break; case IN: - forNode = forNode.setIsForIn(lc).setTest(lc, new JoinPredecessorExpression()); + flags |= ForNode.IS_FOR_IN; + test = new JoinPredecessorExpression(); if (vars != null) { // for (var i in obj) if (vars.size() == 1) { - forNode = forNode.setInit(lc, new IdentNode(vars.get(0).getName())); + init = new IdentNode(vars.get(0).getName()); } else { // for (var i, j in obj) is invalid throw error(AbstractParser.message("many.vars.in.for.in.loop"), vars.get(1).getToken()); @@ -1295,7 +1296,6 @@ } else { // for (expr in obj) - final Node init = forNode.getInit(); assert init != null : "for..in init expression can not be null here"; // check if initial expression is a valid L-value @@ -1316,7 +1316,7 @@ next(); // Get the collection expression. - forNode = forNode.setModify(lc, joinPredecessorExpression()); + modify = joinPredecessorExpression(); break; default: @@ -1327,38 +1327,28 @@ expect(RPAREN); // Set the for body. - final Block body = getStatement(); - forNode = forNode.setBody(lc, body); - forNode.setFinish(body.getFinish()); - - appendStatement(forNode); + body = getStatement(); } finally { lc.pop(forNode); + if (vars != null) { + for (final VarNode var : vars) { + appendStatement(var); + } + } + if (body != null) { + appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify)); + } if (outer != null) { - outer.setFinish(forNode.getFinish()); - outer = restoreBlock(outer); - appendStatement(new BlockStatement(startLine, outer)); + restoreBlock(outer); + appendStatement(new BlockStatement(startLine, new Block( + outer.getToken(), + body.getFinish(), + outer.getStatements()))); } } } /** - * ... IterationStatement : - * ... - * Expression[NoIn]?; Expression? ; Expression? - * var VariableDeclarationList[NoIn]; Expression? ; Expression? - * LeftHandSideExpression in Expression - * var VariableDeclaration[NoIn] in Expression - * - * See 12.6 - * - * Parse the control section of a FOR statement. Also used for - * comprehensions. - * @param forNode Owning FOR. - */ - - - /** * ...IterationStatement : * ... * while ( Expression ) Statement @@ -1371,25 +1361,26 @@ private void whileStatement() { // Capture WHILE token. final long whileToken = token; + final int whileLine = line; // WHILE tested in caller. next(); - // Construct WHILE node. - WhileNode whileNode = new WhileNode(line, whileToken, Token.descPosition(whileToken), false); + final ParserContextLoopNode whileNode = new ParserContextLoopNode(); lc.push(whileNode); + JoinPredecessorExpression test = null; + Block body = null; + try { expect(LPAREN); - final int whileLine = line; - final JoinPredecessorExpression test = joinPredecessorExpression(); + test = joinPredecessorExpression(); expect(RPAREN); - final Block body = getStatement(); - appendStatement(whileNode = - new WhileNode(whileLine, whileToken, finish, false). - setTest(lc, test). - setBody(lc, body)); + body = getStatement(); } finally { lc.pop(whileNode); + if (body != null){ + appendStatement(new WhileNode(whileLine, whileToken, body.getFinish(), false, test, body)); + } } } @@ -1406,34 +1397,32 @@ private void doStatement() { // Capture DO token. final long doToken = token; + int doLine = 0; // DO tested in the caller. next(); - WhileNode doWhileNode = new WhileNode(-1, doToken, Token.descPosition(doToken), true); + final ParserContextLoopNode doWhileNode = new ParserContextLoopNode(); lc.push(doWhileNode); + Block body = null; + JoinPredecessorExpression test = null; + try { // Get DO body. - final Block body = getStatement(); + body = getStatement(); expect(WHILE); expect(LPAREN); - final int doLine = line; - final JoinPredecessorExpression test = joinPredecessorExpression(); + doLine = line; + test = joinPredecessorExpression(); expect(RPAREN); if (type == SEMICOLON) { endOfLine(); } - doWhileNode.setFinish(finish); - - //line number is last - appendStatement(doWhileNode = - new WhileNode(doLine, doToken, finish, true). - setBody(lc, body). - setTest(lc, test)); } finally { lc.pop(doWhileNode); + appendStatement(new WhileNode(doLine, doToken, finish, true, test, body)); } } @@ -1452,7 +1441,7 @@ // CONTINUE tested in caller. nextOrEOL(); - LabelNode labelNode = null; + ParserContextLabelNode labelNode = null; // SEMICOLON or label. switch (type) { @@ -1474,7 +1463,7 @@ } final String labelName = labelNode == null ? null : labelNode.getLabelName(); - final LoopNode targetNode = lc.getContinueTo(labelName); + final ParserContextLoopNode targetNode = lc.getContinueTo(labelName); if (targetNode == null) { throw error(AbstractParser.message("illegal.continue.stmt"), continueToken); @@ -1500,7 +1489,7 @@ // BREAK tested in caller. nextOrEOL(); - LabelNode labelNode = null; + ParserContextLabelNode labelNode = null; // SEMICOLON or label. switch (type) { @@ -1524,7 +1513,7 @@ //either an explicit label - then get its node or just a "break" - get first breakable //targetNode is what we are breaking out from. final String labelName = labelNode == null ? null : labelNode.getLabelName(); - final BreakableNode targetNode = lc.getBreakable(labelName); + final ParserContextBreakableNode targetNode = lc.getBreakable(labelName); if (targetNode == null) { throw error(AbstractParser.message("illegal.break.stmt"), breakToken); } @@ -1632,20 +1621,17 @@ throw error(AbstractParser.message("strict.no.with"), withToken); } - // Get WITH expression. - WithNode withNode = new WithNode(withLine, withToken, finish); - + Expression expression = null; + Block body = null; try { - lc.push(withNode); expect(LPAREN); - withNode = withNode.setExpression(lc, expression()); + expression = expression(); expect(RPAREN); - withNode = withNode.setBody(lc, getStatement()); + body = getStatement(); } finally { - lc.pop(withNode); + appendStatement(new WithNode(withLine, withToken, finish, expression, body)); } - appendStatement(withNode); } /** @@ -1677,19 +1663,22 @@ next(); // Create and add switch statement. - SwitchNode switchNode = new SwitchNode(switchLine, switchToken, Token.descPosition(switchToken), null, new ArrayList(), null); + final ParserContextSwitchNode switchNode= new ParserContextSwitchNode(); lc.push(switchNode); + CaseNode defaultCase = null; + // Prepare to accumulate cases. + final List cases = new ArrayList<>(); + + Expression expression = null; + try { expect(LPAREN); - switchNode = switchNode.setExpression(lc, expression()); + expression = expression(); expect(RPAREN); expect(LBRACE); - // Prepare to accumulate cases. - final List cases = new ArrayList<>(); - CaseNode defaultCase = null; while (type != RBRACE) { // Prepare for next case. @@ -1720,7 +1709,6 @@ // Get CASE body. final Block statements = getBlock(false); final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements); - statements.setFinish(finish); if (caseExpression == null) { defaultCase = caseNode; @@ -1729,13 +1717,10 @@ cases.add(caseNode); } - switchNode = switchNode.setCases(lc, cases, defaultCase); next(); - switchNode.setFinish(finish); - - appendStatement(switchNode); } finally { lc.pop(switchNode); + appendStatement(new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase)); } } @@ -1759,15 +1744,17 @@ throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken); } - LabelNode labelNode = new LabelNode(line, labelToken, finish, ident.getName(), null); + final ParserContextLabelNode labelNode = new ParserContextLabelNode(ident.getName()); + Block body = null; try { lc.push(labelNode); - labelNode = labelNode.setBody(lc, getStatement()); - labelNode.setFinish(finish); - appendStatement(labelNode); + body = getStatement(); } finally { - assert lc.peek() instanceof LabelNode; + assert lc.peek() instanceof ParserContextLabelNode; lc.pop(labelNode); + if (ident != null){ + appendStatement(new LabelNode(line, labelToken, finish, ident.getName(), body)); + } } } @@ -1835,8 +1822,7 @@ // Container block needed to act as target for labeled break statements final int startLine = line; - Block outer = newBlock(); - + final ParserContextBlockNode outer = newBlock(); // Create try. try { @@ -1867,15 +1853,15 @@ expect(RPAREN); - Block catchBlock = newBlock(); + final ParserContextBlockNode catchBlock = newBlock(); try { // Get CATCH body. final Block catchBody = getBlock(true); final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false); appendStatement(catchNode); } finally { - catchBlock = restoreBlock(catchBlock); - catchBlocks.add(catchBlock); + restoreBlock(catchBlock); + catchBlocks.add(new Block(catchBlock.getToken(), finish, catchBlock.getFlags(), catchBlock.getStatements())); } // If unconditional catch then should to be the end. @@ -1897,19 +1883,15 @@ throw error(AbstractParser.message("missing.catch.or.finally"), tryToken); } - final TryNode tryNode = new TryNode(tryLine, tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements); + final TryNode tryNode = new TryNode(tryLine, tryToken, finish, tryBody, catchBlocks, finallyStatements); // Add try. assert lc.peek() == outer; appendStatement(tryNode); - - tryNode.setFinish(finish); - outer.setFinish(finish); - } finally { - outer = restoreBlock(outer); + restoreBlock(outer); } - appendStatement(new BlockStatement(startLine, outer)); + appendStatement(new BlockStatement(startLine, new Block(tryToken, finish, outer.getFlags(), outer.getStatements()))); } /** @@ -1927,7 +1909,7 @@ // DEBUGGER tested in caller. next(); endOfLine(); - appendStatement(new ExpressionStatement(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList()))); + appendStatement(new ExpressionStatement(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, Collections.emptyList()))); } /** @@ -1954,7 +1936,7 @@ case THIS: final String name = type.getName(); next(); - lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_THIS); + lc.getCurrentFunction().setFlag(FunctionNode.USES_THIS); return new IdentNode(primaryToken, finish, name); case IDENT: final IdentNode ident = getIdent(); @@ -2314,9 +2296,24 @@ final IdentNode getNameNode = createIdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName)); expect(LPAREN); expect(RPAREN); - final FunctionNode functionNode = functionBody(getSetToken, getNameNode, new ArrayList(), FunctionNode.Kind.GETTER, functionLine); - - return new PropertyFunction(getIdent, functionNode); + + final ParserContextFunctionNode functionNode = createParserContextFunctionNode(getNameNode, getSetToken, FunctionNode.Kind.GETTER, functionLine, Collections.emptyList()); + lc.push(functionNode); + + final Block functionBody = functionBody(functionNode); + + lc.pop(functionNode); + + final FunctionNode function = createFunctionNode( + functionNode, + getSetToken, + getNameNode, + Collections.emptyList(), + FunctionNode.Kind.GETTER, + functionLine, + functionBody); + + return new PropertyFunction(getIdent, function); } private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) { @@ -2338,9 +2335,25 @@ if (argIdent != null) { parameters.add(argIdent); } - final FunctionNode functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER, functionLine); - - return new PropertyFunction(setIdent, functionNode); + + + final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters); + lc.push(functionNode); + + final Block functionBody = functionBody(functionNode); + + lc.pop(functionNode); + + final FunctionNode function = createFunctionNode( + functionNode, + getSetToken, + setNameNode, + parameters, + FunctionNode.Kind.SETTER, + functionLine, + functionBody); + + return new PropertyFunction(setIdent, function); } private static class PropertyFunction { @@ -2655,11 +2668,18 @@ final List parameters = formalParameterList(); expect(RPAREN); - FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine); + final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.NORMAL, functionLine, parameters); + lc.push(functionNode); + Block functionBody = null; + try{ + functionBody = functionBody(functionNode); + } finally { + lc.pop(functionNode); + } if (isStatement) { if (topLevel || useBlockScope()) { - functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED); + functionNode.setFlag(FunctionNode.IS_DECLARED); } else if (isStrictMode) { throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken); } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ERROR) { @@ -2668,12 +2688,12 @@ warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken); } if (isArguments(name)) { - lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS); + lc.getCurrentFunction().setFlag(FunctionNode.DEFINES_ARGUMENTS); } } if (isAnonymous) { - functionNode = functionNode.setFlag(lc, FunctionNode.IS_ANONYMOUS); + functionNode.setFlag(FunctionNode.IS_ANONYMOUS); } final int arity = parameters.size(); @@ -2687,7 +2707,7 @@ String parameterName = parameter.getName(); if (isArguments(parameterName)) { - functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); + functionNode.setFlag(FunctionNode.DEFINES_ARGUMENTS); } if (parametersSet.contains(parameterName)) { @@ -2705,17 +2725,26 @@ } } else if (arity == 1) { if (isArguments(parameters.get(0))) { - functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); + functionNode.setFlag(FunctionNode.DEFINES_ARGUMENTS); } } + final FunctionNode function = createFunctionNode( + functionNode, + functionToken, + name, + parameters, + FunctionNode.Kind.NORMAL, + functionLine, + functionBody); + if (isStatement) { int varFlags = VarNode.IS_STATEMENT; if (!topLevel && useBlockScope()) { // mark ES6 block functions as lexically scoped varFlags |= VarNode.IS_LET; } - final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags); + final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, function, varFlags); if (topLevel) { functionDeclarations.add(varNode); } else if (useBlockScope()) { @@ -2725,7 +2754,7 @@ } } - return functionNode; + return function; } private String getDefaultValidFunctionName(final int functionLine) { @@ -2832,15 +2861,19 @@ * Parse function body. * @return function node (body.) */ - private FunctionNode functionBody(final long firstToken, final IdentNode ident, final List parameters, final FunctionNode.Kind kind, final int functionLine) { - FunctionNode functionNode = null; + private Block functionBody(final ParserContextFunctionNode functionNode) { long lastToken = 0L; + ParserContextBlockNode body = null; + final long bodyToken = token; + Block functionBody; + int bodyFinish = 0; + final boolean parseBody; Object endParserState = null; try { // Create a new function block. - functionNode = newFunctionNode(firstToken, ident, parameters, kind, functionLine); + body = newBlock(); assert functionNode != null; final int functionId = functionNode.getId(); parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId(); @@ -2856,6 +2889,7 @@ // just expression as function body final Expression expr = assignmentExpression(true); lastToken = previousToken; + functionNode.setLastToken(previousToken); assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode); // EOL uses length field to store the line number final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken)); @@ -2868,7 +2902,6 @@ final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr); appendStatement(returnNode); } - functionNode.setFinish(lastFinish); } else { expectDontAdvance(LBRACE); if (parseBody || !skipFunctionBody(functionNode)) { @@ -2902,25 +2935,25 @@ // we'll rather just restart parsing from this well-known, friendly token instead. } } + bodyFinish = finish; + functionNode.setLastToken(token); expect(RBRACE); - functionNode.setFinish(finish); } } finally { - functionNode = restoreFunctionNode(functionNode, lastToken); + restoreBlock(body); } // NOTE: we can only do alterations to the function node after restoreFunctionNode. if (parseBody) { - functionNode = functionNode.setEndParserState(lc, endParserState); - } else if (functionNode.getBody().getStatementCount() > 0){ + functionNode.setEndParserState(endParserState); + } else if (!body.getStatements().isEmpty()){ // This is to ensure the body is empty when !parseBody but we couldn't skip parsing it (see // skipFunctionBody() for possible reasons). While it is not strictly necessary for correctness to // enforce empty bodies in nested functions that were supposed to be skipped, we do assert it as // an invariant in few places in the compiler pipeline, so for consistency's sake we'll throw away // nested bodies early if we were supposed to skip 'em. - functionNode = functionNode.setBody(null, functionNode.getBody().setStatements(null, - Collections.emptyList())); + body.setStatements(Collections.emptyList()); } if (reparsedFunction != null) { @@ -2932,20 +2965,20 @@ if (data != null) { // Data can be null if when we originally parsed the file, we removed the function declaration // as it was dead code. - functionNode = functionNode.setFlags(lc, data.getFunctionFlags()); + functionNode.setFlag(data.getFunctionFlags()); // This compensates for missing markEval() in case the function contains an inner function // that contains eval(), that now we didn't discover since we skipped the inner function. if (functionNode.hasNestedEval()) { assert functionNode.hasScopeBlock(); - functionNode = functionNode.setBody(lc, functionNode.getBody().setNeedsScope(null)); + body.setFlag(Block.NEEDS_SCOPE); } } } - printAST(functionNode); - return functionNode; + functionBody = new Block(bodyToken, bodyFinish, body.getFlags(), body.getStatements()); + return functionBody; } - private boolean skipFunctionBody(final FunctionNode functionNode) { + private boolean skipFunctionBody(final ParserContextFunctionNode functionNode) { if (reparsedFunction == null) { // Not reparsing, so don't skip any function body. return false; @@ -3008,13 +3041,13 @@ } } - private void addFunctionDeclarations(final FunctionNode functionNode) { + private void addFunctionDeclarations(final ParserContextFunctionNode functionNode) { VarNode lastDecl = null; for (int i = functionDeclarations.size() - 1; i >= 0; i--) { Statement decl = functionDeclarations.get(i); if (lastDecl == null && decl instanceof VarNode) { decl = lastDecl = ((VarNode)decl).setFlag(VarNode.IS_LAST_FUNCTION_DECLARATION); - lc.setFlag(functionNode, FunctionNode.HAS_FUNCTION_DECLARATIONS); + functionNode.setFlag(FunctionNode.HAS_FUNCTION_DECLARATIONS); } prependStatement(decl); } @@ -3359,29 +3392,31 @@ return "'JavaScript Parsing'"; } - private static void markEval(final LexicalContext lc) { - final Iterator iter = lc.getFunctions(); + private static void markEval(final ParserContext lc) { + final Iterator iter = lc.getFunctions(); boolean flaggedCurrentFn = false; while (iter.hasNext()) { - final FunctionNode fn = iter.next(); + final ParserContextFunctionNode fn = iter.next(); if (!flaggedCurrentFn) { - lc.setFlag(fn, FunctionNode.HAS_EVAL); + fn.setFlag(FunctionNode.HAS_EVAL); flaggedCurrentFn = true; } else { - lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL); + fn.setFlag(FunctionNode.HAS_NESTED_EVAL); } + final ParserContextBlockNode body = lc.getFunctionBody(fn); // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip // parsing a nested function. functionBody() contains code to compensate for the lack of invoking // this method when the parser skips a nested function. - lc.setBlockNeedsScope(lc.getFunctionBody(fn)); + body.setFlag(Block.NEEDS_SCOPE); + fn.setFlag(FunctionNode.HAS_SCOPE_BLOCK); } } private void prependStatement(final Statement statement) { - lc.prependStatement(statement); + lc.prependStatementToCurrentNode(statement); } private void appendStatement(final Statement statement) { - lc.appendStatement(statement); + lc.appendStatementToCurrentNode(statement); } } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContext.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import jdk.nashorn.internal.ir.Statement; + +/** + * A class that tracks the current lexical context of node visitation as a stack of {@code ParserContextNode} nodes. Has special + * methods to retrieve useful subsets of the context. + * + * This is implemented with a primitive array and a stack pointer, because it really makes a difference + * performance wise. None of the collection classes were optimal + */ + +class ParserContext { + + private ParserContextNode[] stack; + private int sp; + + private static final int INITIAL_DEPTH = 16; + + /** + * Constructs a ParserContext, + * initializes the stack + */ + public ParserContext(){ + this.sp = 0; + this.stack = new ParserContextNode[INITIAL_DEPTH]; + } + + /** + * Pushes a new block on top of the context, making it the innermost open block. + * @param node the new node + * @return The node that was pushed + */ + public T push(final T node) { + assert !contains(node); + if (sp == stack.length) { + final ParserContextNode[] newStack = new ParserContextNode[sp * 2]; + System.arraycopy(stack, 0, newStack, 0, sp); + stack = newStack; + } + stack[sp] = node; + sp++; + + return node; + } + + /** + * The topmost node on the stack + * @return The topmost node on the stack + */ + public ParserContextNode peek() { + return stack[sp - 1]; + } + + /** + * Removes and returns the topmost Node from the stack. + * @param node The node expected to be popped, used for sanity check + * @return The removed node + */ + public T pop(final T node) { + --sp; + @SuppressWarnings("unchecked") + final T popped = (T)stack[sp]; + stack[sp] = null; + assert node == popped; + + return popped; + } + + /** + * Tests if a node is on the stack. + * @param node The node to test + * @return true if stack contains node, false otherwise + */ + public boolean contains(final ParserContextNode node) { + for (int i = 0; i < sp; i++) { + if (stack[i] == node) { + return true; + } + } + return false; + } + + /** + * Returns the topmost {@link ParserContextBreakableNode} on the stack, null if none on stack + * @return Returns the topmost {@link ParserContextBreakableNode} on the stack, null if none on stack + */ + private ParserContextBreakableNode getBreakable() { + for (final NodeIterator iter = new NodeIterator<>(ParserContextBreakableNode.class, getCurrentFunction()); iter.hasNext(); ) { + final ParserContextBreakableNode next = iter.next(); + if (next.isBreakableWithoutLabel()) { + return next; + } + } + return null; + } + + + + /** + * Find the breakable node corresponding to this label. + * @param labelName name of the label to search for. If null, the closest breakable node will be returned + * unconditionally, e.g. a while loop with no label + * @return closest breakable node + */ + public ParserContextBreakableNode getBreakable(final String labelName) { + if (labelName != null) { + final ParserContextLabelNode foundLabel = findLabel(labelName); + if (foundLabel != null) { + // iterate to the nearest breakable to the foundLabel + ParserContextBreakableNode breakable = null; + for (final NodeIterator iter = new NodeIterator<>(ParserContextBreakableNode.class, foundLabel); iter.hasNext(); ) { + breakable = iter.next(); + } + return breakable; + } + return null; + } else { + return getBreakable(); + } + } + + /** + * Returns the loop node of the current loop, or null if not inside a loop + * @return loop noder + */ + public ParserContextLoopNode getCurrentLoop() { + final Iterator iter = new NodeIterator<>(ParserContextLoopNode.class, getCurrentFunction()); + return iter.hasNext() ? iter.next() : null; + } + + private ParserContextLoopNode getContinueTo() { + return getCurrentLoop(); + } + + /** + * Find the continue target node corresponding to this label. + * @param labelName label name to search for. If null the closest loop node will be returned unconditionally, e.g. a + * while loop with no label + * @return closest continue target node + */ + public ParserContextLoopNode getContinueTo(final String labelName) { + if (labelName != null) { + final ParserContextLabelNode foundLabel = findLabel(labelName); + if (foundLabel != null) { + // iterate to the nearest loop to the foundLabel + ParserContextLoopNode loop = null; + for (final NodeIterator iter = new NodeIterator<>(ParserContextLoopNode.class, foundLabel); iter.hasNext(); ) { + loop = iter.next(); + } + return loop; + } + return null; + } + return getContinueTo(); + } + + /** + * Get the function body of a function node on the stack. + * This will trigger an assertion if node isn't present + * @param functionNode function node + * @return body of function node + */ + public ParserContextBlockNode getFunctionBody(final ParserContextFunctionNode functionNode) { + for (int i = sp - 1; i >= 0 ; i--) { + if (stack[i] == functionNode) { + return (ParserContextBlockNode)stack[i + 1]; + } + } + throw new AssertionError(functionNode.getName() + " not on context stack"); + } + + /** + * Check the stack for a given label node by name + * @param name name of the label + * @return LabelNode if found, null otherwise + */ + public ParserContextLabelNode findLabel(final String name) { + for (final Iterator iter = new NodeIterator<>(ParserContextLabelNode.class, getCurrentFunction()); iter.hasNext(); ) { + final ParserContextLabelNode next = iter.next(); + if (next.getLabelName().equals(name)) { + return next; + } + } + return null; + } + + /** + * Prepends a statement to the current node. + * @param statement The statement to prepend + */ + public void prependStatementToCurrentNode(final Statement statement) { + assert statement != null; + stack[sp - 1].prependStatement(statement); + } + + /** + * Appends a statement to the current Node. + * @param statement The statement to append + */ + public void appendStatementToCurrentNode(final Statement statement) { + assert statement != null; + stack[sp - 1].appendStatement(statement); + } + + /** + * Returns the innermost function in the context. + * @return the innermost function in the context. + */ + public ParserContextFunctionNode getCurrentFunction() { + for (int i = sp - 1; i >= 0; i--) { + if (stack[i] instanceof ParserContextFunctionNode) { + return (ParserContextFunctionNode) stack[i]; + } + } + return null; + } + + /** + * Returns an iterator over all blocks in the context, with the top block (innermost lexical context) first. + * @return an iterator over all blocks in the context. + */ + public Iterator getBlocks() { + return new NodeIterator<>(ParserContextBlockNode.class); + } + + /** + * Returns the innermost block in the context. + * @return the innermost block in the context. + */ + public ParserContextBlockNode getCurrentBlock() { + return getBlocks().next(); + } + + /** + * The last statement added to the context + * @return The last statement added to the context + */ + public Statement getLastStatement() { + if (sp == 0) { + return null; + } + final ParserContextNode top = stack[sp - 1]; + final int s = top.getStatements().size(); + return s == 0 ? null : top.getStatements().get(s - 1); + } + + /** + * Returns an iterator over all functions in the context, with the top (innermost open) function first. + * @return an iterator over all functions in the context. + */ + public Iterator getFunctions() { + return new NodeIterator<>(ParserContextFunctionNode.class); + } + + private class NodeIterator implements Iterator { + private int index; + private T next; + private final Class clazz; + private ParserContextNode until; + + NodeIterator(final Class clazz) { + this(clazz, null); + } + + NodeIterator(final Class clazz, final ParserContextNode until) { + this.index = sp - 1; + this.clazz = clazz; + this.until = until; + this.next = findNext(); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public T next() { + if (next == null) { + throw new NoSuchElementException(); + } + final T lnext = next; + next = findNext(); + return lnext; + } + + @SuppressWarnings("unchecked") + private T findNext() { + for (int i = index; i >= 0; i--) { + final Object node = stack[i]; + if (node == until) { + return null; + } + if (clazz.isAssignableFrom(node.getClass())) { + index = i - 1; + return (T)node; + } + } + return null; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextBaseNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextBaseNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +import java.util.ArrayList; +import java.util.List; +import jdk.nashorn.internal.ir.Statement; + +/** + * Base class for parser context nodes + */ +abstract class ParserContextBaseNode implements ParserContextNode { + /** + * Flags for this node + */ + protected int flags; + + private List statements; + + /** + * Constructor + */ + public ParserContextBaseNode() { + this.statements = new ArrayList<>(); + } + + /** + * @return The flags for this node + */ + @Override + public int getFlags() { + return flags; + } + + /** + * Returns a single flag + * @param flag + * @return A single flag + */ + protected int getFlag(final int flag) { + return (flags & flag); + } + + /** + * @param flag + * @return the new flags + */ + @Override + public int setFlag(final int flag) { + flags |= flag; + return flags; + } + + /** + * @return The list of statements that belongs to this node + */ + @Override + public List getStatements() { + return statements; + } + + /** + * @param statements + */ + @Override + public void setStatements(final List statements) { + this.statements = statements; + } + + /** + * Adds a Statement at the end of the Statementlist + * @param statement The statement to add + */ + @Override + public void appendStatement(final Statement statement) { + this.statements.add(statement); + } + + /** + * Adds a statement at the begining of the statementlist + * @param statement The statement to add + */ + @Override + public void prependStatement(final Statement statement) { + this.statements.add(0, statement); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextBlockNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextBlockNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +/** + * A ParserContextNode that represents a block that is currently being parsed + */ +class ParserContextBlockNode extends ParserContextBaseNode implements ParserContextBreakableNode { + + private final long token; + + /** + * Constructs a ParserContextBlockNode + * + * @param token The first token of the block + */ + public ParserContextBlockNode(final long token) { + this.token = token; + } + + @Override + public boolean isBreakableWithoutLabel() { + return false; + } + + /** + * Get token + * @return The first token of the block + */ + public long getToken() { + return token; + } + +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextBreakableNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextBreakableNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +import jdk.nashorn.internal.ir.BreakNode; + +/** + * An interface that is implemented by ParserContextNodes that can + * contain a {@link BreakNode} + */ +interface ParserContextBreakableNode extends ParserContextNode { + + /** + * Returns true if not i breakable without label, false otherwise + * @return Returns true if not i breakable without label, false otherwise + */ + boolean isBreakableWithoutLabel(); +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextFunctionNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextFunctionNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +import java.util.List; +import jdk.nashorn.internal.codegen.Namespace; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.IdentNode; + +/** + * ParserContextNode that represents a function that is currently being parsed + */ +class ParserContextFunctionNode extends ParserContextBaseNode { + + /** Function name */ + private final String name; + + /** Function identifier node */ + private final IdentNode ident; + + /** Name space for function */ + private final Namespace namespace; + + /** Line number for function declaration */ + private final int line; + + /** Function node kind, see {@link FunctionNode#Kind} */ + private final FunctionNode.Kind kind; + + /** List of parameter identifiers for function */ + private final List parameters; + + /** Token for function start */ + private final long token; + + /** Last function token */ + private long lastToken; + + /** Opaque node for parser end state, see {@link Parser} */ + private Object endParserState; + + /** + * @param token The token for the function + * @param ident External function name + * @param name Internal name of the function + * @param namespace Function's namespace + * @param line The source line of the function + * @param kind Function kind + * @param parameters The parameters of the function + */ + public ParserContextFunctionNode(final long token, final IdentNode ident, final String name, final Namespace namespace, final int line, final FunctionNode.Kind kind, final List parameters) { + this.ident = ident; + this.namespace = namespace; + this.line = line; + this.kind = kind; + this.name = name; + this.parameters = parameters; + this.token = token; + } + + /** + * @return Internal name of the function + */ + public String getName() { + return name; + } + + /** + * @return The external identifier for the function + */ + public IdentNode getIdent() { + return ident; + } + + /** + * + * @return true if function is the program function + */ + public boolean isProgram() { + return getFlag(FunctionNode.IS_PROGRAM) != 0; + } + + /** + * @return if function in strict mode + */ + public boolean isStrict() { + return getFlag(FunctionNode.IS_STRICT) != 0; + } + + /** + * @return true if the function has nested evals + */ + public boolean hasNestedEval() { + return getFlag(FunctionNode.HAS_NESTED_EVAL) != 0; + } + + /** + * Returns true if any of the blocks in this function create their own scope. + * @return true if any of the blocks in this function create their own scope. + */ + public boolean hasScopeBlock() { + return getFlag(FunctionNode.HAS_SCOPE_BLOCK) != 0; + } + + /** + * Create a unique name in the namespace of this FunctionNode + * @param base prefix for name + * @return base if no collision exists, otherwise a name prefix with base + */ + public String uniqueName(final String base) { + return namespace.uniqueName(base); + } + + /** + * @return line number of the function + */ + public int getLineNumber() { + return line; + } + + /** + * @return The kind if function + */ + public FunctionNode.Kind getKind() { + return kind; + } + + /** + * Get parameters + * @return The parameters of the function + */ + public List getParameters() { + return parameters; + } + + /** + * Set last token + * @param token New last token + */ + public void setLastToken(final long token) { + this.lastToken = token; + + } + + /** + * @return lastToken Function's last token + */ + public long getLastToken() { + return lastToken; + } + + /** + * Returns the ParserState of when the parsing of this function was ended + * @return endParserState The end parser state + */ + public Object getEndParserState() { + return endParserState; + } + + /** + * Sets the ParserState of when the parsing of this function was ended + * @param endParserState The end parser state + */ + public void setEndParserState(final Object endParserState) { + this.endParserState = endParserState; + } + + /** + * Returns the if of this function + * @return The function id + */ + public int getId() { + return isProgram() ? -1 : Token.descPosition(token); + } +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextLabelNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextLabelNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,52 @@ +/** +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +/** + * ParserContextNode that represents a LabelNode + */ +class ParserContextLabelNode extends ParserContextBaseNode { + + /** Name for label */ + private final String name; + + /** + * Constructor + * + * @param name The name of the label + */ + public ParserContextLabelNode(final String name) { + this.name = name; + } + + /** + * Returns the name of the label + * @return name of label + */ + public String getLabelName() { + return name; + } +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextLoopNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextLoopNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +/** + * A ParserContextNode that represents a loop that is being parsed + */ +class ParserContextLoopNode extends ParserContextBaseNode implements ParserContextBreakableNode { + + @Override + public boolean isBreakableWithoutLabel() { + return true; + } + +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +import java.util.List; +import jdk.nashorn.internal.ir.Statement; + +/** + * Used for keeping state when needed in the parser. + */ +interface ParserContextNode { + /** + * @return The flags for this node + */ + public int getFlags(); + + /** + * @param flag The flag to set + * @return All current flags after update + */ + public int setFlag(final int flag); + + /** + * @return The list of statements that belongs to this node + */ + public List getStatements(); + + /** + * @param statements The statement list + */ + public void setStatements(final List statements); + + /** + * Adds a Statement at the end of the Statementlist + * @param statement The statement to add + */ + public void appendStatement(final Statement statement); + + /** + * Adds a statement at the begining of the statementlist + * @param statement The statement to add + */ + public void prependStatement(final Statement statement); + +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextSwitchNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextSwitchNode.java Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.parser; + +/** + * A ParserContextNode that represents a SwithcNode that is currently being parsed + */ +class ParserContextSwitchNode extends ParserContextBaseNode implements ParserContextBreakableNode { + + @Override + public boolean isBreakableWithoutLabel() { + return true; + } +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Jul 05 20:04:43 2017 +0200 @@ -483,7 +483,7 @@ final int cacheSize = env._class_cache_size; if (cacheSize > 0) { - classCache = new ClassCache(cacheSize); + classCache = new ClassCache(this, cacheSize); } if (env._persistent_cache) { @@ -1261,17 +1261,23 @@ * Cache for compiled script classes. */ @SuppressWarnings("serial") - private static class ClassCache extends LinkedHashMap { + @Logger(name="classcache") + private static class ClassCache extends LinkedHashMap implements Loggable { private final int size; private final ReferenceQueue> queue; + private final DebugLogger log; - ClassCache(final int size) { + ClassCache(final Context context, final int size) { super(size, 0.75f, true); this.size = size; this.queue = new ReferenceQueue<>(); + this.log = initLogger(context); } void cache(final Source source, final Class clazz) { + if (log.isEnabled()) { + log.info("Caching ", source, " in class cache"); + } put(source, new ClassReference(clazz, queue, source)); } @@ -1283,9 +1289,28 @@ @Override public ClassReference get(final Object key) { for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) { - remove(ref.source); + final Source source = ref.source; + if (log.isEnabled()) { + log.info("Evicting ", source, " from class cache."); + } + remove(source); + } + + final ClassReference ref = super.get(key); + if (ref != null && log.isEnabled()) { + log.info("Retrieved class reference for ", ref.source, " from class cache"); } - return super.get(key); + return ref; + } + + @Override + public DebugLogger initLogger(final Context context) { + return context.getLogger(getClass()); + } + + @Override + public DebugLogger getLogger() { + return log; } } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/GlobalConstants.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/GlobalConstants.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/GlobalConstants.java Wed Jul 05 20:04:43 2017 +0200 @@ -31,7 +31,6 @@ import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.getProgramPoint; import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.SwitchPoint; @@ -328,7 +327,9 @@ } if (!acc.mayRetry()) { - log.info("*** SET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation()); + if (log.isEnabled()) { + log.fine("*** SET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation()); + } return null; } @@ -404,7 +405,9 @@ } if (acc.hasBeenInvalidated() || acc.guardFailed()) { - log.fine("*** GET: Giving up on " + quote(name) + " - retry count has exceeded"); + if (log.isEnabled()) { + log.info("*** GET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation()); + } return null; } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Jul 05 20:04:43 2017 +0200 @@ -676,6 +676,22 @@ return addCode(lookup(fnInit).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); } + /** + * Returns the return type of a function specialization for particular parameter types.
+ * Be aware that the way this is implemented, it forces full materialization (compilation and installation) of + * code for that specialization. + * @param callSiteType the parameter types at the call site. It must include the mandatory {@code callee} and + * {@code this} parameters, so it needs to start with at least {@code ScriptFunction.class} and + * {@code Object.class} class. Since the return type of the function is calculated from the code itself, it is + * irrelevant and should be set to {@code Object.class}. + * @param runtimeScope a current runtime scope. Can be null but when it's present it will be used as a source of + * current runtime values that can improve the compiler's type speculations (and thus reduce the need for later + * recompilations) if the specialization is not already present and thus needs to be freshly compiled. + * @return the return type of the function specialization. + */ + public Class getReturnType(final MethodType callSiteType, final ScriptObject runtimeScope) { + return getBest(callSiteType, runtimeScope, CompiledFunction.NO_FUNCTIONS).type().returnType(); + } @Override synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection forbidden) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java Wed Jul 05 20:04:43 2017 +0200 @@ -210,6 +210,19 @@ } @Override + protected Object invokeNoSuchProperty(final String name, final int programPoint) { + FindProperty find = expression.findProperty(NO_SUCH_PROPERTY_NAME, true); + if (find != null) { + final Object func = find.getObjectValue(); + if (func instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)func, expression, name); + } + } + + return getProto().invokeNoSuchProperty(name, programPoint); + } + + @Override public void setSplitState(final int state) { getNonWithParent().setSplitState(state); } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Wed Jul 05 20:04:43 2017 +0200 @@ -30,6 +30,7 @@ import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -37,6 +38,7 @@ import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; +import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; @@ -120,6 +122,11 @@ */ public abstract Class getElementType(); + @Override + public Type getOptimisticType() { + return Type.typeFor(getElementType()); + } + /** * Look up a continuous array element getter * @param get getter, sometimes combined with a has check that throws CCE on failure for relink diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java Wed Jul 05 20:04:43 2017 +0200 @@ -66,9 +66,9 @@ public Object[] asObjectArray() { final Object[] value = super.asObjectArray(); - if (lo <= Integer.MAX_VALUE) { - final int intHi = (int)Math.min(hi, Integer.MAX_VALUE); - for (int i = (int)lo; i <= intHi; i++) { + if (lo < Integer.MAX_VALUE) { + final int end = (int)Math.min(hi + 1, Integer.MAX_VALUE); + for (int i = (int)lo; i < end; i++) { value[i] = ScriptRuntime.UNDEFINED; } } @@ -81,9 +81,9 @@ final Object value = super.asArrayOfType(componentType); final Object undefValue = convertUndefinedValue(componentType); - if (lo <= Integer.MAX_VALUE) { - final int intHi = (int)Math.min(hi, Integer.MAX_VALUE); - for (int i = (int)lo; i <= intHi; i++) { + if (lo < Integer.MAX_VALUE) { + final int end = (int)Math.min(hi + 1, Integer.MAX_VALUE); + for (int i = (int)lo; i < end; i++) { Array.set(value, i, undefValue); } } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,10 +26,10 @@ package jdk.nashorn.internal.runtime.arrays; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Arrays; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -73,7 +73,7 @@ @Override public Object[] asObjectArray() { - return toObjectArray(); + return toObjectArray(true); } @SuppressWarnings("unused") @@ -116,9 +116,9 @@ return super.asArrayOfType(componentType); } - private Object[] toObjectArray() { + private Object[] toObjectArray(final boolean trim) { assert length <= array.length : "length exceeds internal array size"; - final Object[] oarray = new Object[array.length]; + final Object[] oarray = new Object[trim ? (int)length : array.length]; for (int index = 0; index < length; index++) { oarray[index] = Integer.valueOf(array[index]); @@ -158,7 +158,7 @@ } private ObjectArrayData convertToObject() { - return new ObjectArrayData(toObjectArray(), (int)length); + return new ObjectArrayData(toObjectArray(false), (int)length); } @Override @@ -257,11 +257,6 @@ } @Override - public Type getOptimisticType() { - return Type.INT; - } - - @Override public int getInt(final int index) { return array[index]; } diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Wed Jul 05 20:04:43 2017 +0200 @@ -27,10 +27,10 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; import static jdk.nashorn.internal.lookup.Lookup.MH; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Arrays; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -67,12 +67,12 @@ @Override public Object[] asObjectArray() { - return toObjectArray(array, (int)length); + return toObjectArray(true); } - private static Object[] toObjectArray(final long[] array, final int length) { + private Object[] toObjectArray(final boolean trim) { assert length <= array.length : "length exceeds internal array size"; - final Object[] oarray = new Object[array.length]; + final Object[] oarray = new Object[trim ? (int)length : array.length]; for (int index = 0; index < length; index++) { oarray[index] = Long.valueOf(array[index]); @@ -89,7 +89,7 @@ return super.asArrayOfType(componentType); } - private static double[] toDoubleArray(final long[] array, final int length) { + private double[] toDoubleArray() { assert length <= array.length : "length exceeds internal array size"; final double[] darray = new double[array.length]; @@ -107,9 +107,9 @@ } final int len = (int)length; if (type == Double.class) { - return new NumberArrayData(LongArrayData.toDoubleArray(array, len), len); + return new NumberArrayData(toDoubleArray(), len); } - return new ObjectArrayData(LongArrayData.toObjectArray(array, len), len); + return new ObjectArrayData(toObjectArray(false), len); } @Override @@ -186,11 +186,6 @@ return convert(Double.class).set(index, value, strict); } - @Override - public Type getOptimisticType() { - return Type.LONG; - } - private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "getElem", long.class, int.class).methodHandle(); private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "setElem", void.class, int.class, long.class).methodHandle(); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Wed Jul 05 20:04:43 2017 +0200 @@ -28,10 +28,10 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Arrays; -import jdk.nashorn.internal.codegen.types.Type; /** * Implementation of {@link ArrayData} as soon as a double has been @@ -66,12 +66,12 @@ @Override public Object[] asObjectArray() { - return toObjectArray(array, (int)length); + return toObjectArray(true); } - private static Object[] toObjectArray(final double[] array, final int length) { + private Object[] toObjectArray(final boolean trim) { assert length <= array.length : "length exceeds internal array size"; - final Object[] oarray = new Object[array.length]; + final Object[] oarray = new Object[trim ? (int)length : array.length]; for (int index = 0; index < length; index++) { oarray[index] = Double.valueOf(array[index]); @@ -91,7 +91,7 @@ public ArrayData convert(final Class type) { if (type != Double.class && type != Integer.class && type != Long.class) { final int len = (int)length; - return new ObjectArrayData(NumberArrayData.toObjectArray(array, len), len); + return new ObjectArrayData(toObjectArray(false), len); } return this; } @@ -166,11 +166,6 @@ return this; } - @Override - public Type getOptimisticType() { - return Type.NUMBER; - } - private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), NumberArrayData.class, "getElem", double.class, int.class).methodHandle(); private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), NumberArrayData.class, "setElem", void.class, int.class, double.class).methodHandle(); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Wed Jul 05 20:04:43 2017 +0200 @@ -26,10 +26,10 @@ package jdk.nashorn.internal.runtime.arrays; import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Arrays; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -155,15 +155,11 @@ @Override public ArrayData setEmpty(final long lo, final long hi) { - Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, Integer.MAX_VALUE), ScriptRuntime.EMPTY); + // hi parameter is inclusive, but Arrays.fill toIndex parameter is exclusive + Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi + 1, Integer.MAX_VALUE), ScriptRuntime.EMPTY); return this; } - @Override - public Type getOptimisticType() { - return Type.OBJECT; - } - private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), ObjectArrayData.class, "getElem", Object.class, int.class).methodHandle(); private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), ObjectArrayData.class, "setElem", void.class, int.class, Object.class).methodHandle(); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java Wed Jul 05 20:04:43 2017 +0200 @@ -78,7 +78,7 @@ for (final Map.Entry entry : sparseMap.entrySet()) { final long key = entry.getKey(); - if (key <= Integer.MAX_VALUE) { + if (key < Integer.MAX_VALUE) { objArray[(int)key] = entry.getValue(); } else { break; // ascending key order diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Wed Jul 05 20:04:43 2017 +0200 @@ -152,6 +152,7 @@ static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE); static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE); + private static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class); private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class); private static final Type STRING_TYPE = Type.getType(String.class); private static final Type METHOD_TYPE_TYPE = Type.getType(MethodType.class); @@ -536,8 +537,8 @@ final int argLen = originalArgTypes.length; final Type[] newArgTypes = new Type[argLen + 1]; - // Insert ScriptFunction|Object as the last argument to the constructor - final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : OBJECT_TYPE; + // Insert ScriptFunction|ScriptObject as the last argument to the constructor + final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : SCRIPT_OBJECT_TYPE; newArgTypes[argLen] = extraArgumentType; System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen); @@ -588,6 +589,34 @@ // Initialize converters generateConverterInit(mv, fromFunction); endInitMethod(mv); + + if (! fromFunction) { + newArgTypes[argLen] = OBJECT_TYPE; + final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, + Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); + generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor()); + } + } + + // Object additional param accepting constructor - generated to handle null and undefined value + // for script adapters. This is effectively to throw TypeError on such script adapters. See + // JavaAdapterServices.getHandle as well. + private void generateOverridingConstructorWithObjectParam(final InstructionAdapter mv, final Constructor ctor, final String ctorDescriptor) { + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + final Class[] argTypes = ctor.getParameterTypes(); + int offset = 1; // First arg is at position 1, after this. + for (int i = 0; i < argTypes.length; ++i) { + final Type argType = Type.getType(argTypes[i]); + mv.load(offset, argType); + offset += argType.getSize(); + } + mv.invokespecial(superClassName, INIT, ctorDescriptor, false); + mv.visitVarInsn(ALOAD, offset); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ACONST_NULL); + mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_OBJECT_DESCRIPTOR, false); + endInitMethod(mv); } private static void endInitMethod(final InstructionAdapter mv) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Wed Jul 05 20:04:43 2017 +0200 @@ -39,6 +39,7 @@ import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.ScriptObject; /** * This class encapsulates the bytecode of the adapter class and can be used to load it into the JVM as an actual Class. @@ -51,7 +52,7 @@ private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader"); private static final AccessControlContext GET_CONTEXT_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_GET_CONTEXT); private static final Collection VISIBLE_INTERNAL_CLASS_NAMES = Collections.unmodifiableCollection(new HashSet<>( - Arrays.asList(JavaAdapterServices.class.getName(), ScriptFunction.class.getName(), JSType.class.getName()))); + Arrays.asList(JavaAdapterServices.class.getName(), ScriptObject.class.getName(), ScriptFunction.class.getName(), JSType.class.getName()))); private final String className; private final byte[] classBytes; diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java Wed Jul 05 20:04:43 2017 +0200 @@ -47,7 +47,6 @@ import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.commons.InstructionAdapter; -import jdk.nashorn.api.scripting.ScriptUtils; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; @@ -220,7 +219,7 @@ * @return the filtered return value. */ public static Object exportReturnValue(final Object obj) { - return ScriptUtils.wrap(NashornBeansLinker.exportArgument(obj)); + return NashornBeansLinker.exportArgument(obj, true); } /** diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Wed Jul 05 20:04:43 2017 +0200 @@ -35,17 +35,28 @@ import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.Lookup; +import jdk.nashorn.api.scripting.ScriptUtils; +import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.runtime.ConsString; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.options.Options; /** * This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally - * observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add + * observable (currently ConsString and ScriptObject) to Java APIs, but rather that we flatten it into a String. We can't just add * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when * the target method handle parameter signature is {@code Object}. */ public class NashornBeansLinker implements GuardingDynamicLinker { + // System property to control whether to wrap ScriptObject->ScriptObjectMirror for + // Object type arguments of Java method calls, field set and array set. + private static final boolean MIRROR_ALWAYS = Options.getBooleanProperty("nashorn.mirror.always", true); + private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class); + private static final MethodHandle EXPORT_NATIVE_ARRAY = new Lookup(MethodHandles.lookup()).findOwnStatic("exportNativeArray", Object.class, NativeArray.class); + private static final MethodHandle EXPORT_SCRIPT_OBJECT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportScriptObject", Object.class, ScriptObject.class); + private static final MethodHandle IMPORT_RESULT = new Lookup(MethodHandles.lookup()).findOwnStatic("importResult", Object.class, Object.class); private final BeansLinker beansLinker = new BeansLinker(); @@ -67,8 +78,39 @@ return delegateLinker.getGuardedInvocation(linkRequest, new NashornBeansLinkerServices(linkerServices)); } - static Object exportArgument(final Object arg) { - return arg instanceof ConsString ? arg.toString() : arg; + @SuppressWarnings("unused") + private static Object exportArgument(final Object arg) { + return exportArgument(arg, MIRROR_ALWAYS); + } + + @SuppressWarnings("unused") + private static Object exportNativeArray(final NativeArray arg) { + return exportArgument(arg, MIRROR_ALWAYS); + } + + @SuppressWarnings("unused") + private static Object exportScriptObject(final ScriptObject arg) { + return exportArgument(arg, MIRROR_ALWAYS); + } + + @SuppressWarnings("unused") + private static Object exportScriptArray(final NativeArray arg) { + return exportArgument(arg, MIRROR_ALWAYS); + } + + static Object exportArgument(final Object arg, final boolean mirrorAlways) { + if (arg instanceof ConsString) { + return arg.toString(); + } else if (mirrorAlways && arg instanceof ScriptObject) { + return ScriptUtils.wrap((ScriptObject)arg); + } else { + return arg; + } + } + + @SuppressWarnings("unused") + private static Object importResult(final Object arg) { + return ScriptUtils.unwrap(arg); } private static class NashornBeansLinkerServices implements LinkerServices { @@ -80,23 +122,50 @@ @Override public MethodHandle asType(final MethodHandle handle, final MethodType fromType) { - final MethodHandle typed = linkerServices.asType(handle, fromType); - final MethodType handleType = handle.type(); final int paramCount = handleType.parameterCount(); assert fromType.parameterCount() == handleType.parameterCount(); + MethodType newFromType = fromType; MethodHandle[] filters = null; for(int i = 0; i < paramCount; ++i) { - if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) { - if(filters == null) { + final MethodHandle filter = argConversionFilter(handleType.parameterType(i), fromType.parameterType(i)); + if (filter != null) { + if (filters == null) { filters = new MethodHandle[paramCount]; } - filters[i] = EXPORT_ARGUMENT; + // "erase" specific type with Object type or else we'll get filter mismatch + newFromType = newFromType.changeParameterType(i, Object.class); + filters[i] = filter; } } - return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed; + final MethodHandle typed = linkerServices.asType(handle, newFromType); + MethodHandle result = filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed; + // Filter Object typed return value for possible ScriptObjectMirror. We convert + // ScriptObjectMirror as ScriptObject (if it is mirror from current global). + if (MIRROR_ALWAYS && areBothObjects(handleType.returnType(), fromType.returnType())) { + result = MethodHandles.filterReturnValue(result, IMPORT_RESULT); + } + + return result; + } + + private static MethodHandle argConversionFilter(final Class handleType, final Class fromType) { + if (handleType == Object.class) { + if (fromType == Object.class) { + return EXPORT_ARGUMENT; + } else if (fromType == NativeArray.class) { + return EXPORT_NATIVE_ARRAY; + } else if (fromType == ScriptObject.class) { + return EXPORT_SCRIPT_OBJECT; + } + } + return null; + } + + private static boolean areBothObjects(final Class handleType, final Class fromType) { + return handleType == Object.class && fromType == Object.class; } @Override @@ -104,10 +173,6 @@ return Implementation.asTypeLosslessReturn(this, handle, fromType); } - private static boolean shouldConvert(final Class handleType, final Class fromType) { - return handleType == Object.class && fromType == Object.class; - } - @Override public MethodHandle getTypeConverter(final Class sourceType, final Class targetType) { return linkerServices.getTypeConverter(sourceType, targetType); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornLinker.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornLinker.java Wed Jul 05 20:04:43 2017 +0200 @@ -292,7 +292,7 @@ @SuppressWarnings("unused") private static Object createMirror(final Object obj) { - return ScriptUtils.wrap(obj); + return obj instanceof ScriptObject? ScriptUtils.wrap((ScriptObject)obj) : obj; } private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Jul 05 20:04:43 2017 +0200 @@ -73,6 +73,7 @@ type.error.not.an.object={0} is not an Object type.error.not.a.boolean={0} is not a Boolean type.error.not.a.date={0} is not a Date +type.error.not.a.java.importer={0} is not a JavaImporter object type.error.not.a.number={0} is not a Number type.error.not.a.regexp={0} is not a RegExp type.error.not.a.string={0} is not a String diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/mozilla_compat.js --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Wed Jul 05 20:04:43 2017 +0200 @@ -105,7 +105,7 @@ if (arguments.length < 1 || arguments.length > 2 ) { throw "sync(function [,object]) parameter count mismatch"; } - return Packages.jdk.nashorn.api.scripting.ScriptUtils.makeSynchronizedFunction(func, syncobj); + return Java.synchronized(func, syncobj); } }); @@ -160,7 +160,7 @@ configurable: true, enumerable: false, writable: true, value: function(state) { if (! state) { - state = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap()); + state = java.util.Collections.newSetFromMap(new java.util.HashMap()); } if (state.contains(this)) { return "{}"; diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/basic/JDK-8060011.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8060011.js Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8060011: Concatenating an array and converting it to Java gives wrong result + * + * @test + * @run + */ + + +function compareAsJavaArrays(a1, a2) { + var ja1 = Java.to(a1); + var ja2 = Java.to(a2); + if (ja1.length !== ja2.length) { + throw "different length"; + } + for (var i = 0; i < ja1.length; i++) { + if (ja1[i] !== ja2[i]) { + throw "different element at " + i; + } + } + if (java.util.Arrays.toString(ja1) !== java.util.Arrays.toString(ja2)) { + throw "different string representation"; + } +} + +compareAsJavaArrays([0, 1, 2, 3], + [0].concat([1, 2, 3])); +compareAsJavaArrays([1000000000, 2000000000, 3000000000, 4000000000], + [1000000000].concat([2000000000, 3000000000, 4000000000])); +compareAsJavaArrays([0.5, 1.5, 2.5, 3.5], + [0.5].concat([1.5, 2.5, 3.5])); +compareAsJavaArrays(["0", "1", "2", "3"], + ["0"].concat(["1", "2", "3"])); + + + diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/basic/JDK-8060101.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8060101.js Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter + * + * @test + * @run + */ + +var constant = 0.50; +var ind = 0.0; + +// make sure callsites are exercised quite a few times +// to induce megamorphic callsite for with/JavaImporter +// combo - which triggered that AssertionError. +for (var i = 0; i < 50; i++) { + var math = new JavaImporter(java.lang.StrictMath); + ind += 10.0; + with (math) { + StrictMath.exp(-constant*ind); + } +} + +for (var i = 0; i < 50; i++) { + var math = new JavaImporter(java.lang.StrictMath); + try { + math.Foo(); + } catch (e) { + if (! (e instanceof TypeError)) { + throw e; + } + } +} diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/basic/JDK-8061113.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8061113.js Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8061113: Boolean used as optimistic call return type + * + * @test + * @run + */ + +function testcase() { + var a = {x:0}; + return (function () {return a.x === 0})(); +} +print(testcase()); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/basic/JDK-8061113.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8061113.js.EXPECTED Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,1 @@ +true diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/basic/convert.js --- a/nashorn/test/script/basic/convert.js Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/test/script/basic/convert.js Wed Jul 05 20:04:43 2017 +0200 @@ -42,7 +42,7 @@ // object to Map obj = { foo: 333, bar: 'hello'}; -var map = ScriptUtils.convert(obj, java.util.Map.class); +var map = ScriptUtils.wrap(obj); print(map instanceof java.util.Map); for (m in map) { print(m + " " + map[m]); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/nosecurity/JDK-8044798.js --- a/nashorn/test/script/nosecurity/JDK-8044798.js Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/test/script/nosecurity/JDK-8044798.js Wed Jul 05 20:04:43 2017 +0200 @@ -25,6 +25,8 @@ * JDK-8044798: API for debugging Nashorn * * @test + * @option -Dnashorn.mirror.always=false + * @fork * @run */ diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/script/nosecurity/JDK-8060688.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/nosecurity/JDK-8060688.js Wed Jul 05 20:04:43 2017 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8060688: Nashorn: Generated script class name fails --verify-code for names with special chars + * + * @test + * @run + */ + +var NashornEngineFactory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory"); +var ScriptEngine = Java.type("javax.script.ScriptEngine"); +var ScriptContext = Java.type("javax.script.ScriptContext"); + +var factory = new NashornEngineFactory(); + +var e = factory.getScriptEngine("--verify-code"); + +function evalAndCheck(code) { + try { + e.eval(code); + } catch (exp) { + exp.printStackTrace(); + } +} + +// check default name +evalAndCheck("var a = 3"); +// check few names with special chars +var scontext = e.context; +scontext.setAttribute(ScriptEngine.FILENAME, "", ScriptContext.ENGINE_SCOPE); +evalAndCheck("var h = 'hello'"); +scontext.setAttribute(ScriptEngine.FILENAME, "[myscript]", ScriptContext.ENGINE_SCOPE); +evalAndCheck("var foo = 'world'"); +scontext.setAttribute(ScriptEngine.FILENAME, ";/\\$.", ScriptContext.ENGINE_SCOPE); +evalAndCheck("var foo = 'helloworld'"); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -168,42 +168,6 @@ } } - @Test - /** - * Check that script can't implement sensitive package interfaces. - */ - public void checkSensitiveInterfaceImplTest() throws ScriptException { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Object[] holder = new Object[1]; - e.put("holder", holder); - // put an empty script object into array - e.eval("holder[0] = {}"); - // holder[0] is an object of some subclass of ScriptObject - final Class ScriptObjectClass = holder[0].getClass().getSuperclass(); - final Class PropertyAccessClass = ScriptObjectClass.getInterfaces()[0]; - // implementation methods for PropertyAccess class - e.eval("function set() {}; function get() {}; function getInt(){} " + - "function getDouble(){}; function getLong() {}; " + - "this.delete = function () {}; function has() {}; " + - "function hasOwnProperty() {}"); - - // get implementation of a restricted package interface - try { - log(Objects.toString(((Invocable)e).getInterface((Class)PropertyAccessClass))); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (! (exp instanceof SecurityException)) { - fail("SecurityException expected, got " + exp); - } - } - } - // @bug 8032948: Nashorn linkages awry public static class FakeProxy extends Proxy { public FakeProxy(final InvocationHandler ih) { diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -38,6 +38,7 @@ import java.util.concurrent.Callable; import javax.script.Compilable; import javax.script.CompiledScript; +import javax.script.Invocable; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; @@ -629,6 +630,40 @@ assertEquals(enumerable, Boolean.FALSE); } + public static class Context { + private Object myobj; + + public void set(Object o) { + myobj = o; + } + + public Object get() { + return myobj; + } + } + + // @bug 8050977: Java8 Javascript Nashorn exception: + // no current Global instance for nashorn + @Test + public void currentGlobalMissingTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + + final Context ctx = new Context(); + e.put("ctx", ctx); + e.eval("var obj = { foo: function(str) { return str.toUpperCase() } }"); + e.eval("ctx.set(obj)"); + final Invocable inv = (Invocable)e; + assertEquals("HELLO", inv.invokeMethod(ctx.get(), "foo", "hello")); + // try object literal + e.eval("ctx.set({ bar: function(str) { return str.toLowerCase() } })"); + assertEquals("hello", inv.invokeMethod(ctx.get(), "bar", "HELLO")); + // try array literal + e.eval("var arr = [ 'hello', 'world' ]"); + e.eval("ctx.set(arr)"); + assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", "")); + } + private static void checkProperty(final ScriptEngine e, final String name) throws ScriptException { final String value = System.getProperty(name); diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java --- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -72,6 +72,7 @@ options.set("print.parse", true); options.set("scripting", true); options.set("const.as.var", true); + options.set("verify.code", true); final ErrorManager errors = new ErrorManager() { @Override diff -r d1480cb49283 -r 98b357b2e8a6 nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java --- a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Thu Oct 16 14:55:17 2014 -0700 +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Wed Jul 05 20:04:43 2017 +0200 @@ -325,4 +325,29 @@ ); assertEquals(ret, 10, "Parsed and executed OK"); } + + @Test + public void evalDefaultFileNameTest() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" }); + // default FILENAME being "" make sure generated code bytecode verifies. + engine.eval("var a = 3;"); + } + + @Test + public void evalFileNameWithSpecialCharsTest() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" }); + final ScriptContext ctxt = new SimpleScriptContext(); + // use file name with "dangerous" chars. + ctxt.setAttribute(ScriptEngine.FILENAME, "", ScriptContext.ENGINE_SCOPE); + engine.eval("var a = 3;"); + ctxt.setAttribute(ScriptEngine.FILENAME, "[myscript]", ScriptContext.ENGINE_SCOPE); + engine.eval("var h = 'hello';"); + ctxt.setAttribute(ScriptEngine.FILENAME, ";/\\$.", ScriptContext.ENGINE_SCOPE); + engine.eval("var foo = 'world';"); + // name used by jjs shell tool for the interactive mode + ctxt.setAttribute(ScriptEngine.FILENAME, "", ScriptContext.ENGINE_SCOPE); + engine.eval("var foo = 'world';"); + } }