--- ./.hgtags Wed May 07 19:25:50 2014 -0700 +++ ./.hgtags Wed Jun 25 09:01:10 2014 -0700 @@ -405,6 +405,7 @@ b829c5947c6cd473f42cadfe2c61399fb67c2da6 jdk7u55-b02 a72b902cdd39d9f2f2d353d5ad629e543cbc01ae jdk7u55-b03 6a8ee38075621564dd276e8ed7be576d637acf79 jdk7u55-b04 +92ac508efb9e00d88b04a2bd79ab8a55f450a048 jdk7u65-b00 92ac508efb9e00d88b04a2bd79ab8a55f450a048 jdk7u55-b05 6c7cd2146f69cf0823765b3cf84c338c1dc7157c jdk7u55-b06 5cad0f56c685a0673944dbc5632ea9ae7b9340c7 jdk7u55-b07 @@ -418,6 +419,11 @@ 0820b4707cfa75f8211b88b0daa67bba8475f498 jdk7u55-b30 997ab3897d6ede80b0decdda94b569e57dd7dd90 jdk7u55-b14 1f52edec29fd44c8bacce11ba7440287b37d04d1 jdk7u55-b31 +5b15555172019b3c92484abff7c92f066e162d29 jdk7u55-b32 +fa5ead8cb7d2de49cd138d93fb86fa5a10b07037 jdk7u55-b33 +6041c68893932ee16a272a8d5a42069e217d888c jdk7u55-b34 +8733fb47b3338e9285870b09eb326e758cf69771 jdk7u55-b35 +b9c954604ecaaf8d8a1568ababd9508ff09b742e jdk7u55-b36 11147a12bd8c6b02f98016a8d1151e56f42a43b6 jdk7u60-b00 88113cabda386320a087b288d43e792f523cc0ba jdk7u60-b01 6bdacebbc97f0a03be45be48a6d5b5cf2f7fe77d jdk7u60-b02 @@ -435,6 +441,28 @@ 1ca6a368aec38ee91a41dc03899d7dc1037de44d jdk7u60-b14 a95b821a2627295b90fb4ae8f3b8bc2ff9c64acc jdk7u60-b15 19a3f6f48c541a8cf144eedffa0e52e108052e82 jdk7u60-b16 +472f5930e6cc8f307b5508995ee2edcf9913a852 jdk7u60-b17 472f5930e6cc8f307b5508995ee2edcf9913a852 jdk7u60-b18 -472f5930e6cc8f307b5508995ee2edcf9913a852 jdk7u60-b17 +b9264ea7e0887d511318bf7b53d12f944760bbbb jdk7u65-b01 2a7a5e774023944f291ee27ca5b3ad89e0e62aaf jdk7u60-b19 +ac5183999ba532c6b89f24fe01f6f0eb96799719 jdk7u60-b30 +7e9c1a4c2d50e10ccc6d81b8dc0786e82128a676 jdk7u60-b31 +f792c1446b57932f5cd661afa72bcf41cfe6d1a6 jdk7u60-b32 +870408bbbfa50a6f44997a844c6c31c0cb0cbc40 jdk7u60-b33 +3a683f1730a148bcc1ca6eb9137116db427093f6 jdk7u65-b02 +c154a8de7d34128ab75f46a2b6a909796f63b6e3 jdk7u65-b03 +62e22dbc36410d76716bfa5e9fd679fcb4b1d845 jdk7u65-b04 +4cab26e4e27f8ff382b8d6487224af59dc7c1fa1 jdk7u65-b05 +b2cd3babc4ca1fb48b6073665e627f8bfb65d547 jdk7u65-b06 +bc5e69657c0f6d58775ac7441033bbcbbaee3268 jdk7u65-b07 +48eb3345e05fe904d2e92067da0abd04a9b375e4 jdk7u65-b08 +2e7881991d5294061023f8862b702e4730f2860d jdk7u65-b09 +db03cbff389500c7ccfd4b476ab78319f6e24d2d jdk7u65-b10 +9f629f70ec6c4249baadaadd05b0f32c9129ad05 jdk7u65-b11 +71cd7866ca68b333e36330e179ab1d69d721aaee jdk7u65-b12 +49dbfea9d3a4b709f3230d581a09d960c2de5109 jdk7u65-b13 +0cfadcb9f8006ac5601bb0ce8b74211d6b223c11 jdk7u65-b14 +3cce3737be368dc3d304508cd0d6e354f8a19f55 jdk7u65-b15 +2c8b05ed9802cf4e5f61439a6d6286e7f7cd444e jdk7u65-b16 +927d8d3db13c5221237b51efe45206054ee6e3f3 jdk7u65-b17 +b51ccd32894662064192857007ef41175d433901 jdk7u65-b30 --- ./corba/.hgtags Wed May 07 19:25:52 2014 -0700 +++ ./corba/.hgtags Wed Jun 25 09:01:20 2014 -0700 @@ -407,6 +407,7 @@ db2e6d87bade9d2061646ff9a6b39b5159fba0ec jdk7u55-b02 02ff18f156bd3382fe22e4758b138370f5238e97 jdk7u55-b03 6a88a170331fb38af5046e54bf75f38176af5c41 jdk7u55-b04 +a8d27c3fc4e4e6cd99fa164f04c30a71f474a2d6 jdk7u65-b00 a8d27c3fc4e4e6cd99fa164f04c30a71f474a2d6 jdk7u55-b05 af7f1808106bf4e9b4680d943677299829245d08 jdk7u55-b06 44801796d42bebc90e8c4c7fb5bd79db04b10b75 jdk7u55-b07 @@ -420,6 +421,11 @@ e041c52fe69128ec3439d26afef9b0fcba00684c jdk7u55-b30 a0bfd0e80ae0ae6e3a29bf527b5911c83163b3f5 jdk7u55-b14 55ff6957449cf6c79f5d5bb159df27f51ece1659 jdk7u55-b31 +fba15e177b15873e3c63b0efc7c0f5647a243a79 jdk7u55-b32 +6503115cbedda9216083fc1798e2fa5a2775f68a jdk7u55-b33 +c8614d56bc1c5c60431f938a0c33d8fc42e7aef0 jdk7u55-b34 +be587f9142bcb694b647642fbbb05dbaa7b1b1b3 jdk7u55-b35 +05ea23fd127a217965eb304932e8c0ce5933f04b jdk7u55-b36 c5b5886004e6446b8b27ccdc1fd073354c1dc614 jdk7u60-b00 a531112cc6d0b0a1e7d4ffdaa3ba53addcd25cf4 jdk7u60-b01 d81370c5b863acc19e8fb07315b1ec687ac1136a jdk7u60-b02 @@ -437,6 +443,28 @@ 02bdeb33754315f589bd650dde656d2c9947976d jdk7u60-b14 e5946b2cf82bdea3a4b85917e903168e65a543a7 jdk7u60-b15 e424fb8452851b56db202488a4e9a283934c4887 jdk7u60-b16 +b96d90694be873372cc417b38b01afed6ac1b239 jdk7u60-b17 b96d90694be873372cc417b38b01afed6ac1b239 jdk7u60-b18 -b96d90694be873372cc417b38b01afed6ac1b239 jdk7u60-b17 +550ae238459e0f59d9a85d183bc2b4520adac05b jdk7u65-b01 5d1b39fe68944cff6380db56fbe2fbaa28091bf6 jdk7u60-b19 +39734d26e279098fae06cee5a127e126090ddec9 jdk7u60-b30 +8939f268abb8c153de653f2659fff6716e5f83f8 jdk7u60-b31 +9665790000e22370daefddbf56dd81e89e07b7c4 jdk7u60-b32 +437b4b2aed4811af16efcafca7995684493d205b jdk7u60-b33 +6a89d959cbade46fcd281f421ac40a804d098f0b jdk7u65-b02 +afed3d62e8051fe65f431abe87dad50cbeba3800 jdk7u65-b03 +38fabf72970ae509350f57ffad99f6ac8fc6fdad jdk7u65-b04 +12c1621ce88defa65ebc1bdffb7141bd7d0089a6 jdk7u65-b05 +5041c713522c0fc68239fc91f7fb9498dd7edebb jdk7u65-b06 +144887a766dc17a139524dd43f1a0bc8f2a2a3a2 jdk7u65-b07 +5b8210c41bc41135687028bcb000ca116e2090f6 jdk7u65-b08 +1f7156e0a46129dbaf5b248802371564d92630a3 jdk7u65-b09 +be3cbbea3ec1e14b6492acbbd5c08222c24a5061 jdk7u65-b10 +fd7e4972cfefa174ce3d6dcb7f4b409df11a745b jdk7u65-b11 +792ef0370bf7bcf83c9404d2b44f08722dcd73aa jdk7u65-b12 +b95f46ae5207853a89d52b0453a2fb99fffee817 jdk7u65-b13 +6efadedfe3295dbf2af4a350d813524af029b116 jdk7u65-b14 +78966cf34d868ef18b8a3fa7edec368e1cc4739d jdk7u65-b15 +d765ed30bd5ed2bdd71fda56c056333e1b4b0d7d jdk7u65-b16 +cd642d59aca29ff2b56e7ed016be758828f199cd jdk7u65-b17 +8740dc71b1ceb49c76470b46205c28c1302e864d jdk7u65-b30 --- ./corba/src/share/classes/org/omg/CORBA/ORB.java Wed May 07 19:25:52 2014 -0700 +++ ./corba/src/share/classes/org/omg/CORBA/ORB.java Wed Jun 25 09:01:20 2014 -0700 @@ -291,28 +291,12 @@ (className.equals("com.sun.corba.se.impl.orb.ORBSingleton"))) { singleton = new com.sun.corba.se.impl.orb.ORBSingleton(); } else { - singleton = create_impl_with_systemclassloader(className); + singleton = create_impl(className); } } return singleton; } - private static ORB create_impl_with_systemclassloader(String className) { - - try { - ReflectUtil.checkPackageAccess(className); - ClassLoader cl = ClassLoader.getSystemClassLoader(); - Class orbBaseClass = org.omg.CORBA.ORB.class; - Class singletonOrbClass = Class.forName(className, true, cl).asSubclass(orbBaseClass); - return (ORB)singletonOrbClass.newInstance(); - } catch (Throwable ex) { - SystemException systemException = new INITIALIZE( - "can't instantiate default ORB implementation " + className); - systemException.initCause(ex); - throw systemException; - } - } - private static ORB create_impl(String className) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) --- ./hotspot/.hgtags Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/.hgtags Wed Jun 25 09:01:56 2014 -0700 @@ -616,6 +616,7 @@ 408028d410e316a99495c42df0031018890c22fe jdk7u55-b02 50fb91504dd8cdf410eb956075442daf3aacf1db jdk7u55-b03 3be3b8a032a5508646c1c5620cee18d3e69fc708 jdk7u55-b04 +b86119fa2748bd91ae4984ff2264da92b6626f8c jdk7u65-b00 b86119fa2748bd91ae4984ff2264da92b6626f8c jdk7u55-b05 260d919d52e500a0b20f911fade2a7710474067a jdk7u55-b06 8cf6e0a3a0651c4132ae034c2b68ddf4eb5c4d88 jdk7u55-b07 @@ -629,6 +630,11 @@ d27b468d5f3be3329ff1ff342f3347e6b2e0303b jdk7u55-b30 dff9147a781672f20bb0577a94233264ea4a95d1 jdk7u55-b14 8175599864880938d68d0a515fa561043d7d5fd0 jdk7u55-b31 +ba9270b8fb1f4852ff1d9dab15571eb9e0714495 jdk7u55-b32 +0901a8cf66a0494b55bf104c9666d4e3c6ff93f0 jdk7u55-b33 +278d7e230b297a4632b94ddc07d591e74736e039 jdk7u55-b34 +db88943dba0b7672a09e22974934022fbe8ba8dd jdk7u55-b35 +b3e388601b0fc0922b311e2cc68b9417cedd16ef jdk7u55-b36 ae4adc1492d1c90a70bd2d139a939fc0c8329be9 jdk7u60-b00 af1fc2868a2b919727bfbb0858449bd991bbee4a jdk7u40-b60 cc83359f5e5eb46dd9176b0a272390b1a0a51fdc hs24.60-b01 @@ -655,6 +661,28 @@ b226be2040f971855626f5b88cb41a7d5299fea0 jdk7u60-b14 2871f345b7e5585e20dc7aa91035967fe774cfba jdk7u60-b15 ec76bacbb5b90efc7988dee5345c656126b97561 jdk7u60-b16 +617a6338e0c4f7699eed5061d7e8f576c3ace029 jdk7u60-b17 617a6338e0c4f7699eed5061d7e8f576c3ace029 jdk7u60-b18 -617a6338e0c4f7699eed5061d7e8f576c3ace029 jdk7u60-b17 +4a9635c98a917cfcef506ca5d034c733a33c53f3 jdk7u65-b01 361493c7cdb5f75b28efc63389d6cebaaaa43a2c jdk7u60-b19 +13f561930b3e80a94e2baddc51dfc6c43c5ca601 jdk7u60-b30 +35b2dbe7f7c69ea0f2feb1e66fe8651511a5fb6d jdk7u60-b31 +f166d2e391993f1b12b4ad1685baf999c78e6372 jdk7u60-b32 +cc1fea28c886ef100632247a708eac0c83640914 jdk7u60-b33 +eb797fab50d3b440b17b3e7c5d83f42bfa73655e jdk7u65-b02 +bb00df28ecdbd0da89ab4ed81f6f2b732fa512da jdk7u65-b03 +848481af9003067546c7f34c166bb8d745b95d5f jdk7u65-b04 +98a884fa64a9ef1753a28691106efe10942b9d70 jdk7u65-b05 +6f1dddf9c632bfb14121c9521d17b64bd0be0cd2 jdk7u65-b06 +a053d3d805355ffcd85c17e653182e17d4456bd5 jdk7u65-b07 +6f03dfb50363d26599fcf726586ea3f6d0e0347d jdk7u65-b08 +b4930eb1ea7630b4d8609e2efe6f000d3dc83235 jdk7u65-b09 +4736382ac9d999044b05eb26932ab6fc59dbb159 jdk7u65-b10 +7345c7bf20fd8c91492240a95082af9a201b3a96 jdk7u65-b11 +28b81694b89f88541e28bbc767d78e77ec66cce6 jdk7u65-b12 +f4ed018b4c51dae699da835617b19e8a49c124a4 jdk7u65-b13 +7ec585caae47f7202fb5357607f9ad058b03870e jdk7u65-b14 +7058f0d30de6826b6866ce2d146c63e943be33af jdk7u65-b15 +f1b2970a2564c3360db420431cfbba215da6ae43 jdk7u65-b16 +4c6df9a369cb9d54fe2d898452883a22b8ec6640 jdk7u65-b17 +aca05127f95b5704ee3a34104a8f86e36326f0c0 jdk7u65-b30 --- ./hotspot/make/hotspot_version Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/make/hotspot_version Wed Jun 25 09:01:56 2014 -0700 @@ -34,8 +34,8 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2014 HS_MAJOR_VER=24 -HS_MINOR_VER=60 -HS_BUILD_NUMBER=09 +HS_MINOR_VER=65 +HS_BUILD_NUMBER=04 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 --- ./hotspot/src/os/bsd/vm/os_bsd.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1819,9 +1819,6 @@ ::abort(); } -// unused on bsd for now. -void os::set_error_file(const char *logfile) {} - // This method is a copy of JDK's sysGetLastErrorString // from src/solaris/hpi/src/system_md.c @@ -2585,6 +2582,7 @@ // determine if this is a legacy image or modules image // modules image doesn't have "jre" subdirectory len = strlen(buf); + assert(len < buflen, "Ran out of buffer space"); jrelib_p = buf + len; // Add the appropriate library subdir @@ -2620,7 +2618,7 @@ } } - strcpy(saved_jvm_path, buf); + strncpy(saved_jvm_path, buf, MAXPATHLEN); } void os::print_jni_name_prefix_on(outputStream* st, int args_size) { --- ./hotspot/src/os/linux/vm/os_linux.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/os/linux/vm/os_linux.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1614,9 +1614,6 @@ ::abort(); } -// unused on linux for now. -void os::set_error_file(const char *logfile) {} - // This method is a copy of JDK's sysGetLastErrorString // from src/solaris/hpi/src/system_md.c @@ -2413,6 +2410,7 @@ // determine if this is a legacy image or modules image // modules image doesn't have "jre" subdirectory len = strlen(buf); + assert(len < buflen, "Ran out of buffer room"); jrelib_p = buf + len; snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); if (0 != access(buf, F_OK)) { @@ -2435,7 +2433,7 @@ } } - strcpy(saved_jvm_path, buf); + strncpy(saved_jvm_path, buf, MAXPATHLEN); } void os::print_jni_name_prefix_on(outputStream* st, int args_size) { --- ./hotspot/src/os/solaris/vm/os_solaris.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1877,9 +1877,6 @@ ::abort(); // dump core (for debugging) } -// unused -void os::set_error_file(const char *logfile) {} - // DLL functions const char* os::dll_file_extension() { return ".so"; } @@ -2561,6 +2558,7 @@ // determine if this is a legacy image or modules image // modules image doesn't have "jre" subdirectory len = strlen(buf); + assert(len < buflen, "Ran out of buffer space"); jrelib_p = buf + len; snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); if (0 != access(buf, F_OK)) { @@ -2581,7 +2579,7 @@ } } - strcpy(saved_jvm_path, buf); + strncpy(saved_jvm_path, buf, MAXPATHLEN); } --- ./hotspot/src/os/windows/vm/os_windows.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/os/windows/vm/os_windows.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1773,27 +1773,28 @@ // libjvm.so is installed there (append a fake suffix // hotspot/libjvm.so). char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != NULL && java_home_var[0] != 0) { - - strncpy(buf, java_home_var, buflen); - - // determine if this is a legacy image or modules image - // modules image doesn't have "jre" subdirectory - size_t len = strlen(buf); - char* jrebin_p = buf + len; - jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\"); - if (0 != _access(buf, 0)) { - jio_snprintf(jrebin_p, buflen-len, "\\bin\\"); - } - len = strlen(buf); - jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll"); + if (java_home_var != NULL && java_home_var[0] != 0 && + strlen(java_home_var) < (size_t)buflen) { + + strncpy(buf, java_home_var, buflen); + + // determine if this is a legacy image or modules image + // modules image doesn't have "jre" subdirectory + size_t len = strlen(buf); + char* jrebin_p = buf + len; + jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\"); + if (0 != _access(buf, 0)) { + jio_snprintf(jrebin_p, buflen-len, "\\bin\\"); + } + len = strlen(buf); + jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll"); } } if(buf[0] == '\0') { - GetModuleFileName(vm_lib_handle, buf, buflen); - } - strcpy(saved_jvm_path, buf); + GetModuleFileName(vm_lib_handle, buf, buflen); + } + strncpy(saved_jvm_path, buf, MAX_PATH); } @@ -2218,17 +2219,6 @@ #endif //_WIN64 -// Fatal error reporting is single threaded so we can make this a -// static and preallocated. If it's more than MAX_PATH silently ignore -// it. -static char saved_error_file[MAX_PATH] = {0}; - -void os::set_error_file(const char *logfile) { - if (strlen(logfile) <= MAX_PATH) { - strncpy(saved_error_file, logfile, MAX_PATH); - } -} - static inline void report_error(Thread* t, DWORD exception_code, address addr, void* siginfo, void* context) { VMError err(t, exception_code, addr, siginfo, context); --- ./hotspot/src/share/vm/classfile/classFileParser.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -961,7 +961,7 @@ "Wrong size %u for field's Signature attribute in class file %s", attribute_length, CHECK); } - generic_signature_index = cfs->get_u2(CHECK); + generic_signature_index = parse_generic_signature_attribute(cp, CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); @@ -1698,7 +1698,8 @@ } // Sift through annotations, looking for those significant to the VM: -void ClassFileParser::parse_annotations(u1* buffer, int limit, +void ClassFileParser::parse_annotations(Handle class_loader, + u1* buffer, int limit, constantPoolHandle cp, ClassFileParser::AnnotationCollector* coll, TRAPS) { @@ -1736,7 +1737,7 @@ } // Here is where parsing particular annotations will take place. - AnnotationCollector::ID id = coll->annotation_index(aname); + AnnotationCollector::ID id = coll->annotation_index(class_loader, is_anonymous(), aname); if (id == AnnotationCollector::_unknown) continue; coll->set_annotation(id); // If there are no values, just set the bit and move on: @@ -1765,20 +1766,30 @@ } } -ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) { +ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Handle class_loader, + bool is_anonymous, + Symbol* name) { vmSymbols::SID sid = vmSymbols::find_sid(name); + // Privileged code can use all annotations. Other code silently drops some. + const bool privileged = class_loader.is_null() || is_anonymous || + class_loader()->klass()->klass_part()->name() == + vmSymbols::sun_misc_Launcher_ExtClassLoader(); switch (sid) { case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_ForceInline; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_DontInline; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Compiled; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; default: break; } @@ -1818,8 +1829,8 @@ // from the method back up to the containing klass. These flag values // are added to klass's access_flags. -methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interface, - AccessFlags *promoted_flags, +methodHandle ClassFileParser::parse_method(Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags *promoted_flags, typeArrayHandle* method_annotations, typeArrayHandle* method_parameter_annotations, typeArrayHandle* method_default_annotations, @@ -2122,13 +2133,12 @@ "Invalid Signature attribute length %u in class file %s", method_attribute_length, CHECK_(nullHandle)); } - cfs->guarantee_more(2, CHECK_(nullHandle)); // generic_signature_index - generic_signature_index = cfs->get_u2_fast(); + generic_signature_index = parse_generic_signature_attribute(cp, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); + parse_annotations(class_loader, runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { runtime_invisible_annotations_length = method_attribute_length; @@ -2357,8 +2367,8 @@ // from the methods back up to the containing klass. These flag values // are added to klass's access_flags. -objArrayHandle ClassFileParser::parse_methods(constantPoolHandle cp, bool is_interface, - AccessFlags* promoted_flags, +objArrayHandle ClassFileParser::parse_methods(Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, objArrayOop* methods_annotations_oop, objArrayOop* methods_parameter_annotations_oop, @@ -2381,7 +2391,8 @@ objArrayHandle methods_parameter_annotations; objArrayHandle methods_default_annotations; for (int index = 0; index < length; index++) { - methodHandle method = parse_method(cp, is_interface, + methodHandle method = parse_method(class_loader, cp, + is_interface, promoted_flags, &method_annotations, &method_parameter_annotations, @@ -2490,6 +2501,17 @@ } } +// Parse generic_signature attribute for methods and fields +u2 ClassFileParser::parse_generic_signature_attribute(constantPoolHandle cp, TRAPS) { + ClassFileStream* cfs = stream(); + cfs->guarantee_more(2, CHECK_0); // generic_signature_index + u2 generic_signature_index = cfs->get_u2_fast(); + check_property( + valid_symbol_at(cp, generic_signature_index), + "Invalid Signature attribute at constant pool index %u in class file %s", + generic_signature_index, CHECK_0); + return generic_signature_index; +} void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS) { ClassFileStream* cfs = stream(); @@ -2654,18 +2676,19 @@ ClassFileStream* cfs = stream(); u1* current_start = cfs->current(); - cfs->guarantee_more(2, CHECK); // length - int attribute_array_length = cfs->get_u2_fast(); - - guarantee_property(_max_bootstrap_specifier_index < attribute_array_length, - "Short length on BootstrapMethods in class file %s", - CHECK); - guarantee_property(attribute_byte_length > sizeof(u2), "Invalid BootstrapMethods attribute length %u in class file %s", attribute_byte_length, CHECK); + cfs->guarantee_more(attribute_byte_length, CHECK); + + int attribute_array_length = cfs->get_u2_fast(); + + guarantee_property(_max_bootstrap_specifier_index < attribute_array_length, + "Short length on BootstrapMethods in class file %s", + CHECK); + // The attribute contains a counted array of counted tuples of shorts, // represending bootstrap specifiers: // length*{bootstrap_method_index, argument_count*{argument_index}} @@ -2726,7 +2749,8 @@ } -void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, +void ClassFileParser::parse_classfile_attributes(Handle class_loader, + constantPoolHandle cp, ClassFileParser::ClassAnnotationCollector* parsed_annotations, TRAPS) { ClassFileStream* cfs = stream(); @@ -2809,7 +2833,8 @@ runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, + parse_annotations(class_loader, + runtime_visible_annotations, runtime_visible_annotations_length, cp, parsed_annotations, @@ -3172,7 +3197,8 @@ objArrayOop methods_annotations_oop = NULL; objArrayOop methods_parameter_annotations_oop = NULL; objArrayOop methods_default_annotations_oop = NULL; - objArrayHandle methods = parse_methods(cp, access_flags.is_interface(), + objArrayHandle methods = parse_methods(class_loader, cp, + access_flags.is_interface(), &promoted_flags, &has_final_method, &methods_annotations_oop, @@ -3186,7 +3212,7 @@ // Additional attributes ClassAnnotationCollector parsed_annotations; - parse_classfile_attributes(cp, &parsed_annotations, CHECK_(nullHandle)); + parse_classfile_attributes(class_loader, cp, &parsed_annotations, CHECK_(nullHandle)); // Make sure this is the end of class file stream guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); --- ./hotspot/src/share/vm/classfile/classFileParser.hpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -102,7 +102,7 @@ assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, ""); } // If this annotation name has an ID, report it (or _none). - ID annotation_index(Symbol* name); + ID annotation_index(Handle class_loader, bool is_anonymous, Symbol* name); // Set the annotation name: void set_annotation(ID id) { assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); @@ -169,14 +169,14 @@ u2* java_fields_count_ptr, TRAPS); // Method parsing - methodHandle parse_method(constantPoolHandle cp, bool is_interface, - AccessFlags* promoted_flags, + methodHandle parse_method(Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags* promoted_flags, typeArrayHandle* method_annotations, typeArrayHandle* method_parameter_annotations, typeArrayHandle* method_default_annotations, TRAPS); - objArrayHandle parse_methods (constantPoolHandle cp, bool is_interface, - AccessFlags* promoted_flags, + objArrayHandle parse_methods (Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, objArrayOop* methods_annotations_oop, objArrayOop* methods_parameter_annotations_oop, @@ -202,6 +202,7 @@ typeArrayOop parse_stackmap_table(u4 code_attribute_length, TRAPS); // Classfile attribute parsing + u2 parse_generic_signature_attribute(constantPoolHandle cp, TRAPS); void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS); void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp, int length, TRAPS); u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, @@ -210,7 +211,8 @@ u2 enclosing_method_method_index, constantPoolHandle cp, TRAPS); - void parse_classfile_attributes(constantPoolHandle cp, + void parse_classfile_attributes(Handle class_loader, + constantPoolHandle cp, ClassAnnotationCollector* parsed_annotations, TRAPS); void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS); @@ -224,7 +226,7 @@ int runtime_invisible_annotations_length, TRAPS); int skip_annotation(u1* buffer, int limit, int index); int skip_annotation_value(u1* buffer, int limit, int index); - void parse_annotations(u1* buffer, int limit, constantPoolHandle cp, + void parse_annotations(Handle class_loader, u1* buffer, int limit, constantPoolHandle cp, /* Results (currently, only one result is supported): */ AnnotationCollector* result, TRAPS); @@ -335,6 +337,12 @@ : cp->tag_at(index).is_klass_reference()); } + // Checks that the cpool index is in range and is a utf8 + bool valid_symbol_at(constantPoolHandle cp, int cpool_index) { + return (cp->is_within_bounds(cpool_index) && + cp->tag_at(cpool_index).is_utf8()); + } + public: // Constructor ClassFileParser(ClassFileStream* st) { set_stream(st); } --- ./hotspot/src/share/vm/classfile/stackMapTable.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/classfile/stackMapTable.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -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 @@ -134,6 +134,7 @@ } // check if uninitialized objects exist on backward branches check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); + frame->verifier()->update_furthest_jump(target); } void StackMapTable::check_new_object( --- ./hotspot/src/share/vm/classfile/verifier.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/classfile/verifier.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, 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 @@ -629,6 +629,9 @@ bool no_control_flow = false; // Set to true when there is no direct control // flow from current instruction to the next // instruction in sequence + + set_furthest_jump(0); + Bytecodes::Code opcode; while (!bcs.is_last_bytecode()) { // Check for recursive re-verification before each bytecode. @@ -2239,6 +2242,29 @@ "Bad method call"); return; } + + // Make sure that this call is not jumped over. + if (bci < furthest_jump()) { + verify_error(ErrorContext::bad_code(bci), + "Bad method call from inside of a branch"); + return; + } + + // Make sure that this call is not done from within a TRY block because + // that can result in returning an incomplete object. Simply checking + // (bci >= start_pc) also ensures that this call is not done after a TRY + // block. That is also illegal because this call must be the first Java + // statement in the constructor. + ExceptionTable exhandlers(_method()); + int exlength = exhandlers.length(); + for(int i = 0; i < exlength; i++) { + if (bci >= exhandlers.start_pc(i)) { + verify_error(ErrorContext::bad_code(bci), + "Bad method call from after the start of a try block"); + return; + } + } + current_frame->initialize_object(type, current_type()); *this_uninit = true; } else if (type.is_uninitialized()) { @@ -2275,6 +2301,11 @@ methodOop m = instanceKlass::cast(ref_klass)->uncached_lookup_method( vmSymbols::object_initializer_name(), cp->signature_ref_at(bcs->get_index_u2())); + if (m == NULL) { + verify_error(ErrorContext::bad_code(bci), + "Call to missing method"); + return; + } instanceKlassHandle mh(THREAD, m->method_holder()); if (m->is_protected() && !mh->is_same_class_package(_klass())) { bool assignable = current_type().is_assignable_from( --- ./hotspot/src/share/vm/classfile/verifier.hpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/classfile/verifier.hpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, 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 @@ -256,6 +256,9 @@ ErrorContext _error_context; // contains information about an error + // Used to detect illegal jumps over calls to super() and this() in ctors. + int32_t _furthest_jump; + void verify_method(methodHandle method, TRAPS); char* generate_code_data(methodHandle m, u4 code_length, TRAPS); void verify_exception_handler_table(u4 code_length, char* code_data, @@ -398,6 +401,20 @@ Symbol* create_temporary_symbol(const char *s, int length, TRAPS); TypeOrigin ref_ctx(const char* str, TRAPS); + + // Keep track of the furthest branch done in a method to make sure that + // there are no branches over calls to super() or this() from inside of + // a constructor. + int32_t furthest_jump() { return _furthest_jump; } + + void set_furthest_jump(int32_t target) { + _furthest_jump = target; + } + + void update_furthest_jump(int32_t target) { + if (target > _furthest_jump) _furthest_jump = target; + } + }; inline int ClassVerifier::change_sig_to_verificationType( --- ./hotspot/src/share/vm/compiler/compileBroker.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1921,6 +1921,7 @@ ResourceMark rm; char* method_name = method->name()->as_C_string(); strncpy(_last_method_compiled, method_name, CompileBroker::name_buffer_length); + _last_method_compiled[CompileBroker::name_buffer_length - 1] = '\0'; // ensure null terminated char current_method[CompilerCounters::cmname_buffer_length]; size_t maxLen = CompilerCounters::cmname_buffer_length; --- ./hotspot/src/share/vm/oops/klassVtable.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/oops/klassVtable.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -209,6 +209,17 @@ // For bytecodes not produced by javac together it is possible that a method does not override // the superclass's method, but might indirectly override a super-super class's vtable entry // If none found, return a null superk, else return the superk of the method this does override +// For public and protected methods: if they override a superclass, they will +// also be overridden themselves appropriately. +// Private methods do not override and are not overridden. +// Package Private methods are trickier: +// e.g. P1.A, pub m +// P2.B extends A, package private m +// P1.C extends B, public m +// P1.C.m needs to override P1.A.m and can not override P2.B.m +// Therefore: all package private methods need their own vtable entries for +// them to be the root of an inheritance overriding decision +// Package private methods may also override other vtable entries instanceKlass* klassVtable::find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { instanceKlass* superk = initialsuper; @@ -310,8 +321,12 @@ ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) && ((super_klass = find_transitive_override(super_klass, target_method, i, target_loader, target_classname, THREAD)) != (instanceKlass*)NULL))) { - // overriding, so no new entry - allocate_new = false; + + // Package private methods always need a new entry to root their own + // overriding. They may also override other methods. + if (!target_method()->is_package_private()) { + allocate_new = false; + } if (checkconstraints) { // Override vtable entry if passes loader constraint check @@ -433,6 +448,12 @@ return true; } + // Package private methods always need a new entry to root their own + // overriding. This allows transitive overriding to work. + if (target_method()->is_package_private()) { + return true; + } + // search through the super class hierarchy to see if we need // a new entry ResourceMark rm; --- ./hotspot/src/share/vm/opto/graphKit.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/opto/graphKit.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1120,6 +1120,17 @@ } return _gvn.transform( new (C) ConvI2LNode(offset)); } + +Node* GraphKit::ConvI2UL(Node* offset) { + juint offset_con = (juint) find_int_con(offset, Type::OffsetBot); + if (offset_con != (juint) Type::OffsetBot) { + return longcon((julong) offset_con); + } + Node* conv = _gvn.transform( new (C) ConvI2LNode(offset)); + Node* mask = _gvn.transform( ConLNode::make(C, (julong) max_juint) ); + return _gvn.transform( new (C) AndLNode(conv, mask) ); +} + Node* GraphKit::ConvL2I(Node* offset) { // short-circuit a common case jlong offset_con = find_long_con(offset, (jlong)Type::OffsetBot); --- ./hotspot/src/share/vm/opto/graphKit.hpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/opto/graphKit.hpp Wed Jun 25 09:01:56 2014 -0700 @@ -338,6 +338,7 @@ // Convert between int and long, and size_t. // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.) Node* ConvI2L(Node* offset); + Node* ConvI2UL(Node* offset); Node* ConvL2I(Node* offset); // Find out the klass of an object. Node* load_object_klass(Node* object); --- ./hotspot/src/share/vm/opto/library_call.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/opto/library_call.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -2432,7 +2432,7 @@ case T_ADDRESS: // Cast to an int type. p = _gvn.transform(new (C) CastP2XNode(NULL, p)); - p = ConvX2L(p); + p = ConvX2UL(p); break; default: fatal(err_msg_res("unexpected type %d: %s", type, type2name(type))); --- ./hotspot/src/share/vm/opto/type.hpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/opto/type.hpp Wed Jun 25 09:01:56 2014 -0700 @@ -1348,6 +1348,7 @@ #define ConvL2X(x) (x) #define ConvX2I(x) ConvL2I(x) #define ConvX2L(x) (x) +#define ConvX2UL(x) (x) #else @@ -1392,6 +1393,7 @@ #define ConvL2X(x) ConvL2I(x) #define ConvX2I(x) (x) #define ConvX2L(x) ConvI2L(x) +#define ConvX2UL(x) ConvI2UL(x) #endif --- ./hotspot/src/share/vm/runtime/os.hpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/runtime/os.hpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -460,9 +460,6 @@ // run cmd in a separate process and return its exit code; or -1 on failures static int fork_and_exec(char *cmd); - // Set file to send error reports. - static void set_error_file(const char *logfile); - // os::exit() is merged with vm_exit() // static void exit(int num); --- ./hotspot/src/share/vm/utilities/events.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/utilities/events.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -93,7 +93,7 @@ va_start(ap, format); // Save a copy of begin message and log it. _buffer.printv(format, ap); - Events::log(NULL, _buffer); + Events::log(NULL, "%s", (const char*)_buffer); va_end(ap); } } @@ -102,6 +102,6 @@ if (LogEvents) { // Append " done" to the begin message and log it _buffer.append(" done"); - Events::log(NULL, _buffer); + Events::log(NULL, "%s", (const char*)_buffer); } } --- ./hotspot/src/share/vm/utilities/vmError.cpp Wed May 07 19:26:16 2014 -0700 +++ ./hotspot/src/share/vm/utilities/vmError.cpp Wed Jun 25 09:01:56 2014 -0700 @@ -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 @@ -951,7 +951,6 @@ if (fd != -1) { out.print_raw("# An error report file with more information is saved as:\n# "); out.print_raw_cr(buffer); - os::set_error_file(buffer); log.set_fd(fd); } else { --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./hotspot/test/compiler/6653795/UnsafeGetAddressTest.java Wed Jun 25 09:01:56 2014 -0700 @@ -0,0 +1,68 @@ +/* + * 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 6653795 + * @summary C2 intrinsic for Unsafe.getAddress performs pointer sign extension on 32-bit systems + * @run main UnsafeGetAddressTest + * + */ + +import sun.misc.Unsafe; +import java.lang.reflect.*; + +public class UnsafeGetAddressTest { + private static Unsafe unsafe; + + public static void main(String[] args) throws Exception { + Class c = UnsafeGetAddressTest.class.getClassLoader().loadClass("sun.misc.Unsafe"); + Field f = c.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe)f.get(c); + + long address = unsafe.allocateMemory(unsafe.addressSize()); + unsafe.putAddress(address, 0x0000000080000000L); + // from sun.misc.Unsafe.getAddress' documentation: + // "If the native pointer is less than 64 bits wide, it is + // extended as an unsigned number to a Java long." + result = unsafe.getAddress(address); + System.out.printf("1: was 0x%x, expected 0x%x\n", result, + 0x0000000080000000L); + for (int i = 0; i < 1000000; i++) { + result = unsafe.getAddress(address); + } + + // The code has got compiled, check the result now + System.out.printf("2: was 0x%x, expected 0x%x\n", result, + 0x0000000080000000L); + if (result != 0x0000000080000000L) { + System.out.println("Test Failed"); + System.exit(97); + } else { + System.out.println("Test Passed"); + } + } + static volatile long result; +} + --- ./jaxp/.hgtags Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/.hgtags Wed Jun 25 09:03:02 2014 -0700 @@ -408,6 +408,7 @@ 8275dc4db7f852edb331ae48d663d08b9ab2b5c7 jdk7u55-b02 381e73f93a83e8d3bfd7dbf79f4f363a8fd6442f jdk7u55-b03 c72c57f71c2ba6362d9ccfbf4743947b9ecefcac jdk7u55-b04 +5592b0c44617022e3c136eedfa1e98d4f254c964 jdk7u65-b00 5592b0c44617022e3c136eedfa1e98d4f254c964 jdk7u55-b05 c59d714090080ad2e06f0ca5e8d354403059d8ce jdk7u55-b06 125ea54089add3a16898b801a9989bf6cca05da6 jdk7u55-b07 @@ -421,6 +422,11 @@ 01f26830f88cf4f10897416fe1f4f372efcdecf5 jdk7u55-b30 26187a65c765b3177f1b7ff0638259bf66f9ec47 jdk7u55-b14 5be97f6c25d9eb3ef0a05fc860964cb3d27134b0 jdk7u55-b31 +94f3ad704f28d5ec65f7a3b1cbf5cfe7e42151f3 jdk7u55-b32 +476aad2c130e2b1b7033fa6789754c03151da95c jdk7u55-b33 +32aa4a5892b0567b19da2bc5b72aa3f3a3398130 jdk7u55-b34 +1f8449a6e05ee0a495ba89c3b4021b46f641ff40 jdk7u55-b35 +7767e8740aea3283703e634ffdbfccd0fbebe82d jdk7u55-b36 d9b92749a0f4c8e6c6f4fe11210c2a02d70bae74 jdk7u60-b00 ad39e88c503948fc4fc01e97c75b6e3c24599d23 jdk7u60-b01 050986fd54e3ec4515032ee938bc59e86772b6c0 jdk7u60-b02 @@ -438,6 +444,28 @@ 2814f43a6c73414dcb2b799e1a52d5b44688590d jdk7u60-b14 10eed57b66336660f71f7524f2283478bdf373dc jdk7u60-b15 fefd2d5c524b0be78876d9b98d926abda2828e79 jdk7u60-b16 +ba6b0b5dfe5a0f50fac95c488c8a5400ea07d4f8 jdk7u60-b17 ba6b0b5dfe5a0f50fac95c488c8a5400ea07d4f8 jdk7u60-b18 -ba6b0b5dfe5a0f50fac95c488c8a5400ea07d4f8 jdk7u60-b17 +dd5a398eedc7031a4fb8682bc423e787db465c9e jdk7u65-b01 581752d32aebea959fec84e8ae692e1f63d2c4a8 jdk7u60-b19 +cef2dec8b5d76555c5b7b2e1a62275206f76a07a jdk7u60-b30 +bfa8403a1e28bdc1e94ba61d89e170e4ccc7d58b jdk7u60-b31 +33a8a292a02aa76139d0d04970a0d87cc674f2e3 jdk7u60-b32 +583c5eeb9f31275121aecca60307b8885a1a80d0 jdk7u60-b33 +27909f138bdb9ffdd2ab4bded231c7ccc2264046 jdk7u65-b02 +b3307181bd0f1a2c6e1e2c403b87a76e34452110 jdk7u65-b03 +efa9425faaf402b7ea9c6226eb08236d8fa1ff2b jdk7u65-b04 +319df7bff5bf7a9c2d659dd9021b918e729fa56f jdk7u65-b05 +5fd236e2f1bbc09349858f9c56dd223b6d6f21f6 jdk7u65-b06 +e1ae0b54e22200f2d67de39f6a16899ad4a1e574 jdk7u65-b07 +86e93799766d67102a37559b3831abcc825d7e24 jdk7u65-b08 +e24ee8ca453937c11be2fdbab0b4244aa7ec22bd jdk7u65-b09 +6c20039a2e0104f30697e22dc06fe83ff7a43d39 jdk7u65-b10 +50625e7c71b9b1d31bb901aec66366cacc239b3b jdk7u65-b11 +b56b145c3d85b649188a40a91106005a3ebfcf2b jdk7u65-b12 +3a8933cb0219594b72c797732768070fa23c491e jdk7u65-b13 +ddb29a56b839563502b9f80deca5d6064641f1d7 jdk7u65-b14 +708c636721447ebf679c2c754cb36a503c6177b8 jdk7u65-b15 +a34a9f6740955e1cd844c5b701d76dbe7290913a jdk7u65-b16 +178512d1bd9caf56d61811ad0d4b4269475407aa jdk7u65-b17 +be897d0fd2a0b5f43b0d0e48075e5b070ca584d4 jdk7u65-b30 --- ./jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java Wed Jun 25 09:03:02 2014 -0700 @@ -91,6 +91,13 @@ */ public static final String JDK_XML_NAME_LIMIT = ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit"; + + /** + * JDK maxElementDepth limit + */ + public static final String JDK_MAX_ELEMENT_DEPTH = + ORACLE_JAXP_PROPERTY_PREFIX + "maxElementDepth"; + /** * JDK property indicating whether the parser shall print out entity * count information @@ -139,6 +146,11 @@ */ public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit"; + /** + * JDK maxElementDepth limit + */ + public static final String SP_MAX_ELEMENT_DEPTH = "jdk.xml.maxElementDepth"; + //legacy System Properties public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; --- ./jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java Wed Jun 25 09:03:02 2014 -0700 @@ -76,7 +76,9 @@ GENEAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_GENEAL_ENTITY_SIZE_LIMIT, XalanConstants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0), PARAMETER_ENTITY_SIZE_LIMIT(XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, - XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000); + XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000), + MAX_ELEMENT_DEPTH_LIMIT(XalanConstants.JDK_MAX_ELEMENT_DEPTH, + XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0); final String apiProperty; final String systemProperty; --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java Wed Jun 25 09:03:02 2014 -0700 @@ -252,6 +252,13 @@ */ public static final String JDK_XML_NAME_LIMIT = ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit"; + + /** + * JDK maxElementDepth limit + */ + public static final String JDK_MAX_ELEMENT_DEPTH = + ORACLE_JAXP_PROPERTY_PREFIX + "maxElementDepth"; + /** * JDK property to allow printing out information from the limit analyzer */ @@ -297,6 +304,11 @@ */ public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit"; + /** + * JDK maxElementDepth limit + */ + public static final String SP_MAX_ELEMENT_DEPTH = "jdk.xml.maxElementDepth"; + //legacy System Properties public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Wed Jun 25 09:03:02 2014 -0700 @@ -1309,6 +1309,7 @@ fAttributes.removeAllAttributes(); + checkDepth(rawname); if(!seekCloseOfStartTag()){ fReadingAttributes = true; fAttributeCacheUsedCount =0; @@ -1913,6 +1914,21 @@ // utility methods /** + * Check if the depth exceeds the maxElementDepth limit + * @param elementName name of the current element + */ + void checkDepth(String elementName) { + fLimitAnalyzer.addValue(Limit.MAX_ELEMENT_DEPTH_LIMIT, elementName, fElementStack.fDepth); + if (fSecurityManager.isOverLimit(Limit.MAX_ELEMENT_DEPTH_LIMIT,fLimitAnalyzer)) { + fSecurityManager.debugPrint(fLimitAnalyzer); + reportFatalError("MaxElementDepthLimit", new Object[]{elementName, + fLimitAnalyzer.getTotalValue(Limit.MAX_ELEMENT_DEPTH_LIMIT), + fSecurityManager.getLimit(Limit.MAX_ELEMENT_DEPTH_LIMIT), + "maxElementDepth"}); + } + } + + /** * Calls document handler with a single character resulting from * built-in entity resolution. * --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java Wed Jun 25 09:03:02 2014 -0700 @@ -220,6 +220,7 @@ fCurrentElement = fElementQName; String rawname = fElementQName.rawname; + checkDepth(rawname); if (fBindNamespaces) { fNamespaceContext.pushContext(); if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) { --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Wed Jun 25 09:03:02 2014 -0700 @@ -299,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\". TotalEntitySizeLimit=JAXP00010004: The accumulated size \"{0}\" of entities exceeded the \"{1}\" limit set by \"{2}\". MaxXMLNameLimit=JAXP00010005: The name \"{0}\" exceeded the \"{1}\" limit set by \"{2}\". + MaxElementDepthLimit=JAXP00010006: The element \"{0}\" has a depth of \"{1}\" that exceeds the limit \"{2}\" set by \"{3}\". --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,28 +1,3 @@ -# -# Copyright (c) 2009, 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. -# - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -276,7 +251,7 @@ NMTOKENInvalid = Attributwert "{0}" mit dem Typ NMTOKEN muss ein Namenstoken sein. NMTOKENSInvalid = Attributwert "{0}" mit dem Typ NMTOKENS muss mindestens ein Namenstoken sein. NoNotationOnEmptyElement = Elementtyp "{0}", der als EMPTY deklariert wurde, kann nicht das Attribut "{1}" mit dem Typ NOTATION deklarieren. - RootElementTypeMustMatchDoctypedecl = Dokument-Root-Element "{1}"muss mit DOCTYPE-Root "{0}" \u00FCbereinstimmen. + RootElementTypeMustMatchDoctypedecl = Document Root-Element "{1}"muss mit DOCTYPE-Root "{0}" \u00FCbereinstimmen. UndeclaredElementInContentSpec = Contentmodell des Elements "{0}" verweist auf das nicht deklarierte Element "{1}". UniqueNotationName = Deklaration f\u00FCr die Notation "{0}" ist nicht eindeutig. Ein jeweiliger Name darf nicht in mehreren Notationsdeklarationen deklariert werden. ENTITYFailedInitializeGrammar = ENTITYDatatype-Validator: Nicht erfolgreich. Initialisierungsmethode muss mit einer g\u00FCltigen Grammatikreferenz aufgerufen werden. \t @@ -324,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003: Die L\u00E4nge von Entit\u00E4t "{0}" ist "{1}" und \u00FCberschreitet den Grenzwert "{2}", der von "{3}" festgelegt wurde. TotalEntitySizeLimit=JAXP00010004: Die akkumulierte Gr\u00F6\u00DFe "{0}" der Entit\u00E4ten \u00FCberschreitet den Grenzwert "{1}", der von "{2}" festgelegt wurde. MaxXMLNameLimit=JAXP00010005: Der Name "{0}" \u00FCberschreitet den Grenzwert "{1}", der von "{2}" festgelegt wurde. + MaxElementDepthLimit=JAXP00010006: Die Tiefe von Element "{0}" ist "{1}" und \u00FCberschreitet den Grenzwert "{2}", der von "{3}" festgelegt wurde. --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,28 +1,3 @@ -# -# Copyright (c) 2009, 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. -# - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -324,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003: la longitud de la entidad "{0}" es "{1}", que excede el l\u00EDmite de "{2}" que ha definido "{3}". TotalEntitySizeLimit=JAXP00010004: el tama\u00F1o acumulado "{0}" de las entidades ha excedido el l\u00EDmite de "{1}" que ha definido "{2}". MaxXMLNameLimit=JAXP00010005: el nombre "{0}" ha excedido el l\u00EDmite de "{1}" que ha definido "{2}". + MaxElementDepthLimit=JAXP00010006: El elemento "{0}" tiene una profundidad de "{1}" que excede el l\u00EDmite "{2}" definido por "{3}". --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,28 +1,3 @@ -# -# Copyright (c) 2009, 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. -# - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -324,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003 : La longueur de l''entit\u00E9 "{0}" est de "{1}". Cette valeur d\u00E9passe la limite de "{2}" d\u00E9finie par "{3}". TotalEntitySizeLimit=JAXP00010004 : La taille cumul\u00E9e des entit\u00E9s ("{0}") d\u00E9passe la limite de "{1}" d\u00E9finie par "{2}". MaxXMLNameLimit=JAXP00010005 : le nom "{0}" d\u00E9passe la limite de "{1}" d\u00E9finie par "{2}". + MaxElementDepthLimit=JAXP00010006 : l''\u00E9l\u00E9ment "{0}" a une profondeur de "{1}" qui d\u00E9passe la limite de "{2}" d\u00E9finie par "{3}". --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,28 +1,3 @@ -# -# Copyright (c) 2009, 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. -# - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -324,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003: la lunghezza dell''entit\u00E0 "{0}" \u00E8 "{1}". Tale valore supera il limite "{2}" definito da "{3}". TotalEntitySizeLimit=JAXP00010004: le dimensioni accumulate "{0}" delle entit\u00E0 supera il limite "{1}" definito da "{2}". MaxXMLNameLimit=JAXP00010005: il nome "{0}" supera il limite "{1}" definito da "{2}". + MaxElementDepthLimit=JAXP00010006: la profondit\u00E0 dell''elemento "{0}" \u00E8 "{1}". Tale valore supera il limite "{2}" definito da "{3}". --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,27 +1,3 @@ -# -# Copyright (c) 2009, 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. - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -146,7 +122,7 @@ ExpectedByte = {1}\u30D0\u30A4\u30C8\u306EUTF-8\u30B7\u30FC\u30B1\u30F3\u30B9\u306E\u30D0\u30A4\u30C8{0}\u304C\u5FC5\u8981\u3067\u3059\u3002 InvalidHighSurrogate = UTF-8\u30B7\u30FC\u30B1\u30F3\u30B9\u306E\u4E0A\u4F4D\u30B5\u30ED\u30B2\u30FC\u30C8\u30FB\u30D3\u30C3\u30C8\u306E\u4E0A\u9650\u306F0x10\u3067\u3059\u304C\u30010x{0}\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002 OperationNotSupported = \u64CD\u4F5C"{0}"\u306F{1}\u30EA\u30FC\u30C0\u30FC\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 - InvalidASCII = \u30D0\u30A4\u30C8"{0}"\u306F\u3001(7\u30D3\u30C3\u30C8) ASCII\u30AD\u30E3\u30E9\u30AF\u30BF\u30FB\u30BB\u30C3\u30C8\u306E\u30E1\u30F3\u30D0\u30FC\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002 + InvalidASCII = \u30D0\u30A4\u30C8"{0}"\u306F\u3001(7\u30D3\u30C3\u30C8) ASCII\u6587\u5B57\u30BB\u30C3\u30C8\u306E\u30E1\u30F3\u30D0\u30FC\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002 CharConversionFailure = \u7279\u5B9A\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3067\u3042\u308B\u3068\u78BA\u5B9A\u3055\u308C\u305F\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u306B\u306F\u3001\u305D\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3067\u4E0D\u6B63\u306A\u30B7\u30FC\u30B1\u30F3\u30B9\u3092\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002 # DTD Messages @@ -323,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3"{0}"\u306E\u9577\u3055\u306F"{1}"\u3067\u3001"{3}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{2}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002 TotalEntitySizeLimit=JAXP00010004: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u306E\u7D2F\u7A4D\u30B5\u30A4\u30BA"{0}"\u306F\u3001"{2}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{1}"\u3092\u8D85\u3048\u307E\u3057\u305F\u3002 MaxXMLNameLimit=JAXP00010005: \u540D\u524D"{0}"\u306F\u3001"{2}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{1}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002 + MaxElementDepthLimit=JAXP00010006: \u8981\u7D20"{0}"\u306E\u6DF1\u3055\u306F"{1}"\u3067\u3001"{3}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{2}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002 --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,28 +1,3 @@ -# -# Copyright (c) 2009, 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. -# - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -324,4 +299,5 @@ MaxEntitySizeLimit=JAXP00010003: "{0}" \uC5D4\uD2F0\uD2F0\uC758 \uAE38\uC774\uAC00 "{3}"\uC5D0\uC11C \uC124\uC815\uB41C "{2}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{1}"\uC785\uB2C8\uB2E4. TotalEntitySizeLimit=JAXP00010004: \uC5D4\uD2F0\uD2F0\uC758 \uB204\uC801 \uD06C\uAE30 "{0}"\uC774(\uAC00) "{2}"\uC5D0\uC11C \uC124\uC815\uB41C "{1}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4. MaxXMLNameLimit=JAXP00010005: "{0}" \uC774\uB984\uC774 "{2}"\uC5D0\uC11C \uC124\uC815\uB41C "{1}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4. + MaxElementDepthLimit=JAXP00010006: "{0}" \uC694\uC18C\uC758 \uAE4A\uC774\uAC00 "{3}"\uC5D0\uC11C \uC124\uC815\uB41C "{2}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{1}"\uC785\uB2C8\uB2E4. --- ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties Wed Jun 25 09:03:02 2014 -0700 @@ -1,28 +1,3 @@ -# -# Copyright (c) 2009, 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. -# - # This file contains error and warning messages related to XML # The messages are arranged in key and value tuples in a ListResourceBundle. # @@ -154,7 +129,7 @@ # 2.2 Characters InvalidCharInEntityValue = Um caractere XML inv\u00E1lido (Unicode: 0x {0}) foi encontrado no valor da entidade da literal. InvalidCharInExternalSubset = Um caractere XML inv\u00E1lido (Unicode: 0x {0}) foi encontrado no subconjunto externo do DTD. - InvalidCharInIgnoreSect = Um caractere XML inv\u00E1lido (Unicode: 0x{0}) foi encontrado na se\u00E7\u00E3o condicional deletada. + InvalidCharInIgnoreSect = Um caractere XML inv\u00E1lido (Unicode: 0x{0}) foi encontrado na se\u00E7\u00E3o condicional exclu\u00EDda. InvalidCharInPublicID = Um caractere XML inv\u00E1lido (Unicode: 0x{0}) foi encontrado no identificador p\u00FAblico. InvalidCharInSystemID = Um caractere XML inv\u00E1lido (Unicode: 0x{0}) foi encontrado no identificador do sistema. # 2.3 Common Syntactic Constructs @@ -173,7 +148,7 @@ PEReferenceWithinMarkup = A refer\u00EAncia da entidade do par\u00E2metro "%{0};" n\u00E3o pode ocorrer na marca\u00E7\u00E3o no subconjunto interno do DTD. MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = As declara\u00E7\u00F5es de marca\u00E7\u00E3o contidas ou apontadas pela declara\u00E7\u00E3o do tipo de documento devem estar corretas. # 2.10 White Space Handling - MSG_XML_SPACE_DECLARATION_ILLEGAL = Deve ser fornecida a declara\u00E7\u00E3o do atributo para "xml:space" como um tipo enumerado, cujo os \u00FAnicos valores poss\u00EDveis s\u00E3o "default" e "preserve". + MSG_XML_SPACE_DECLARATION_ILLEGAL = Deve ser fornecida a declara\u00E7\u00E3o do atributo para "xml:space" como um tipo enumerado, cujo os \u00FAnicos valores poss\u00EDveis s\u00E3o "padr\u00E3o" e "preserve". # 3.2 Element Type Declarations MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL = O espa\u00E7o em branco \u00E9 necess\u00E1rio ap\u00F3s " cache; if (caches[index] == null) { --- ./jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java Wed May 07 19:26:26 2014 -0700 +++ ./jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java Wed Jun 25 09:03:02 2014 -0700 @@ -66,7 +66,8 @@ ELEMENT_ATTRIBUTE_LIMIT(Constants.JDK_ELEMENT_ATTRIBUTE_LIMIT, Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000), TOTAL_ENTITY_SIZE_LIMIT(Constants.JDK_TOTAL_ENTITY_SIZE_LIMIT, Constants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000), GENEAL_ENTITY_SIZE_LIMIT(Constants.JDK_GENEAL_ENTITY_SIZE_LIMIT, Constants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0), - PARAMETER_ENTITY_SIZE_LIMIT(Constants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, Constants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000); + PARAMETER_ENTITY_SIZE_LIMIT(Constants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, Constants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000), + MAX_ELEMENT_DEPTH_LIMIT(Constants.JDK_MAX_ELEMENT_DEPTH, Constants.SP_MAX_ELEMENT_DEPTH, 0, 0); final String apiProperty; final String systemProperty; @@ -429,9 +430,10 @@ return false; } - if (index==Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || - index==Limit.ENTITY_EXPANSION_LIMIT.ordinal() || - index==Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) { + if (index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || + index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal()) { return (limitAnalyzer.getTotalValue(index) > values[index]); } else { return (limitAnalyzer.getValue(index) > values[index]); --- ./jaxws/.hgtags Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/.hgtags Wed Jun 25 09:03:17 2014 -0700 @@ -407,6 +407,7 @@ a257072fc2aa482abd6ffa28e235dbe532af6d00 jdk7u55-b02 2916fdfc475bf29bc702887bf5ba02df67c98916 jdk7u55-b03 f4759b4547602b3bc865db8c5f356f46979c6389 jdk7u55-b04 +8a8dfdbc66149b89f804c5a50e4692c2520569ae jdk7u65-b00 8a8dfdbc66149b89f804c5a50e4692c2520569ae jdk7u55-b05 2696d6747826cea92a97b2d80be4a59ff99462bd jdk7u55-b06 1ad971afe2b5db93420654fa65b23f827760fed7 jdk7u55-b07 @@ -420,6 +421,11 @@ 5d726bf8fedc1f10d250e980653315919b7602f2 jdk7u55-b30 81d0f297557c4a876727cabeb2bfcdf066a1fc9d jdk7u55-b14 2d103c97c9bd0b3357e6d5e2b5b9ffb64c271288 jdk7u55-b31 +b15b4084288fa4ea9caf7f6b4e79d164c77bb1d6 jdk7u55-b32 +efd71c6ca0832e894b7e1619111860062fa96458 jdk7u55-b33 +485d7912bc20775bda670ea2236c883366590dd7 jdk7u55-b34 +587be38f9a6d60fbefc92dbe9fbd4c83d579c680 jdk7u55-b35 +62332eaec2ff8fc8bece2a905554ac08e375a661 jdk7u55-b36 cb5f95263f620967f5097c5ff8e0b27cfb9e8c44 jdk7u60-b00 f675dfce1e61a6ed01732ae7cfbae941791cba74 jdk7u60-b01 8a3b9e8492a5ac4e2e0c166dbfc5d058be244377 jdk7u60-b02 @@ -437,6 +443,28 @@ 43b5a7cf08e7ee018b1fa42a89510b4c381dc4c5 jdk7u60-b14 d00389bf5439e5c42599604d2ebc909d26df8dcf jdk7u60-b15 2fc16d3a321212abc0cc93462b22c4be7f693ab9 jdk7u60-b16 +b312ec543dc09db784e161eb89607d4afd4cab1e jdk7u60-b17 b312ec543dc09db784e161eb89607d4afd4cab1e jdk7u60-b18 -b312ec543dc09db784e161eb89607d4afd4cab1e jdk7u60-b17 +23598a667bb89b57d5abab5b37781a0952e16cf9 jdk7u65-b01 1d21eb9011a060c7761c9a8a53e69d58bbea4893 jdk7u60-b19 +39e67887a3b112bf74f84df2aac0f46c65bfb005 jdk7u60-b30 +dfc2c4b9b16bd2d68435ddc9bb12036982021844 jdk7u60-b31 +0e17943c39fadb810b4dd2e9ac732503b86043f4 jdk7u60-b32 +910559d7f754d8fd6ab80a627869877443358316 jdk7u60-b33 +8ac19021e6af5d92b46111a6c41430f36ccdb901 jdk7u65-b02 +a70d681bc273a110d10cf3c4f9b35b25ca6a600f jdk7u65-b03 +7cd17f96988509e99fbb71003aeb76d92b638fef jdk7u65-b04 +7bafb24c6466999bc08742b160d0e450bc12a2c5 jdk7u65-b05 +35b31c516cab0a81fa9d2a119ec101be3f5a2969 jdk7u65-b06 +eb89c1c30a93b1d43cbc1b7520bca46d31d0829a jdk7u65-b07 +d63ca1c5bdb9fb2e36ec4afda431c0d1dfdfc07c jdk7u65-b08 +e4cc1e93c6332c8463e75a25c3d735884d185259 jdk7u65-b09 +d10ec17267415303a71d358ae6202369db77ba96 jdk7u65-b10 +2f5dcee6d56b00551db21408ebad2ff2faad7c7a jdk7u65-b11 +f03350485cd388620981bb7e7faa2d1890d11a1b jdk7u65-b12 +471f883e9830d8341248b99da7c9cfab9fcc94d6 jdk7u65-b13 +11deffa2096f08dab69de13d4fcf361c6d252636 jdk7u65-b14 +39ad61a579fd824fbec1bec4e071376449ba8195 jdk7u65-b15 +198bf1acd262f2c16715d3be5e33d7b8de1e7776 jdk7u65-b16 +df4dc644fe344e973fc1692c28683eec8ba82600 jdk7u65-b17 +0e0ca87a6d5212a0885f0c8c00b8f7cf24a64d89 jdk7u65-b30 --- ./jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/model/nav/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/model/nav/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/api/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/api/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -130,14 +130,6 @@ private final Map bridges = new LinkedHashMap(); /** - * Shared instance of {@link TransformerFactory}. - * Lock before use, because a {@link TransformerFactory} is not thread-safe - * whereas {@link JAXBContextImpl} is. - * Lazily created. - */ - private volatile static SAXTransformerFactory tf; - - /** * Shared instance of {@link DocumentBuilder}. * Lock before use. Lazily created. */ @@ -702,13 +694,7 @@ */ static Transformer createTransformer() { try { - if (tf==null) { - synchronized(JAXBContextImpl.class) { - if (tf==null) { - tf = (SAXTransformerFactory)TransformerFactory.newInstance(); - } - } - } + SAXTransformerFactory tf = (SAXTransformerFactory)TransformerFactory.newInstance(); return tf.newTransformer(); } catch (TransformerConfigurationException e) { throw new Error(e); // impossible @@ -720,13 +706,7 @@ */ public static TransformerHandler createTransformerHandler() { try { - if (tf==null) { - synchronized(JAXBContextImpl.class) { - if (tf==null) { - tf = (SAXTransformerFactory)TransformerFactory.newInstance(); - } - } - } + SAXTransformerFactory tf = (SAXTransformerFactory)TransformerFactory.newInstance(); return tf.newTransformerHandler(); } catch (TransformerConfigurationException e) { throw new Error(e); // impossible --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/property/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/property/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/model/Utils.java Wed May 07 19:26:28 2014 -0700 +++ ./jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/model/Utils.java Wed Jun 25 09:03:17 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,22 +43,32 @@ * * Has *package private* access to avoid inappropriate usage. */ -/* package */ final class Utils { +final class Utils { private static final Logger LOGGER = Logger.getLogger(Utils.class.getName()); /** * static ReflectionNavigator field to avoid usage of reflection every time we use it. */ - /* package */ static final Navigator REFLECTION_NAVIGATOR; + static final Navigator REFLECTION_NAVIGATOR; static { // we statically initializing REFLECTION_NAVIGATOR property - Class refNav = null; try { - refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); + Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator"); //noinspection unchecked - Method getInstance = refNav.getDeclaredMethod("getInstance"); - getInstance.setAccessible(true); + final Method getInstance = refNav.getDeclaredMethod("getInstance"); + + // requires accessClassInPackage privilege + AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Object run() { + getInstance.setAccessible(true); + return null; + } + } + ); + //noinspection unchecked REFLECTION_NAVIGATOR = (Navigator) getInstance.invoke(null); } catch (ClassNotFoundException e) { --- ./jdk/.hgtags Wed May 07 19:26:47 2014 -0700 +++ ./jdk/.hgtags Wed Apr 16 12:37:49 2014 +0400 @@ -391,6 +391,7 @@ 2ca3e1fa4455ad564228ad6e654498167af2f20d jdk7u55-b02 c12b3c81366cb067ff4444952209d54bfa387353 jdk7u55-b03 476d1bddaa32bf440953c3b1814ba38f16886c03 jdk7u55-b04 +7fa6d3ba2cc77cd1e6f24e33f0c39788cb2893b8 jdk7u65-b00 7fa6d3ba2cc77cd1e6f24e33f0c39788cb2893b8 jdk7u55-b05 795654fce29c38d4c8504f760d8d8a36248d38ed jdk7u55-b06 4b2ed892b195e95f7541aaa3b129a2caa5faae1d jdk7u55-b07 @@ -404,6 +405,11 @@ 4a5651c84b1e6cf26dc9b19f00747e5004efba68 jdk7u55-b30 ffd99c5975217a14609851602c5f5dc005234aba jdk7u55-b14 88f1bf248cc520e0bf7ef17bc862f87aab958373 jdk7u55-b31 +b83f5194edf23b752fe2c0a9be361455f87196df jdk7u55-b32 +01a4cd03a6c85abb62eb5d1c2b5bf7d2f544c04e jdk7u55-b33 +3f54f8a387c1a908c07106b685183b19a5fc1064 jdk7u55-b34 +2cdc52ec4813abe38b4e52ae9c9f0ff5dcc87faa jdk7u55-b35 +6845d311ff990d422f9376d37e3e82d5d06bff3f jdk7u55-b36 db5a29c812ee25c34ce9cd97de6e0dae284a4e34 jdk7u60-b00 def34c4a798678c424786a8f0d0508e90185958d jdk7u60-b01 ff67c89658525e8903fb870861ed3645befd6bc5 jdk7u60-b02 @@ -421,6 +427,28 @@ b7fbd9b4febf8961091fdf451d3da477602a8f1d jdk7u60-b14 04882f9a073e8de153ec7ad32486569fd9a087ec jdk7u60-b15 41547583c3a035c3924ffedfa8704e58d69e5c50 jdk7u60-b16 +e484202d9a4104840d758a21b2bba1250e766343 jdk7u60-b17 e484202d9a4104840d758a21b2bba1250e766343 jdk7u60-b18 -e484202d9a4104840d758a21b2bba1250e766343 jdk7u60-b17 +c220d329a78161f79df73048ed55db91f538e3b7 jdk7u65-b01 7190843ddaf4f3ad158c3071be0f4ca42a5802dc jdk7u60-b19 +8dc56d0f3e860658619eaa57d10fb1a4182d71cd jdk7u60-b30 +feac9624a1e1ffebe09a19ae351d88e3ef98c441 jdk7u60-b31 +fb40615ef352e03ee94c0682a6ca0a0e6a33a70b jdk7u60-b32 +9cfcdeeecfac66004cb5bbb2c5bba5c57e170539 jdk7u60-b33 +a42a3bb22f6991d8f6a30e4f1782ad620c40eb65 jdk7u65-b02 +756071871d61e1ca410c63a3f1c4dabcc51a90df jdk7u65-b03 +bac16c82c14a35d1e9d3c4d0bd317dbbb296f34e jdk7u65-b04 +14b3f82c245fb8d0eeb21dc99ff0b4985571910c jdk7u65-b05 +7d8e5d90789533b5cc22eeb15c19ce1bb8a20573 jdk7u65-b06 +cde691a6989fa875107a3974aa92681d286be6ec jdk7u65-b07 +d5353f8e1e02e12a1262d65ed85183425b0cdf13 jdk7u65-b08 +45913a29c1edd3e63c9c818ffab7aebd4d75fa40 jdk7u65-b09 +3bb943c6ff7dd614cb428501db8c2c655e5f5223 jdk7u65-b10 +b84e98280630be44a87f4336009f61350f3c7dc0 jdk7u65-b11 +61d15f512305655a51c04811006850e4955936bd jdk7u65-b12 +69698344d0a1771ed9162ecad2065829ca1f8994 jdk7u65-b13 +2e6105ddad44866c4cdc1ba06620b48685e34111 jdk7u65-b14 +8cff6ce00a91820b4cb7ef24ed42063c2305127d jdk7u65-b15 +190017413768f02addea8b2c5106157e3c4076c7 jdk7u65-b16 +23e78e36bc39f4f761ac2b0e055c562c3ff204f5 jdk7u65-b17 +96d1fa382dda17ae105f28083bda41f79fc3093f jdk7u65-b30 --- ./jdk/make/java/util/FILES_properties.gmk Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/java/util/FILES_properties.gmk Wed Apr 16 12:37:49 2014 +0400 @@ -107,6 +107,7 @@ sun/util/resources/CalendarData_pl.properties \ sun/util/resources/CalendarData_pt.properties \ sun/util/resources/CalendarData_pt_PT.properties \ + sun/util/resources/CalendarData_pt_BR.properties \ sun/util/resources/CalendarData_ro.properties \ sun/util/resources/CalendarData_ru.properties \ sun/util/resources/CalendarData_sk.properties \ --- ./jdk/make/sun/javazic/tzdata/VERSION Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/sun/javazic/tzdata/VERSION Wed Apr 16 12:37:49 2014 +0400 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2014b +tzdata2014c --- ./jdk/make/sun/javazic/tzdata/africa Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/sun/javazic/tzdata/africa Wed Apr 16 12:37:49 2014 +0400 @@ -358,11 +358,54 @@ # http://www.worldtimezone.com/dst_news/dst_news_egypt02.html # +# From Ahmad El-Dardiry (2014-05-07): +# Egypt is to change back to Daylight system on May 15 +# http://english.ahram.org.eg/NewsContent/1/64/100735/Egypt/Politics-/Egypts-government-to-reapply-daylight-saving-time-.aspx + +# From Gunther Vermier (2015-05-13): +# our Egypt office confirms that the change will be at 15 May "midnight" (24:00) + +# From Paul Eggert (2014-05-13): +# Sarah El Deeb and Lee Keath of AP report that the Egyptian government says +# the change is because of blackouts in Cairo, even though Ahram Online (cited +# above) says DST had no affect on electricity consumption. The AP story says +# DST will not be observed during Ramadan. There is no information about when +# DST will end. See: +# http://abcnews.go.com/International/wireStory/el-sissi-pushes-egyptians-line-23614833 +# +# For now, guess that later transitions will use 2010's rules, and that +# Egypt will agree with Morocco (see below) about the date Ramadan starts and +# ends, though (unlike Morocco) it will switch at 00:00 standard time. In +# Egypt the spring-forward transitions are removed for 2020-2022, when the +# guessed spring-forward date falls during the estimated Ramadan, and all +# transitions removed for 2023-2038, where the estimated Ramadan falls entirely +# outside the guessed daylight-saving time. Ramadan intrudes on the guessed +# DST starting in 2039, but that's beyond our somewhat-arbitrary cutoff. + Rule Egypt 2008 only - Aug lastThu 23:00s 0 - Rule Egypt 2009 only - Aug 20 23:00s 0 - Rule Egypt 2010 only - Aug 11 0:00 0 - Rule Egypt 2010 only - Sep 10 0:00 1:00 S Rule Egypt 2010 only - Sep lastThu 23:00s 0 - +Rule Egypt 2014 only - May 15 24:00 1:00 S +Rule Egypt 2014 only - Jun 29 0:00s 0 - +Rule Egypt 2014 only - Jul 29 0:00s 1:00 S +Rule Egypt 2014 max - Sep lastThu 23:00s 0 - +Rule Egypt 2015 2019 - Apr lastFri 0:00s 1:00 S +Rule Egypt 2015 only - Jun 18 0:00s 0 - +Rule Egypt 2015 only - Jul 18 0:00s 1:00 S +Rule Egypt 2016 only - Jun 7 0:00s 0 - +Rule Egypt 2016 only - Jul 7 0:00s 1:00 S +Rule Egypt 2017 only - May 27 0:00s 0 - +Rule Egypt 2017 only - Jun 26 0:00s 1:00 S +Rule Egypt 2018 only - May 16 0:00s 0 - +Rule Egypt 2018 only - Jun 15 0:00s 1:00 S +Rule Egypt 2019 only - May 6 0:00s 0 - +Rule Egypt 2019 only - Jun 5 0:00s 1:00 S +Rule Egypt 2020 only - May 24 0:00s 1:00 S +Rule Egypt 2021 only - May 13 0:00s 1:00 S +Rule Egypt 2022 only - May 3 0:00s 1:00 S +Rule Egypt 2023 max - Apr lastFri 0:00s 1:00 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Cairo 2:05:09 - LMT 1900 Oct --- ./jdk/make/sun/javazic/tzdata/asia Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/sun/javazic/tzdata/asia Wed Apr 16 12:37:49 2014 +0400 @@ -1370,22 +1370,6 @@ # "Jordan will switch to winter time on Friday, October 27". # -# From Phil Pizzey (2009-04-02): -# ...I think I may have spotted an error in the timezone data for -# Jordan. -# The current (2009d) asia file shows Jordan going to daylight -# saving -# time on the last Thursday in March. -# -# Rule Jordan 2000 max - Mar lastThu 0:00s 1:00 S -# -# However timeanddate.com, which I usually find reliable, shows Jordan -# going to daylight saving time on the last Friday in March since 2002. -# Please see -# -# http://www.timeanddate.com/worldclock/timezone.html?n=11 -# - # From Steffen Thorsen (2009-04-02): # This single one might be good enough, (2009-03-24, Arabic): # --- ./jdk/make/sun/javazic/tzdata/europe Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/sun/javazic/tzdata/europe Wed Apr 16 12:37:49 2014 +0400 @@ -2989,6 +2989,10 @@ # From Alexander Krivenyshev (2014-03-17): # time change at 2:00 (2am) on March 30, 2014 # http://vz.ru/news/2014/3/17/677464.html +# From Paul Eggert (2014-03-30): +# Simferopol and Sevastopol reportedly changed their central town clocks +# late the previous day, but this appears to have been ceremonial +# and the discrepancies are small enough to not worry about. 2:00 EU EE%sT 2014 Mar 30 2:00 4:00 - MSK --- ./jdk/make/sun/lwawt/FILES_export_macosx.gmk Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/sun/lwawt/FILES_export_macosx.gmk Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -141,7 +141,6 @@ sun/lwawt/macosx/CMenuBar.java \ sun/lwawt/macosx/CMenuComponent.java \ sun/lwawt/macosx/CMenuItem.java \ - sun/lwawt/macosx/CMouseInfoPeer.java \ sun/lwawt/macosx/CPlatformView.java \ sun/lwawt/macosx/CPlatformWindow.java \ sun/lwawt/macosx/CPlatformComponent.java \ --- ./jdk/make/sun/security/ec/mapfile-vers Wed May 07 19:26:47 2014 -0700 +++ ./jdk/make/sun/security/ec/mapfile-vers Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ -28,7 +28,6 @@ SUNWprivate_1.1 { global: Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair; - Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes; Java_sun_security_ec_ECDSASignature_signDigest; Java_sun_security_ec_ECDSASignature_verifySignedDigest; Java_sun_security_ec_ECDHKeyAgreement_deriveKey; --- ./jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -89,10 +89,15 @@ private volatile int windowState = Frame.NORMAL; + // check that the mouse is over the window + private volatile boolean isMouseOver = false; + // A peer where the last mouse event came to. Used by cursor manager to + // find the component under cursor + private static volatile LWComponentPeer lastCommonMouseEventPeer = null; + // A peer where the last mouse event came to. Used to generate - // MOUSE_ENTERED/EXITED notifications and by cursor manager to - // find the component under cursor - private static volatile LWComponentPeer lastMouseEventPeer = null; + // MOUSE_ENTERED/EXITED notifications + private volatile LWComponentPeer lastMouseEventPeer; // Peers where all dragged/released events should come to, // depending on what mouse button is being dragged according to Cocoa @@ -773,59 +778,62 @@ Rectangle r = getBounds(); // findPeerAt() expects parent coordinates LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); - LWWindowPeer lastWindowPeer = - (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null; - LWWindowPeer curWindowPeer = - (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null; if (id == MouseEvent.MOUSE_EXITED) { - // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched - // to a peer from another window. So we must first check if this peer is - // the same as lastWindowPeer - if (lastWindowPeer == this) { - if (isEnabled()) { + isMouseOver = false; + if (lastMouseEventPeer != null) { + if (lastMouseEventPeer.isEnabled()) { Point lp = lastMouseEventPeer.windowToLocal(x, y, - lastWindowPeer); + this); Component target = lastMouseEventPeer.getTarget(); postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } + + // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched + // to a peer from another window. So we must first check if this peer is + // the same as lastWindowPeer + if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) { + lastCommonMouseEventPeer = null; + } lastMouseEventPeer = null; } - } else { - if (targetPeer != lastMouseEventPeer) { - // lastMouseEventPeer may be null if mouse was out of Java windows - if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { - // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit - // later), in which case lastWindowPeer is another window - if (lastWindowPeer != this) { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer); - // Additionally translate from this to lastWindowPeer coordinates - Rectangle lr = lastWindowPeer.getBounds(); - oldp.x += r.x - lr.x; - oldp.y += r.y - lr.y; - Component target = lastMouseEventPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, - when, modifiers, oldp, - screenX, screenY, clickCount, popupTrigger, button); - } else { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); - Component target = lastMouseEventPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, - when, modifiers, oldp, - screenX, screenY, clickCount, popupTrigger, button); - } - } - lastMouseEventPeer = targetPeer; - if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) { - Point newp = targetPeer.windowToLocal(x, y, curWindowPeer); + } else if (id == MouseEvent.MOUSE_ENTERED) { + isMouseOver = true; + if (targetPeer != null) { + if (targetPeer.isEnabled()) { + Point lp = targetPeer.windowToLocal(x, y, this); Component target = targetPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, - when, modifiers, newp, + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } + lastCommonMouseEventPeer = targetPeer; + lastMouseEventPeer = targetPeer; } + } else { + PlatformWindow topmostPlatformWindow = + platformWindow.getTopmostPlatformWindowUnderMouse(); + + LWWindowPeer topmostWindowPeer = + topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null; + + // topmostWindowPeer == null condition is added for the backword + // compatibility with applets. It can be removed when the + // getTopmostPlatformWindowUnderMouse() method will be properly + // implemented i CPlatformEmbeddedFrame class + if (topmostWindowPeer == this || topmostWindowPeer == null) { + generateMouseEnterExitEventsForComponents(when, button, x, y, + screenX, screenY, modifiers, clickCount, popupTrigger, + targetPeer); + } else { + LWComponentPeer topmostTargetPeer = + topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null; + topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, + screenX, screenY, modifiers, clickCount, popupTrigger, + topmostTargetPeer); + } + // TODO: fill "bdata" member of AWTEvent int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0; @@ -875,19 +883,13 @@ // mouseClickButtons is updated below, after MOUSE_CLICK is sent } - // check if we receive mouseEvent from outside the window's bounds - // it can be either mouseDragged or mouseReleased - if (curWindowPeer == null) { - //TODO This can happen if this window is invisible. this is correct behavior in this case? - curWindowPeer = this; - } if (targetPeer == null) { //TODO This can happen if this window is invisible. this is correct behavior in this case? targetPeer = this; } - Point lp = targetPeer.windowToLocal(x, y, curWindowPeer); + Point lp = targetPeer.windowToLocal(x, y, this); if (targetPeer.isEnabled()) { if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) { postMouseEnteredExitedEvent(targetPeer.getTarget(), id, @@ -918,6 +920,33 @@ notifyUpdateCursor(); } + private void generateMouseEnterExitEventsForComponents(long when, + int button, int x, int y, int screenX, int screenY, + int modifiers, int clickCount, boolean popupTriger, + LWComponentPeer targetPeer) { + if (!isMouseOver || targetPeer == lastMouseEventPeer) { + return; + } + + // Generate Mouse Exit for components + if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { + Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); + Component target = lastMouseEventPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, + oldp, screenX, screenY, clickCount, popupTriger, button); + } + lastCommonMouseEventPeer = targetPeer; + lastMouseEventPeer = targetPeer; + + // Genrate Mouse Enter for Componetns + if (targetPeer != null && targetPeer.isEnabled()) { + Point newp = targetPeer.windowToLocal(x, y, this); + Component target = targetPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, + newp, screenX, screenY, clickCount, popupTriger, button); + } + } + private void postMouseEnteredExitedEvent( Component target, int id, long when, int modifiers, Point loc, int xAbs, int yAbs, @@ -1198,11 +1227,11 @@ } public static LWWindowPeer getWindowUnderCursor() { - return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null; + return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null; } public static LWComponentPeer getPeerUnderCursor() { - return lastMouseEventPeer; + return lastCommonMouseEventPeer; } /* --- ./jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -118,6 +118,8 @@ public void setAlwaysOnTop(boolean value); + public PlatformWindow getTopmostPlatformWindowUnderMouse(); + public void updateFocusableWindowState(); public boolean rejectFocusRequest(CausedFocusEvent.Cause cause); --- ./jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java Wed May 07 19:26:47 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt.macosx; - -import java.awt.Window; -import sun.lwawt.LWMouseInfoPeer; -import sun.lwawt.LWWindowPeer; - -public class CMouseInfoPeer extends LWMouseInfoPeer -{ - //If a new window is to appear under the cursor, - //we get wrong window. - //This is a workaround for macosx. - @Override - public boolean isWindowUnderMouse(Window w) { - if (w == null) { - return false; - } - - return ((LWWindowPeer)w.getPeer()).getPlatformWindow().isUnderMouse(); - } -} --- ./jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -151,6 +151,11 @@ @Override public void setAlwaysOnTop(boolean value) {} + // This method should be properly implemented for applets. + // It returns null just as a stub. + @Override + public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; } + @Override public void updateFocusableWindowState() {} --- ./jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -61,8 +61,9 @@ private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage); private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename); private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled); - private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr); + private static native void nativeSynthesizeMouseEnteredExitedEvents(); private static native void nativeDispose(long nsWindowPtr); + private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse(); // Loger to report issues happened during execution but that do not affect functionality private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow"); @@ -593,7 +594,7 @@ } } - nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + nativeSynthesizeMouseEnteredExitedEvents(); // Configure stuff #2 updateFocusabilityForAutoRequestFocus(true); @@ -738,6 +739,9 @@ setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop); } + public PlatformWindow getTopmostPlatformWindowUnderMouse() { + return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse(); + } @Override public void setOpacity(float opacity) { CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity); @@ -830,7 +834,7 @@ throw new RuntimeException("Unknown window state: " + windowState); } - nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + nativeSynthesizeMouseEnteredExitedEvents(); // NOTE: the SWP.windowState field gets updated to the newWindowState // value when the native notification comes to us --- ./jdk/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 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 @@ -148,6 +148,11 @@ } @Override + public PlatformWindow getTopmostPlatformWindowUnderMouse() { + return null; + } + + @Override public void updateFocusableWindowState() { } --- ./jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Apr 16 12:37:49 2014 +0400 @@ -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 @@ -300,11 +300,6 @@ } @Override - protected MouseInfoPeer createMouseInfoPeerImpl() { - return new CMouseInfoPeer(); - } - - @Override protected int getScreenHeight() { return GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height; --- ./jdk/src/macosx/native/sun/awt/AWTView.h Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/native/sun/awt/AWTView.h Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -33,8 +33,8 @@ @private jobject m_cPlatformView; - // Handler for the tracking rect needed for Enter/Exit events management. - NSTrackingRectTag rolloverTrackingRectTag; + // Handler for the tracking area needed for Enter/Exit events management. + NSTrackingArea* rolloverTrackingArea; // TODO: NSMenu *contextualMenu; @@ -61,7 +61,7 @@ - (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer; - (void) deliverJavaMouseEvent: (NSEvent *) event; -- (void) resetTrackingRect; +- (void) resetTrackingArea; - (void) deliverJavaKeyEventHelper: (NSEvent *) event; - (jobject) awtComponent:(JNIEnv *)env; --- ./jdk/src/macosx/native/sun/awt/AWTView.m Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/native/sun/awt/AWTView.m Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -82,6 +82,7 @@ fPAHNeedsToSelect = NO; mouseIsOver = NO; + [self resetTrackingArea]; if (windowLayer != nil) { self.cglLayer = windowLayer; @@ -149,7 +150,7 @@ [[self window] makeFirstResponder: self]; }]; if ([self window] != NULL) { - [self resetTrackingRect]; + [self resetTrackingArea]; } } @@ -380,30 +381,31 @@ JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); } +- (void) resetTrackingArea { + if (rolloverTrackingArea != nil) { + [self removeTrackingArea:rolloverTrackingArea]; + [rolloverTrackingArea release]; + } -- (void) clearTrackingRect { - if (rolloverTrackingRectTag > 0) { - [self removeTrackingRect:rolloverTrackingRectTag]; - rolloverTrackingRectTag = 0; - } -} + int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited | + NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag); -- (void) resetTrackingRect { - [self clearTrackingRect]; - rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect] - owner:self - userData:NULL - assumeInside:NO]; + rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] + options:options + owner:self + userInfo:nil + ]; + [self addTrackingArea:rolloverTrackingArea]; } - (void)updateTrackingAreas { [super updateTrackingAreas]; - [self resetTrackingRect]; + [self resetTrackingArea]; } - (void) resetCursorRects { [super resetCursorRects]; - [self resetTrackingRect]; + [self resetTrackingArea]; } -(void) deliverJavaKeyEventHelper: (NSEvent *) event { --- ./jdk/src/macosx/native/sun/awt/AWTWindow.m Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/macosx/native/sun/awt/AWTWindow.m Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -314,10 +314,8 @@ return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]; } -// checks that this window is under the mouse cursor and this point is not overlapped by others windows -- (BOOL) isTopmostWindowUnderMouse { - - int currentWinID = [self.nsWindow windowNumber]; +// return id for the topmost window under mouse ++ (NSInteger) getTopmostWindowUnderMouseID { NSRect screenRect = [[NSScreen mainScreen] frame]; NSPoint nsMouseLocation = [NSEvent mouseLocation]; @@ -327,51 +325,75 @@ for (NSDictionary *window in windows) { - int layer = [[window objectForKey:(id)kCGWindowLayer] intValue]; + NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue]; if (layer == 0) { - int winID = [[window objectForKey:(id)kCGWindowNumber] intValue]; CGRect rect; CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect); if (CGRectContainsPoint(rect, cgMouseLocation)) { - return currentWinID == winID; - } else if (currentWinID == winID) { - return NO; + return [[window objectForKey:(id)kCGWindowNumber] integerValue]; } } } - return NO; + return -1; } -- (void) synthesizeMouseEnteredExitedEvents { +// checks that this window is under the mouse cursor and this point is not overlapped by other windows +- (BOOL) isTopmostWindowUnderMouse { + return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID]; +} - int eventType = 0; - BOOL isUnderMouse = [self isTopmostWindowUnderMouse]; - BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver]; ++ (AWTWindow *) getTopmostWindowUnderMouse { + NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator]; + NSWindow *window; - if (isUnderMouse && !mouseIsOver) { - eventType = NSMouseEntered; - } else if (!isUnderMouse && mouseIsOver) { - eventType = NSMouseExited; - } else { - return; + NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID]; + + while ((window = [windowEnumerator nextObject]) != nil) { + if ([window windowNumber] == topmostWindowUnderMouseID) { + BOOL isAWTWindow = [AWTWindow isAWTWindow: window]; + return isAWTWindow ? (AWTWindow *) [window delegate] : nil; + } } + return nil; +} + ++ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType { NSPoint screenLocation = [NSEvent mouseLocation]; - NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation]; + NSPoint windowLocation = [window convertScreenToBase: screenLocation]; int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask; NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType location: windowLocation modifierFlags: modifierFlags timestamp: 0 - windowNumber: [self.nsWindow windowNumber] + windowNumber: [window windowNumber] context: nil eventNumber: 0 trackingNumber: 0 userData: nil ]; - [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent]; + [[window contentView] deliverJavaMouseEvent: mouseEvent]; +} + ++(void) synthesizeMouseEnteredExitedEventsForAllWindows { + NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID]; + NSArray *windows = [NSApp windows]; + NSWindow *window; + + NSEnumerator *windowEnumerator = [windows objectEnumerator]; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isAWTWindow: window]) { + BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID); + BOOL mouseIsOver = [[window contentView] mouseIsOver]; + if (isUnderMouse && !mouseIsOver) { + [AWTWindow synthesizeMouseEnteredExitedEvents: window withType:NSMouseEntered]; + } else if (!isUnderMouse && mouseIsOver) { + [AWTWindow synthesizeMouseEnteredExitedEvents: window withType:NSMouseExited]; + } + } + } } + (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window { @@ -979,7 +1001,7 @@ // (this will also re-enable screen updates, which were disabled above) // TODO: send PaintEvent - [window synthesizeMouseEnteredExitedEvents]; + [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows]; }]; JNF_COCOA_EXIT(env); @@ -1158,19 +1180,40 @@ /* * Class: sun_lwawt_macosx_CPlatformWindow + * Method: nativeGetTopMostWindowUnderMouse + * Signature: (J)V + */ +JNIEXPORT jobject +JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse +(JNIEnv *env, jclass clazz) +{ + jobject topmostWindowUnderMouse = nil; + + JNF_COCOA_ENTER(env); + AWT_ASSERT_APPKIT_THREAD; + + AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse]; + if (awtWindow != nil) { + topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject]; + } + + JNF_COCOA_EXIT(env); + + return topmostWindowUnderMouse; +} + +/* + * Class: sun_lwawt_macosx_CPlatformWindow * Method: nativeSynthesizeMouseEnteredExitedEvents * Signature: (J)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents -(JNIEnv *env, jclass clazz, jlong windowPtr) +(JNIEnv *env, jclass clazz) { JNF_COCOA_ENTER(env); - NSWindow *nsWindow = OBJC(windowPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ - AWTWindow *window = (AWTWindow*)[nsWindow delegate]; - - [window synthesizeMouseEnteredExitedEvents]; + [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows]; }]; JNF_COCOA_EXIT(env); --- ./jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, 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 @@ -39,6 +39,8 @@ import sun.security.rsa.*; import sun.security.jca.Providers; +import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; +import sun.security.util.KeyUtil; /** * RSA cipher implementation. Supports RSA en/decryption and signing/verifying @@ -91,8 +93,8 @@ // padding object private RSAPadding padding; - // cipher parameter for OAEP padding - private OAEPParameterSpec spec = null; + // cipher parameter for OAEP padding and TLS RSA premaster secret + private AlgorithmParameterSpec spec = null; // buffer for the data private byte[] buffer; @@ -110,6 +112,9 @@ // hash algorithm for OAEP private String oaepHashAlgorithm = "SHA-1"; + // the source of randomness + private SecureRandom random; + public RSACipher() { paddingType = PAD_PKCS1; } @@ -175,7 +180,7 @@ // see JCE spec protected AlgorithmParameters engineGetParameters() { - if (spec != null) { + if (spec != null && spec instanceof OAEPParameterSpec) { try { AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP", "SunJCE"); @@ -278,8 +283,13 @@ buffer = new byte[n]; } else if (paddingType == PAD_PKCS1) { if (params != null) { - throw new InvalidAlgorithmParameterException - ("Parameters not supported"); + if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new InvalidAlgorithmParameterException( + "Parameters not supported"); + } + + spec = params; + this.random = random; // for TLS RSA premaster secret } int blockType = (mode <= MODE_DECRYPT) ? RSAPadding.PAD_BLOCKTYPE_2 : RSAPadding.PAD_BLOCKTYPE_1; @@ -295,19 +305,18 @@ throw new InvalidKeyException ("OAEP cannot be used to sign or verify signatures"); } - OAEPParameterSpec myParams; if (params != null) { if (!(params instanceof OAEPParameterSpec)) { throw new InvalidAlgorithmParameterException ("Wrong Parameters for OAEP Padding"); } - myParams = (OAEPParameterSpec) params; + spec = params; } else { - myParams = new OAEPParameterSpec(oaepHashAlgorithm, "MGF1", + spec = new OAEPParameterSpec(oaepHashAlgorithm, "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); } padding = RSAPadding.getInstance(RSAPadding.PAD_OAEP_MGF1, n, - random, myParams); + random, (OAEPParameterSpec)spec); if (encrypt) { int k = padding.getMaxDataSize(); buffer = new byte[k]; @@ -422,17 +431,40 @@ if (wrappedKey.length > buffer.length) { throw new InvalidKeyException("Key is too long for unwrapping"); } + + boolean isTlsRsaPremasterSecret = + algorithm.equals("TlsRsaPremasterSecret"); + Exception failover = null; + byte[] encoded = null; + update(wrappedKey, 0, wrappedKey.length); try { - byte[] encoded = doFinal(); - return ConstructKeys.constructKey(encoded, algorithm, type); + encoded = doFinal(); } catch (BadPaddingException e) { - // should not occur - throw new InvalidKeyException("Unwrapping failed", e); + if (isTlsRsaPremasterSecret) { + failover = e; + } else { + throw new InvalidKeyException("Unwrapping failed", e); + } } catch (IllegalBlockSizeException e) { // should not occur, handled with length check above throw new InvalidKeyException("Unwrapping failed", e); } + + if (isTlsRsaPremasterSecret) { + if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new IllegalStateException( + "No TlsRsaPremasterSecretParameterSpec specified"); + } + + // polish the TLS premaster secret + encoded = KeyUtil.checkTlsPreMasterSecretKey( + ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(), + ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(), + random, encoded, (failover != null)); + } + + return ConstructKeys.constructKey(encoded, algorithm, type); } // see JCE spec @@ -440,5 +472,4 @@ RSAKey rsaKey = RSAKeyFactory.toRSAKey(key); return rsaKey.getModulus().bitLength(); } - } --- ./jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java Wed Apr 16 12:37:49 2014 +0400 @@ -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 @@ -56,7 +56,7 @@ protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { - if (params instanceof TlsRsaPremasterSecretParameterSpec == false) { + if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } this.spec = (TlsRsaPremasterSecretParameterSpec)params; @@ -67,21 +67,20 @@ throw new InvalidParameterException(MSG); } + // Only can be used in client side to generate TLS RSA premaster secret. protected SecretKey engineGenerateKey() { if (spec == null) { throw new IllegalStateException( "TlsRsaPremasterSecretGenerator must be initialized"); } - byte[] b = spec.getEncodedSecret(); - if (b == null) { - if (random == null) { - random = new SecureRandom(); - } - b = new byte[48]; - random.nextBytes(b); - b[0] = (byte)spec.getMajorVersion(); - b[1] = (byte)spec.getMinorVersion(); + + if (random == null) { + random = new SecureRandom(); } + byte[] b = new byte[48]; + random.nextBytes(b); + b[0] = (byte)spec.getMajorVersion(); + b[1] = (byte)spec.getMinorVersion(); return new SecretKeySpec(b, "TlsRsaPremasterSecret"); } --- ./jdk/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, 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 @@ -34,22 +34,14 @@ import javax.management.remote.SubjectDelegationPermission; -import com.sun.jmx.remote.util.CacheMap; -import java.util.ArrayList; -import java.util.Collection; +import java.util.*; public class SubjectDelegator { - private static final int PRINCIPALS_CACHE_SIZE = 10; - private static final int ACC_CACHE_SIZE = 10; - - private CacheMap principalsCache; - private CacheMap accCache; - /* Return the AccessControlContext appropriate to execute an operation on behalf of the delegatedSubject. If the authenticatedAccessControlContext does not have permission to delegate to that subject, throw SecurityException. */ - public synchronized AccessControlContext + public AccessControlContext delegatedContext(AccessControlContext authenticatedACC, Subject delegatedSubject, boolean removeCallerContext) @@ -58,56 +50,14 @@ if (System.getSecurityManager() != null && authenticatedACC == null) { throw new SecurityException("Illegal AccessControlContext: null"); } - if (principalsCache == null || accCache == null) { - principalsCache = - new CacheMap<>(PRINCIPALS_CACHE_SIZE); - accCache = - new CacheMap<>(ACC_CACHE_SIZE); - } - - // Retrieve the principals for the given - // delegated subject from the cache - // - Principal[] delegatedPrincipals = principalsCache.get(delegatedSubject); - - // Convert the set of principals stored in the - // delegated subject into an array of principals - // and store it in the cache - // - if (delegatedPrincipals == null) { - delegatedPrincipals = - delegatedSubject.getPrincipals().toArray(new Principal[0]); - principalsCache.put(delegatedSubject, delegatedPrincipals); - } - - // Retrieve the access control context for the - // given delegated subject from the cache - // - AccessControlContext delegatedACC = accCache.get(delegatedSubject); - - // Build the access control context to be used - // when executing code as the delegated subject - // and store it in the cache - // - if (delegatedACC == null) { - if (removeCallerContext) { - delegatedACC = - JMXSubjectDomainCombiner.getDomainCombinerContext( - delegatedSubject); - } else { - delegatedACC = - JMXSubjectDomainCombiner.getContext(delegatedSubject); - } - accCache.put(delegatedSubject, delegatedACC); - } // Check if the subject delegation permission allows the // authenticated subject to assume the identity of each // principal in the delegated subject // - final Principal[] dp = delegatedPrincipals; - final Collection permissions = new ArrayList<>(dp.length); - for(Principal p : dp) { + Collection ps = getSubjectPrincipals(delegatedSubject); + final Collection permissions = new ArrayList<>(ps.size()); + for(Principal p : ps) { final String pname = p.getClass().getName() + "." + p.getName(); permissions.add(new SubjectDelegationPermission(pname)); } @@ -122,7 +72,15 @@ }; AccessController.doPrivileged(action, authenticatedACC); - return delegatedACC; + return getDelegatedAcc(delegatedSubject, removeCallerContext); + } + + private AccessControlContext getDelegatedAcc(Subject delegatedSubject, boolean removeCallerContext) { + if (removeCallerContext) { + return JMXSubjectDomainCombiner.getDomainCombinerContext(delegatedSubject); + } else { + return JMXSubjectDomainCombiner.getContext(delegatedSubject); + } } /** @@ -137,11 +95,9 @@ public static synchronized boolean checkRemoveCallerContext(Subject subject) { try { - final Principal[] dp = - subject.getPrincipals().toArray(new Principal[0]); - for (int i = 0 ; i < dp.length ; i++) { + for (Principal p : getSubjectPrincipals(subject)) { final String pname = - dp[i].getClass().getName() + "." + dp[i].getName(); + p.getClass().getName() + "." + p.getName(); final Permission sdp = new SubjectDelegationPermission(pname); AccessController.checkPermission(sdp); @@ -151,4 +107,19 @@ } return true; } + + /** + * Retrieves the {@linkplain Subject} principals + * @param subject The subject + * @return If the {@code Subject} is immutable it will return the principals directly. + * If the {@code Subject} is mutable it will create an unmodifiable copy. + */ + private static Collection getSubjectPrincipals(Subject subject) { + if (subject.isReadOnly()) { + return subject.getPrincipals(); + } + + List principals = Arrays.asList(subject.getPrincipals().toArray(new Principal[0])); + return Collections.unmodifiableList(principals); + } } --- ./jdk/src/share/classes/com/sun/jmx/remote/util/CacheMap.java Wed May 07 19:26:47 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2003, 2006, 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 com.sun.jmx.remote.util; - -import java.lang.ref.SoftReference; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.WeakHashMap; - -import com.sun.jmx.mbeanserver.Util; - -/** - *

Like WeakHashMap, except that the keys of the n most - * recently-accessed entries are kept as {@link SoftReference soft - * references}. Accessing an element means creating it, or retrieving - * it with {@link #get(Object) get}. Because these entries are kept - * with soft references, they will tend to remain even if their keys - * are not referenced elsewhere. But if memory is short, they will - * be removed.

- */ -public class CacheMap extends WeakHashMap { - /** - *

Create a CacheMap that can keep up to - * nSoftReferences as soft references.

- * - * @param nSoftReferences Maximum number of keys to keep as soft - * references. Access times for {@link #get(Object) get} and - * {@link #put(Object, Object) put} have a component that scales - * linearly with nSoftReferences, so this value - * should not be too great. - * - * @throws IllegalArgumentException if - * nSoftReferences is negative. - */ - public CacheMap(int nSoftReferences) { - if (nSoftReferences < 0) { - throw new IllegalArgumentException("nSoftReferences = " + - nSoftReferences); - } - this.nSoftReferences = nSoftReferences; - } - - public V put(K key, V value) { - cache(key); - return super.put(key, value); - } - - public V get(Object key) { - cache(Util.cast(key)); - return super.get(key); - } - - /* We don't override remove(Object) or try to do something with - the map's iterators to detect removal. So we may keep useless - entries in the soft reference list for keys that have since - been removed. The assumption is that entries are added to the - cache but never removed. But the behavior is not wrong if - they are in fact removed -- the caching is just less - performant. */ - - private void cache(K key) { - Iterator> it = cache.iterator(); - while (it.hasNext()) { - SoftReference sref = it.next(); - K key1 = sref.get(); - if (key1 == null) - it.remove(); - else if (key.equals(key1)) { - // Move this element to the head of the LRU list - it.remove(); - cache.add(0, sref); - return; - } - } - - int size = cache.size(); - if (size == nSoftReferences) { - if (size == 0) - return; // degenerate case, equivalent to WeakHashMap - it.remove(); - } - - cache.add(0, new SoftReference(key)); - } - - /* List of soft references for the most-recently referenced keys. - The list is in most-recently-used order, i.e. the first element - is the most-recently referenced key. There are never more than - nSoftReferences elements of this list. - - If we didn't care about J2SE 1.3 compatibility, we could use - LinkedHashSet in conjunction with a subclass of SoftReference - whose equals and hashCode reflect the referent. */ - private final LinkedList> cache = - new LinkedList>(); - private final int nSoftReferences; -} --- ./jdk/src/share/classes/com/sun/security/sasl/CramMD5Base.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/com/sun/security/sasl/CramMD5Base.java Wed Apr 16 12:37:49 2014 +0400 @@ -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 @@ -32,6 +32,7 @@ import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; +import java.util.Arrays; import java.util.logging.Logger; /** @@ -159,7 +160,7 @@ MessageDigest md5 = MessageDigest.getInstance("MD5"); /* digest the key if longer than 64 bytes */ - if (key.length > 64) { + if (key.length > MD5_BLOCKSIZE) { key = md5.digest(key); } @@ -169,13 +170,9 @@ int i; /* store key in pads */ - for (i = 0; i < MD5_BLOCKSIZE; i++) { - for ( ; i < key.length; i++) { - ipad[i] = key[i]; - opad[i] = key[i]; - } - ipad[i] = 0x00; - opad[i] = 0x00; + for (i = 0; i < key.length; i++) { + ipad[i] = key[i]; + opad[i] = key[i]; } /* XOR key with pads */ @@ -207,6 +204,11 @@ } } + Arrays.fill(ipad, (byte)0); + Arrays.fill(opad, (byte)0); + ipad = null; + opad = null; + return (digestString.toString()); } --- ./jdk/src/share/classes/java/awt/Component.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/awt/Component.java Wed Apr 16 12:37:49 2014 +0400 @@ -7922,7 +7922,7 @@ res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD); } } - if (!res) { + if (clearOnFailure && !res) { if (focusLog.isLoggable(PlatformLogger.FINER)) { focusLog.finer("clear global focus owner"); } --- ./jdk/src/share/classes/java/awt/KeyboardFocusManager.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/awt/KeyboardFocusManager.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, 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 @@ -248,15 +248,7 @@ public static void setCurrentKeyboardFocusManager( KeyboardFocusManager newManager) throws SecurityException { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (replaceKeyboardFocusManagerPermission == null) { - replaceKeyboardFocusManagerPermission = - new AWTPermission("replaceKeyboardFocusManager"); - } - security. - checkPermission(replaceKeyboardFocusManagerPermission); - } + checkReplaceKFMPermission(); KeyboardFocusManager oldManager = null; @@ -508,7 +500,7 @@ */ protected Component getGlobalFocusOwner() throws SecurityException { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); return focusOwner; } } @@ -543,7 +535,7 @@ if (focusOwner == null || focusOwner.isFocusable()) { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); oldFocusOwner = getFocusOwner(); @@ -595,7 +587,7 @@ */ public void clearGlobalFocusOwner() { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); } if (!GraphicsEnvironment.isHeadless()) { // Toolkit must be fully initialized, otherwise @@ -676,7 +668,7 @@ throws SecurityException { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); return permanentFocusOwner; } } @@ -712,7 +704,7 @@ if (permanentFocusOwner == null || permanentFocusOwner.isFocusable()) { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); oldPermanentFocusOwner = getPermanentFocusOwner(); @@ -779,7 +771,7 @@ */ protected Window getGlobalFocusedWindow() throws SecurityException { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); return focusedWindow; } } @@ -811,7 +803,7 @@ if (focusedWindow == null || focusedWindow.isFocusableWindow()) { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); oldFocusedWindow = getFocusedWindow(); @@ -879,7 +871,7 @@ */ protected Window getGlobalActiveWindow() throws SecurityException { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); return activeWindow; } } @@ -909,7 +901,7 @@ protected void setGlobalActiveWindow(Window activeWindow) { Window oldActiveWindow; synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); oldActiveWindow = getActiveWindow(); if (focusLog.isLoggable(PlatformLogger.FINER)) { @@ -1205,7 +1197,7 @@ throws SecurityException { synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); return currentFocusCycleRoot; } } @@ -1230,7 +1222,7 @@ Container oldFocusCycleRoot; synchronized (KeyboardFocusManager.class) { - checkCurrentKFMSecurity(); + checkKFMSecurity(); oldFocusCycleRoot = getCurrentFocusCycleRoot(); currentFocusCycleRoot = newFocusCycleRoot; @@ -2368,7 +2360,8 @@ focusLog.finest("Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && - heavyweight == nativeFocusOwner) + heavyweight == nativeFocusOwner && + heavyweight.getContainingWindow() == nativeFocusedWindow) { if (descendant == currentFocusOwner) { // Redundant request. @@ -3050,13 +3043,36 @@ } } - private void checkCurrentKFMSecurity() { + private static void checkReplaceKFMPermission() + throws SecurityException + { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + if (replaceKeyboardFocusManagerPermission == null) { + replaceKeyboardFocusManagerPermission = + new AWTPermission("replaceKeyboardFocusManager"); + } + security. + checkPermission(replaceKeyboardFocusManagerPermission); + } + } + + // Checks if this KeyboardFocusManager instance is the current KFM, + // or otherwise checks if the calling thread has "replaceKeyboardFocusManager" + // permission. Here's the reasoning to do so: + // + // A system KFM instance (which is the current KFM by default) may have no + // "replaceKFM" permission when a client code is on the call stack beneath, + // but still it should be able to execute the methods protected by this check + // due to the system KFM is trusted (and so it does like "privileged"). + // + // If this KFM instance is not the current KFM but the client code has all + // permissions we can't throw SecurityException because it would contradict + // the security concepts. In this case the trusted client code is responsible + // for calling the secured methods from KFM instance which is not current. + private void checkKFMSecurity() { if (this != getCurrentKeyboardFocusManager()) { - if (focusLog.isLoggable(PlatformLogger.FINER)) { - focusLog.finer("This manager is " + this + - ", current is " + getCurrentKeyboardFocusManager()); - } - throw new SecurityException(notPrivileged); + checkReplaceKFMPermission(); } } } --- ./jdk/src/share/classes/java/io/ObjectOutputStream.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/io/ObjectOutputStream.java Wed Apr 16 12:37:49 2014 +0400 @@ -1254,7 +1254,7 @@ } bout.setBlockDataMode(true); - if (isCustomSubclass()) { + if (cl != null && isCustomSubclass()) { ReflectUtil.checkPackageAccess(cl); } annotateProxyClass(cl); @@ -1283,7 +1283,7 @@ Class cl = desc.forClass(); bout.setBlockDataMode(true); - if (isCustomSubclass()) { + if (cl != null && isCustomSubclass()) { ReflectUtil.checkPackageAccess(cl); } annotateClass(cl); --- ./jdk/src/share/classes/java/lang/Class.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/Class.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -2338,44 +2338,110 @@ } /** + * Atomic operations support. + */ + private static class Atomic { + // initialize Unsafe machinery here, since we need to call Class.class instance method + // and have to avoid calling it in the static initializer of the Class class... + private static final Unsafe unsafe = Unsafe.getUnsafe(); + // offset of Class.reflectionData instance field + private static final long reflectionDataOffset; + // offset of Class.annotationType instance field + private static final long annotationTypeOffset; + + static { + Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches + reflectionDataOffset = objectFieldOffset(fields, "reflectionData"); + annotationTypeOffset = objectFieldOffset(fields, "annotationType"); + } + + private static long objectFieldOffset(Field[] fields, String fieldName) { + Field field = searchFields(fields, fieldName); + if (field == null) { + throw new Error("No " + fieldName + " field found in java.lang.Class"); + } + return unsafe.objectFieldOffset(field); + } + + static boolean casReflectionData(Class clazz, + SoftReference> oldData, + SoftReference> newData) { + return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData); + } + + static boolean casAnnotationType(Class clazz, + AnnotationType oldType, + AnnotationType newType) { + return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType); + } + } + + /** * Reflection support. */ // Caches for certain reflective results private static boolean useCaches = true; - private volatile transient SoftReference declaredFields; - private volatile transient SoftReference publicFields; - private volatile transient SoftReference declaredMethods; - private volatile transient SoftReference publicMethods; - private volatile transient SoftReference[]> declaredConstructors; - private volatile transient SoftReference[]> publicConstructors; - // Intermediate results for getFields and getMethods - private volatile transient SoftReference declaredPublicFields; - private volatile transient SoftReference declaredPublicMethods; + + // reflection data that might get invalidated when JVM TI RedefineClasses() is called + static class ReflectionData { + volatile Field[] declaredFields; + volatile Field[] publicFields; + volatile Method[] declaredMethods; + volatile Method[] publicMethods; + volatile Constructor[] declaredConstructors; + volatile Constructor[] publicConstructors; + // Intermediate results for getFields and getMethods + volatile Field[] declaredPublicFields; + volatile Method[] declaredPublicMethods; + // Value of classRedefinedCount when we created this ReflectionData instance + final int redefinedCount; + + ReflectionData(int redefinedCount) { + this.redefinedCount = redefinedCount; + } + } + + private volatile transient SoftReference> reflectionData; // Incremented by the VM on each call to JVM TI RedefineClasses() // that redefines this class or a superclass. private volatile transient int classRedefinedCount = 0; - // Value of classRedefinedCount when we last cleared the cached values - // that are sensitive to class redefinition. - private volatile transient int lastRedefinedCount = 0; + // Lazily create and cache ReflectionData + private ReflectionData reflectionData() { + SoftReference> reflectionData = this.reflectionData; + int classRedefinedCount = this.classRedefinedCount; + ReflectionData rd; + if (useCaches && + reflectionData != null && + (rd = reflectionData.get()) != null && + rd.redefinedCount == classRedefinedCount) { + return rd; + } + // else no SoftReference or cleared SoftReference or stale ReflectionData + // -> create and replace new instance + return newReflectionData(reflectionData, classRedefinedCount); + } - // Clears cached values that might possibly have been obsoleted by - // a class redefinition. - private void clearCachesOnClassRedefinition() { - if (lastRedefinedCount != classRedefinedCount) { - declaredFields = publicFields = declaredPublicFields = null; - declaredMethods = publicMethods = declaredPublicMethods = null; - declaredConstructors = publicConstructors = null; - annotations = declaredAnnotations = null; + private ReflectionData newReflectionData(SoftReference> oldReflectionData, + int classRedefinedCount) { + if (!useCaches) return null; - // Use of "volatile" (and synchronization by caller in the case - // of annotations) ensures that no thread sees the update to - // lastRedefinedCount before seeing the caches cleared. - // We do not guard against brief windows during which multiple - // threads might redundantly work to fill an empty cache. - lastRedefinedCount = classRedefinedCount; + while (true) { + ReflectionData rd = new ReflectionData<>(classRedefinedCount); + // try to CAS it... + if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) { + return rd; + } + // else retry + oldReflectionData = this.reflectionData; + classRedefinedCount = this.classRedefinedCount; + if (oldReflectionData != null && + (rd = oldReflectionData.get()) != null && + rd.redefinedCount == classRedefinedCount) { + return rd; + } } } @@ -2403,7 +2469,7 @@ } // Annotations handling - private native byte[] getRawAnnotations(); + native byte[] getRawAnnotations(); native ConstantPool getConstantPool(); @@ -2418,27 +2484,19 @@ // via ReflectionFactory.copyField. private Field[] privateGetDeclaredFields(boolean publicOnly) { checkInitted(); - Field[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicOnly) { - if (declaredPublicFields != null) { - res = declaredPublicFields.get(); - } - } else { - if (declaredFields != null) { - res = declaredFields.get(); - } - } + Field[] res; + ReflectionData rd = reflectionData(); + if (rd != null) { + res = publicOnly ? rd.declaredPublicFields : rd.declaredFields; if (res != null) return res; } // No cached value available; request value from VM res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); - if (useCaches) { + if (rd != null) { if (publicOnly) { - declaredPublicFields = new SoftReference<>(res); + rd.declaredPublicFields = res; } else { - declaredFields = new SoftReference<>(res); + rd.declaredFields = res; } } return res; @@ -2449,12 +2507,10 @@ // via ReflectionFactory.copyField. private Field[] privateGetPublicFields(Set> traversedInterfaces) { checkInitted(); - Field[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicFields != null) { - res = publicFields.get(); - } + Field[] res; + ReflectionData rd = reflectionData(); + if (rd != null) { + res = rd.publicFields; if (res != null) return res; } @@ -2487,8 +2543,8 @@ res = new Field[fields.size()]; fields.toArray(res); - if (useCaches) { - publicFields = new SoftReference<>(res); + if (rd != null) { + rd.publicFields = res; } return res; } @@ -2511,18 +2567,10 @@ // instead be copied via ReflectionFactory.copyConstructor. private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { checkInitted(); - Constructor[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicOnly) { - if (publicConstructors != null) { - res = publicConstructors.get(); - } - } else { - if (declaredConstructors != null) { - res = declaredConstructors.get(); - } - } + Constructor[] res; + ReflectionData rd = reflectionData(); + if (rd != null) { + res = publicOnly ? rd.publicConstructors : rd.declaredConstructors; if (res != null) return res; } // No cached value available; request value from VM @@ -2531,11 +2579,11 @@ } else { res = getDeclaredConstructors0(publicOnly); } - if (useCaches) { + if (rd != null) { if (publicOnly) { - publicConstructors = new SoftReference<>(res); + rd.publicConstructors = res; } else { - declaredConstructors = new SoftReference<>(res); + rd.declaredConstructors = res; } } return res; @@ -2552,27 +2600,19 @@ // via ReflectionFactory.copyMethod. private Method[] privateGetDeclaredMethods(boolean publicOnly) { checkInitted(); - Method[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicOnly) { - if (declaredPublicMethods != null) { - res = declaredPublicMethods.get(); - } - } else { - if (declaredMethods != null) { - res = declaredMethods.get(); - } - } + Method[] res; + ReflectionData rd = reflectionData(); + if (rd != null) { + res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods; if (res != null) return res; } // No cached value available; request value from VM res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); - if (useCaches) { + if (rd != null) { if (publicOnly) { - declaredPublicMethods = new SoftReference<>(res); + rd.declaredPublicMethods = res; } else { - declaredMethods = new SoftReference<>(res); + rd.declaredMethods = res; } } return res; @@ -2674,12 +2714,10 @@ // via ReflectionFactory.copyMethod. private Method[] privateGetPublicMethods() { checkInitted(); - Method[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicMethods != null) { - res = publicMethods.get(); - } + Method[] res; + ReflectionData rd = reflectionData(); + if (rd != null) { + res = rd.publicMethods; if (res != null) return res; } @@ -2727,8 +2765,8 @@ methods.addAllIfNotPresent(inheritedMethods); methods.compactAndTrim(); res = methods.getArray(); - if (useCaches) { - publicMethods = new SoftReference<>(res); + if (rd != null) { + rd.publicMethods = res; } return res; } @@ -2738,7 +2776,7 @@ // Helpers for fetchers of one field, method, or constructor // - private Field searchFields(Field[] fields, String name) { + private static Field searchFields(Field[] fields, String name) { String internedName = name.intern(); for (int i = 0; i < fields.length; i++) { if (fields[i].getName() == internedName) { @@ -2756,7 +2794,7 @@ // of Field objects which have to be created for the common // case where the field being requested is declared in the // class which is being queried. - Field res = null; + Field res; // Search declared public fields if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) { return res; @@ -2808,7 +2846,7 @@ // number of Method objects which have to be created for the // common case where the method being requested is declared in // the class which is being queried. - Method res = null; + Method res; // Search declared public methods if ((res = searchMethods(privateGetDeclaredMethods(true), name, @@ -3209,9 +3247,20 @@ // Annotations cache private transient Map, Annotation> annotations; private transient Map, Annotation> declaredAnnotations; + // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields + private transient int lastAnnotationsRedefinedCount = 0; + + // Clears cached values that might possibly have been obsoleted by + // a class redefinition. + private void clearAnnotationCachesOnClassRedefinition() { + if (lastAnnotationsRedefinedCount != classRedefinedCount) { + annotations = declaredAnnotations = null; + lastAnnotationsRedefinedCount = classRedefinedCount; + } + } private synchronized void initAnnotationsIfNecessary() { - clearCachesOnClassRedefinition(); + clearAnnotationCachesOnClassRedefinition(); if (annotations != null) return; declaredAnnotations = AnnotationParser.parseAnnotations( @@ -3233,10 +3282,11 @@ // Annotation types cache their internal (AnnotationType) form - private AnnotationType annotationType; + @SuppressWarnings("UnusedDeclaration") + private volatile transient AnnotationType annotationType; - void setAnnotationType(AnnotationType type) { - annotationType = type; + boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) { + return Atomic.casAnnotationType(this, oldType, newType); } AnnotationType getAnnotationType() { --- ./jdk/src/share/classes/java/lang/ProcessBuilder.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/ProcessBuilder.java Wed Apr 16 12:37:49 2014 +0400 @@ -1018,6 +1018,12 @@ String dir = directory == null ? null : directory.toString(); + for (int i = 1; i < cmdarray.length; i++) { + if (cmdarray[i].indexOf('\u0000') >= 0) { + throw new IOException("invalid null character in command"); + } + } + try { return ProcessImpl.start(cmdarray, environment, --- ./jdk/src/share/classes/java/lang/System.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/System.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -1178,12 +1178,15 @@ public sun.reflect.ConstantPool getConstantPool(Class klass) { return klass.getConstantPool(); } - public void setAnnotationType(Class klass, AnnotationType type) { - klass.setAnnotationType(type); + public boolean casAnnotationType(Class klass, AnnotationType oldType, AnnotationType newType) { + return klass.casAnnotationType(oldType, newType); } public AnnotationType getAnnotationType(Class klass) { return klass.getAnnotationType(); } + public byte[] getRawClassAnnotations(Class klass) { + return klass.getRawAnnotations(); + } public > E[] getEnumConstantsShared(Class klass) { return klass.getEnumConstantsShared(); --- ./jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Apr 16 12:37:49 2014 +0400 @@ -243,12 +243,12 @@ assert(names.length == nameCursor); if (doesAlloc) { // names = { argx,y,z,... new C, init method } - names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]); - names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); + names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]); } else if (needsInit) { - names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]); } else { - names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]); } Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! @@ -596,18 +596,18 @@ final int RESULT = nameCursor-1; // either the call or the cast Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); if (needsInit) - names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); + names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]); if (needsCast && !isGetter) - names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); + names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert(outArgs.length == (isGetter ? 3 : 4)); outArgs[0] = UNSAFE; if (isStatic) { - outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); - outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); + outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]); } else { - outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); - outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); + outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]); } if (!isGetter) { outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); @@ -615,7 +615,7 @@ for (Object a : outArgs) assert(a != null); names[LINKER_CALL] = new Name(linker, outArgs); if (needsCast && isGetter) - names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); + names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); for (Name n : names) assert(n != null); String fieldOrStatic = (isStatic ? "Static" : "Field"); String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging @@ -624,48 +624,54 @@ return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); } - private static final NamedFunction - NF_internalMemberName, - NF_internalMemberNameEnsureInit, - NF_ensureInitialized, - NF_fieldOffset, - NF_checkBase, - NF_staticBase, - NF_staticOffset, - NF_checkCast, - NF_allocateInstance, - NF_constructorMethod; - static { - try { - NamedFunction nfs[] = { - NF_internalMemberName = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberName", Object.class)), - NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), - NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("ensureInitialized", Object.class)), - NF_fieldOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("fieldOffset", Object.class)), - NF_checkBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkBase", Object.class)), - NF_staticBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticBase", Object.class)), - NF_staticOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticOffset", Object.class)), - NF_checkCast = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkCast", Object.class, Object.class)), - NF_allocateInstance = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("allocateInstance", Object.class)), - NF_constructorMethod = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("constructorMethod", Object.class)) - }; - for (NamedFunction nf : nfs) { - // Each nf must be statically invocable or we get tied up in our bootstraps. - assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; - nf.resolve(); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction + NF_internalMemberName, + NF_internalMemberNameEnsureInit, + NF_ensureInitialized, + NF_fieldOffset, + NF_checkBase, + NF_staticBase, + NF_staticOffset, + NF_checkCast, + NF_allocateInstance, + NF_constructorMethod; + static { + try { + NamedFunction nfs[] = { + NF_internalMemberName = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberName", Object.class)), + NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), + NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("ensureInitialized", Object.class)), + NF_fieldOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("fieldOffset", Object.class)), + NF_checkBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkBase", Object.class)), + NF_staticBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticBase", Object.class)), + NF_staticOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticOffset", Object.class)), + NF_checkCast = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkCast", Object.class, Object.class)), + NF_allocateInstance = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("allocateInstance", Object.class)), + NF_constructorMethod = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("constructorMethod", Object.class)) + }; + for (NamedFunction nf : nfs) { + // Each nf must be statically invocable or we get tied up in our bootstraps. + assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; + nf.resolve(); + } + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); } - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); } } } --- ./jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Apr 16 12:37:49 2014 +0400 @@ -613,6 +613,12 @@ return false; // inner class of some sort if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) return false; // not on BCP + MethodType mtype = member.getMethodOrFieldType(); + if (!isStaticallyNameable(mtype.returnType())) + return false; + for (Class ptype : mtype.parameterArray()) + if (!isStaticallyNameable(ptype)) + return false; if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) return true; // in java.lang.invoke package if (member.isPublic() && isStaticallyNameable(cls)) --- ./jdk/src/share/classes/java/lang/invoke/Invokers.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/invoke/Invokers.java Wed Apr 16 12:37:49 2014 +0400 @@ -318,6 +318,7 @@ // let mt=TYPEOF(a*:R), tmh=asType(mh, mt); // tmh.invokeBasic(a*) outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); + outArgs[0] = names[CHECK_TYPE]; outCallType = mtype; } else { names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg); --- ./jdk/src/share/classes/java/lang/invoke/MethodHandle.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/lang/invoke/MethodHandle.java Wed Apr 16 12:37:49 2014 +0400 @@ -753,6 +753,10 @@ * to the target method handle. * (The array may also be null when zero elements are required.) *

+ * If, when the adapter is called, the supplied array argument does + * not have the correct number of elements, the adapter will throw + * an {@link IllegalArgumentException} instead of invoking the target. + *

* Here are some simple examples of array-spreading method handles: *

 MethodHandle equals = publicLookup()
@@ -763,6 +767,12 @@
 MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
 assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
 assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
+// try to spread from anything but a 2-array:
+for (int n = 0; n <= 10; n++) {
+  Object[] badArityArgs = (n == 2 ? null : new Object[n]);
+  try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
+  catch (IllegalArgumentException ex) { } // OK
+}
 // spread both arguments from a String array:
 MethodHandle eq2s = equals.asSpreader(String[].class, 2);
 assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
--- ./jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed May 07 19:26:47 2014 -0700
+++ ./jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Apr 16 12:37:49 2014 +0400
@@ -430,7 +430,7 @@
                 // Spread the array.
                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
                 Name array = names[argIndex];
-                names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount);
+                names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount);
                 for (int j = 0; j < spreadArgCount; i++, j++) {
                     indexes[i] = nameCursor;
                     names[nameCursor++] = new Name(aload, array, j);
@@ -454,14 +454,8 @@
     }
 
     static void checkSpreadArgument(Object av, int n) {
-        // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
-        // but the actual exception raised by an arity mismatch should be WMTE
-        final boolean RAISE_RANDOM_EXCEPTIONS = true;  // FIXME: delete in JSR 292 M1
         if (av == null) {
             if (n == 0)  return;
-            int len;
-            if (RAISE_RANDOM_EXCEPTIONS)
-                len = ((Object[])av).length;  // throw NPE; but delete this after tests are fixed
         } else if (av instanceof Object[]) {
             int len = ((Object[])av).length;
             if (len == n)  return;
@@ -470,19 +464,23 @@
             if (len == n)  return;
         }
         // fall through to error:
-        if (RAISE_RANDOM_EXCEPTIONS)
-            throw newIllegalArgumentException("Array is not of length "+n);
-        throw new WrongMethodTypeException("Array is not of length "+n);
+        throw newIllegalArgumentException("array is not of length "+n);
     }
 
-    private static final NamedFunction NF_checkSpreadArgument;
-    static {
-        try {
-            NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
-                    .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
-            NF_checkSpreadArgument.resolve();
-        } catch (ReflectiveOperationException ex) {
-            throw newInternalError(ex);
+    /**
+     * Pre-initialized NamedFunctions for bootstrapping purposes.
+     * Factored in an inner class to delay initialization until first usage.
+     */
+    private static class Lazy {
+        static final NamedFunction NF_checkSpreadArgument;
+        static {
+            try {
+                NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
+                        .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
+                NF_checkSpreadArgument.resolve();
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError(ex);
+            }
         }
     }
 
--- ./jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Wed May 07 19:26:47 2014 -0700
+++ ./jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Wed Apr 16 12:37:49 2014 +0400
@@ -26,12 +26,15 @@
 package java.lang.invoke;
 
 import java.lang.reflect.*;
+
 import sun.invoke.util.ValueConversions;
 import sun.invoke.util.VerifyAccess;
 import sun.invoke.util.Wrapper;
+
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Arrays;
+
 import sun.reflect.CallerSensitive;
 import sun.reflect.Reflection;
 import sun.reflect.misc.ReflectUtil;
@@ -245,6 +248,9 @@
      * In general, the conditions under which a method handle may be
      * looked up for a method {@code M} are exactly equivalent to the conditions
      * under which the lookup class could have compiled and resolved a call to {@code M}.
+     * Where the JVM would raise exceptions like {@code NoSuchMethodError},
+     * a method handle lookup will generally raise a corresponding
+     * checked exception, such as {@code NoSuchMethodException}.
      * And the effect of invoking the method handle resulting from the lookup
      * is exactly equivalent to executing the compiled and resolved call to {@code M}.
      * The same point is true of fields and constructors.
@@ -261,6 +267,12 @@
      * (which will necessarily be a superclass of the lookup class)
      * to the lookup class itself.
      * 

+ * The JVM represents constructors and static initializer blocks as internal methods + * with special names ({@code ""} and {@code ""}). + * The internal syntax of invocation instructions allows them to refer to such internal + * methods as if they were normal methods, but the JVM verifier rejects them. + * A lookup of such an internal method will produce a {@code NoSuchMethodException}. + *

* In some cases, access between nested classes is obtained by the Java compiler by creating * an wrapper method to access a private method of another class * in the same top-level declaration. @@ -575,6 +587,15 @@ * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * Example: + *

{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
+  "asList", methodType(List.class, Object[].class));
+assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
+         * }
* @param refc the class from which the method is accessed * @param name the name of the method * @param type the type of the method @@ -625,6 +646,34 @@ * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker} * with the same {@code type} argument. * + * Example: + *

{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_concat = publicLookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
+  "hashCode", methodType(int.class));
+MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
+  "hashCode", methodType(int.class));
+assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
+assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
+assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
+// interface method:
+MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
+  "subSequence", methodType(CharSequence.class, int.class, int.class));
+assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
+// constructor "internal method" must be accessed differently:
+MethodType MT_newString = methodType(void.class); //()V for new String()
+try { assertEquals("impossible", lookup()
+        .findVirtual(String.class, "", MT_newString));
+ } catch (NoSuchMethodException ex) { } // OK
+MethodHandle MH_newString = publicLookup()
+  .findConstructor(String.class, MT_newString);
+assertEquals("", (String) MH_newString.invokeExact());
+         * }
+ * * @param refc the class or interface from which the method is accessed * @param name the name of the method * @param type the type of the method, with the receiver argument omitted @@ -666,12 +715,30 @@ * If the constructor's class has not yet been initialized, that is done * immediately, before the method handle is returned. *

- * Note: The requested type must have a return type of {@code void}. - * This is consistent with the JVM's treatment of constructor type descriptors. + * (Note: The requested type must have a return type of {@code void}. + * This is consistent with the JVM's treatment of constructor type descriptors.) *

* The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + * Example: + *

{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_newArrayList = publicLookup().findConstructor(
+  ArrayList.class, methodType(void.class, Collection.class));
+Collection orig = Arrays.asList("x", "y");
+Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
+assert(orig != copy);
+assertEquals(orig, copy);
+// a variable-arity constructor:
+MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
+  ProcessBuilder.class, methodType(void.class, String[].class));
+ProcessBuilder pb = (ProcessBuilder)
+  MH_newProcessBuilder.invoke("x", "y", "z");
+assertEquals("[x, y, z]", pb.command().toString());
+         * }
* @param refc the class or interface from which the method is accessed * @param type the type of the method, with the receiver argument omitted, and a void return type * @return the desired method handle @@ -711,6 +778,45 @@ * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + *

+ * (Note: JVM internal methods named {@code } not visible to this API, + * even though the {@code invokespecial} instruction can refer to them + * in special circumstances. Use {@link #findConstructor findConstructor} + * to access instance initialization methods in a safe manner.) + * Example: + *

{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+static class Listie extends ArrayList {
+  public String toString() { return "[wee Listie]"; }
+  static Lookup lookup() { return MethodHandles.lookup(); }
+}
+...
+// no access to constructor via invokeSpecial:
+MethodHandle MH_newListie = Listie.lookup()
+  .findConstructor(Listie.class, methodType(void.class));
+Listie l = (Listie) MH_newListie.invokeExact();
+try { assertEquals("impossible", Listie.lookup().findSpecial(
+        Listie.class, "", methodType(void.class), Listie.class));
+ } catch (NoSuchMethodException ex) { } // OK
+// access to super and self methods via invokeSpecial:
+MethodHandle MH_super = Listie.lookup().findSpecial(
+  ArrayList.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_this = Listie.lookup().findSpecial(
+  Listie.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_duper = Listie.lookup().findSpecial(
+  Object.class, "toString" , methodType(String.class), Listie.class);
+assertEquals("[]", (String) MH_super.invokeExact(l));
+assertEquals(""+l, (String) MH_this.invokeExact(l));
+assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
+try { assertEquals("inaccessible", Listie.lookup().findSpecial(
+        String.class, "toString", methodType(String.class), Listie.class));
+ } catch (IllegalAccessException ex) { } // OK
+Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
+assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
+         * }
+ * * @param refc the class or interface from which the method is accessed * @param name the name of the method (which must not be "<init>") * @param type the type of the method, with the receiver argument omitted @@ -1014,15 +1120,16 @@ /// Helper methods, all package-private. MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { + name.getClass(); type.getClass(); // NPE checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchFieldException.class); } MemberName resolveOrFail(byte refKind, Class refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { + type.getClass(); // NPE checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE + checkMethodName(refKind, name); return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); } @@ -1033,6 +1140,12 @@ throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); } + void checkMethodName(byte refKind, String name) throws NoSuchMethodException { + if (name.startsWith("<") && refKind != REF_newInvokeSpecial) + throw new NoSuchMethodException("illegal method name: "+name); + } + + /** * Find my trustable caller class if m is a caller sensitive method. * If this lookup object has private access, then the caller class is the lookupClass. @@ -1155,6 +1268,10 @@ int allowedModes = this.allowedModes; if (allowedModes == TRUSTED) return; int mods = m.getModifiers(); + if (Modifier.isProtected(mods) && refKind == REF_newInvokeSpecial) { + // cannot "new" a protected ctor in a different package + mods ^= Modifier.PROTECTED; + } if (Modifier.isFinal(mods) && MethodHandleNatives.refKindIsSetter(refKind)) throw m.makeAccessException("unexpected set of a final field", this); @@ -1399,6 +1516,9 @@ *

* Before invoking its target, the invoker will spread the final array, apply * reference casts as necessary, and unbox and widen primitive arguments. + * If, when the invoker is called, the supplied array argument does + * not have the correct number of elements, the invoker will throw + * an {@link IllegalArgumentException} instead of invoking the target. *

* This method is equivalent to the following code (though it may be more efficient): *

--- ./jdk/src/share/classes/java/lang/reflect/Proxy.java	Wed May 07 19:26:47 2014 -0700
+++ ./jdk/src/share/classes/java/lang/reflect/Proxy.java	Wed Apr 16 12:37:49 2014 +0400
@@ -396,12 +396,13 @@
                                          Class... interfaces)
         throws IllegalArgumentException
     {
-        SecurityManager sm = System.getSecurityManager();
+        final Class[] intfs = interfaces.clone();
+        final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
         }
 
-        return getProxyClass0(loader, interfaces);
+        return getProxyClass0(loader, intfs);
     }
 
     /*
@@ -725,15 +726,16 @@
             throw new NullPointerException();
         }
 
+        final Class[] intfs = interfaces.clone();
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
         }
 
         /*
          * Look up or generate the designated proxy class.
          */
-        Class cl = getProxyClass0(loader, interfaces);
+        Class cl = getProxyClass0(loader, intfs);
 
         /*
          * Invoke its constructor with the designated invocation handler.
--- ./jdk/src/share/classes/java/security/Provider.java	Wed May 07 19:26:47 2014 -0700
+++ ./jdk/src/share/classes/java/security/Provider.java	Wed Apr 16 12:37:49 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, 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
@@ -1017,7 +1017,7 @@
      * 

This class defines the methods {@link #supportsParameter * supportsParameter()} and {@link #newInstance newInstance()} * which are used by the Java security framework when it searches for - * suitable services and instantes them. The valid arguments to those + * suitable services and instantiates them. The valid arguments to those * methods depend on the type of service. For the service types defined * within Java SE, see the * @@ -1207,7 +1207,7 @@ * * @throws InvalidParameterException if the value of * constructorParameter is invalid for this type of service. - * @throws NoSuchAlgorithmException if instantation failed for + * @throws NoSuchAlgorithmException if instantiation failed for * any other reason. */ public Object newInstance(Object constructorParameter) @@ -1235,7 +1235,9 @@ + " engines"); } Class clazz = getImplClass(); - return clazz.newInstance(); + Class[] empty = {}; + Constructor con = clazz.getConstructor(empty); + return con.newInstance(); } else { Class paramClass = cap.getConstructorParameterClass(); if (constructorParameter != null) { @@ -1278,13 +1280,18 @@ } else { clazz = cl.loadClass(className); } + if (!Modifier.isPublic(clazz.getModifiers())) { + throw new NoSuchAlgorithmException + ("class configured for " + type + " (provider: " + + provider.getName() + ") is not public."); + } classRef = new WeakReference(clazz); } return clazz; } catch (ClassNotFoundException e) { throw new NoSuchAlgorithmException ("class configured for " + type + "(provider: " + - provider.getName() + ")" + "cannot be found.", e); + provider.getName() + ") cannot be found.", e); } } @@ -1297,15 +1304,21 @@ throws Exception { Class clazz = getImplClass(); if (constructorParameter == null) { - Object o = clazz.newInstance(); - return o; + // create instance with public no-arg constructor if it exists + try { + Class[] empty = {}; + Constructor con = clazz.getConstructor(empty); + return con.newInstance(); + } catch (NoSuchMethodException e) { + throw new NoSuchAlgorithmException("No public no-arg " + + "constructor found in class " + className); + } } Class argClass = constructorParameter.getClass(); Constructor[] cons = clazz.getConstructors(); // find first public constructor that can take the // argument as parameter - for (int i = 0; i < cons.length; i++) { - Constructor con = cons[i]; + for (Constructor con : cons) { Class[] paramTypes = con.getParameterTypes(); if (paramTypes.length != 1) { continue; @@ -1313,10 +1326,9 @@ if (paramTypes[0].isAssignableFrom(argClass) == false) { continue; } - Object o = con.newInstance(new Object[] {constructorParameter}); - return o; + return con.newInstance(constructorParameter); } - throw new NoSuchAlgorithmException("No constructor matching " + throw new NoSuchAlgorithmException("No public constructor matching " + argClass.getName() + " found in class " + className); } --- ./jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Apr 16 12:37:49 2014 +0400 @@ -221,6 +221,8 @@ if (vclass != fieldClass) throw new ClassCastException(); + if (vclass.isPrimitive()) + throw new IllegalArgumentException("Must be reference type"); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); --- ./jdk/src/share/classes/javax/crypto/JceSecurity.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/javax/crypto/JceSecurity.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -216,26 +216,28 @@ private static final Map codeBaseCacheRef = new WeakHashMap(); /* - * Retuns the CodeBase for the given class. + * Returns the CodeBase for the given class. */ static URL getCodeBase(final Class clazz) { - URL url = (URL)codeBaseCacheRef.get(clazz); - if (url == null) { - url = (URL)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ProtectionDomain pd = clazz.getProtectionDomain(); - if (pd != null) { - CodeSource cs = pd.getCodeSource(); - if (cs != null) { - return cs.getLocation(); + synchronized (codeBaseCacheRef) { + URL url = (URL)codeBaseCacheRef.get(clazz); + if (url == null) { + url = (URL)AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ProtectionDomain pd = clazz.getProtectionDomain(); + if (pd != null) { + CodeSource cs = pd.getCodeSource(); + if (cs != null) { + return cs.getLocation(); + } } + return NULL_URL; } - return NULL_URL; - } - }); - codeBaseCacheRef.put(clazz, url); + }); + codeBaseCacheRef.put(clazz, url); + } + return (url == NULL_URL) ? null : url; } - return (url == NULL_URL) ? null : url; } private static void setupJurisdictionPolicies() throws Exception { --- ./jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java Wed Apr 16 12:37:49 2014 +0400 @@ -718,7 +718,8 @@ * @return the Desktop folder. */ public File getHomeDirectory() { - return getRoots()[0]; + File[] roots = getRoots(); + return (roots.length == 0) ? null : roots[0]; } /** --- ./jdk/src/share/classes/sun/awt/AppContext.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/AppContext.java Wed Apr 16 12:37:49 2014 +0400 @@ -323,6 +323,20 @@ while (context == null) { threadGroup = threadGroup.getParent(); if (threadGroup == null) { + // We've got up to the root thread group and did not find an AppContext + // Try to get it from the security manager + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) { + ThreadGroup smThreadGroup = securityManager.getThreadGroup(); + if (smThreadGroup != null) { + /* + * If we get this far then it's likely that + * the ThreadGroup does not actually belong + * to the applet, so do not cache it. + */ + return threadGroup2appContext.get(smThreadGroup); + } + } return null; } context = threadGroup2appContext.get(threadGroup); --- ./jdk/src/share/classes/sun/awt/FontConfiguration.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/FontConfiguration.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, 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 @@ -867,7 +867,7 @@ return descriptors; } - private FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { + protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex]; --- ./jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -755,10 +755,22 @@ + scanlineStride); } - for (int i = 0; i < data.length; i++) { - if (scanlineStride > data[i].length) { - throw new RasterFormatException("Incorrect scanline stride: " - + scanlineStride); + if ((long)minX - sampleModelTranslateX < 0 || + (long)minY - sampleModelTranslateY < 0) { + + throw new RasterFormatException("Incorrect origin/translate: (" + + minX + ", " + minY + ") / (" + + sampleModelTranslateX + ", " + sampleModelTranslateY + ")"); + } + + + if (height > 1 || minY - sampleModelTranslateY > 0) { + // buffer should contain at least one scanline + for (int i = 0; i < data.length; i++) { + if (scanlineStride > data[i].length) { + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } } } --- ./jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -885,15 +885,31 @@ } } + if ((long)minX - sampleModelTranslateX < 0 || + (long)minY - sampleModelTranslateY < 0) { + + throw new RasterFormatException("Incorrect origin/translate: (" + + minX + ", " + minY + ") / (" + + sampleModelTranslateX + ", " + sampleModelTranslateY + ")"); + } + // we can be sure that width and height are greater than 0 if (scanlineStride < 0 || - scanlineStride > (Integer.MAX_VALUE / height) || - scanlineStride > data.length) + scanlineStride > (Integer.MAX_VALUE / height)) { // integer overflow throw new RasterFormatException("Incorrect scanline stride: " + scanlineStride); } + + if (height > 1 || minY - sampleModelTranslateY > 0) { + // buffer should contain at least one scanline + if (scanlineStride > data.length) { + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + } + int lastScanOffset = (height - 1) * scanlineStride; if (pixelStride < 0 || --- ./jdk/src/share/classes/sun/awt/image/BytePackedRaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/image/BytePackedRaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -1386,13 +1386,28 @@ throw new RasterFormatException("Invalid raster dimension"); } + if ((long)minX - sampleModelTranslateX < 0 || + (long)minY - sampleModelTranslateY < 0) { + + throw new RasterFormatException("Incorrect origin/translate: (" + + minX + ", " + minY + ") / (" + + sampleModelTranslateX + ", " + sampleModelTranslateY + ")"); + } + if (scanlineStride < 0 || - scanlineStride > (Integer.MAX_VALUE / height) || - scanlineStride > data.length) + scanlineStride > (Integer.MAX_VALUE / height)) { throw new RasterFormatException("Invalid scanline stride"); } + if (height > 1 || minY - sampleModelTranslateY > 0) { + // buffer should contain at least one scanline + if (scanlineStride > data.length) { + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + } + int lastbit = (dataBitOffset + (height-1) * scanlineStride * 8 + (width-1) * pixelBitStride --- ./jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -654,15 +654,31 @@ ") must be >= 0"); } + if ((long)minX - sampleModelTranslateX < 0 || + (long)minY - sampleModelTranslateY < 0) { + + throw new RasterFormatException("Incorrect origin/translate: (" + + minX + ", " + minY + ") / (" + + sampleModelTranslateX + ", " + sampleModelTranslateY + ")"); + } + // we can be sure that width and height are greater than 0 if (scanlineStride < 0 || - scanlineStride > (Integer.MAX_VALUE / height) || - scanlineStride > data.length) + scanlineStride > (Integer.MAX_VALUE / height)) { // integer overflow throw new RasterFormatException("Incorrect scanline stride: " + scanlineStride); } + + if (height > 1 || minY - sampleModelTranslateY > 0) { + // buffer should contain at least one scanline + if (scanlineStride > data.length) { + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + } + int lastScanOffset = (height - 1) * scanlineStride; if (pixelStride < 0 || --- ./jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -754,10 +754,21 @@ + scanlineStride); } - for (int i = 0; i < data.length; i++) { - if (scanlineStride > data[i].length) { - throw new RasterFormatException("Incorrect scanline stride: " - + scanlineStride); + if ((long)minX - sampleModelTranslateX < 0 || + (long)minY - sampleModelTranslateY < 0) { + + throw new RasterFormatException("Incorrect origin/translate: (" + + minX + ", " + minY + ") / (" + + sampleModelTranslateX + ", " + sampleModelTranslateY + ")"); + } + + if (height > 1 || minY - sampleModelTranslateY > 0) { + // buffer should contain at least one scanline + for (int i = 0; i < data.length; i++) { + if (scanlineStride > data[i].length) { + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } } } --- ./jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -819,15 +819,31 @@ } } + if ((long)minX - sampleModelTranslateX < 0 || + (long)minY - sampleModelTranslateY < 0) { + + throw new RasterFormatException("Incorrect origin/translate: (" + + minX + ", " + minY + ") / (" + + sampleModelTranslateX + ", " + sampleModelTranslateY + ")"); + } + // we can be sure that width and height are greater than 0 if (scanlineStride < 0 || - scanlineStride > (Integer.MAX_VALUE / height) || - scanlineStride > data.length) + scanlineStride > (Integer.MAX_VALUE / height)) { // integer overflow throw new RasterFormatException("Incorrect scanline stride: " + scanlineStride); } + + if (height > 1 || minY - sampleModelTranslateY > 0) { + // buffer should contain at least one scanline + if (scanlineStride > data.length) { + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + } + int lastScanOffset = (height - 1) * scanlineStride; if (pixelStride < 0 || --- ./jdk/src/share/classes/sun/invoke/util/VerifyAccess.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/invoke/util/VerifyAccess.java Wed Apr 16 12:37:49 2014 +0400 @@ -89,35 +89,28 @@ if (allowedModes == 0) return false; assert((allowedModes & PUBLIC) != 0 && (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0); - // Usually refc and defc are the same, but if they differ, verify them both. - if (refc != defc) { - if (!isClassAccessible(refc, lookupClass, allowedModes)) { - // Note that defc is verified in the switch below. - return false; - } - if ((mods & (ALL_ACCESS_MODES|STATIC)) == (PROTECTED|STATIC) && - (allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0) { - // Apply the special rules for refc here. - if (!isRelatedClass(refc, lookupClass)) - return isSamePackage(defc, lookupClass); - // If refc == defc, the call to isPublicSuperClass will do - // the whole job, since in that case refc (as defc) will be - // a superclass of the lookup class. - } + // The symbolic reference class (refc) must always be fully verified. + if (!isClassAccessible(refc, lookupClass, allowedModes)) { + return false; } + // Usually refc and defc are the same, but verify defc also in case they differ. if (defc == lookupClass && (allowedModes & PRIVATE) != 0) return true; // easy check; all self-access is OK switch (mods & ALL_ACCESS_MODES) { case PUBLIC: - if (refc != defc) return true; // already checked above - return isClassAccessible(refc, lookupClass, allowedModes); + return true; // already checked above case PROTECTED: if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)) return true; + if ((allowedModes & PROTECTED) == 0) + return false; + if ((mods & STATIC) != 0 && + !isRelatedClass(refc, lookupClass)) + return false; if ((allowedModes & PROTECTED) != 0 && - isPublicSuperClass(defc, lookupClass)) + isSuperClass(defc, lookupClass)) return true; return false; case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. @@ -139,8 +132,8 @@ lookupClass.isAssignableFrom(refc)); } - static boolean isPublicSuperClass(Class defc, Class lookupClass) { - return isPublic(defc.getModifiers()) && defc.isAssignableFrom(lookupClass); + static boolean isSuperClass(Class defc, Class lookupClass) { + return defc.isAssignableFrom(lookupClass); } /** --- ./jdk/src/share/classes/sun/misc/JavaLangAccess.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/misc/JavaLangAccess.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, 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 @@ -35,10 +35,10 @@ ConstantPool getConstantPool(Class klass); /** - * Set the AnnotationType instance corresponding to this class. + * Compare-And-Swap the AnnotationType instance corresponding to this class. * (This method only applies to annotation types.) */ - void setAnnotationType(Class klass, AnnotationType annotationType); + boolean casAnnotationType(Class klass, AnnotationType oldType, AnnotationType newType); /** * Get the AnnotationType instance corresponding to this class. @@ -47,6 +47,12 @@ AnnotationType getAnnotationType(Class klass); /** + * Get the array of bytes that is the class-file representation + * of this Class' annotations. + */ + byte[] getRawClassAnnotations(Class klass); + + /** * Returns the elements of an enum class or null if the * Class object does not represent an enum type; * the result is uncloned, cached, and shared by all callers. --- ./jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -67,7 +67,35 @@ return Collections.emptyMap(); try { - return parseAnnotations2(rawAnnotations, constPool, container); + return parseAnnotations2(rawAnnotations, constPool, container, null); + } catch(BufferUnderflowException e) { + throw new AnnotationFormatError("Unexpected end of annotations."); + } catch(IllegalArgumentException e) { + // Type mismatch in constant pool + throw new AnnotationFormatError(e); + } + } + + /** + * Like {@link #parseAnnotations(byte[], sun.reflect.ConstantPool, Class)} + * with an additional parameter {@code selectAnnotationClasses} which selects the + * annotation types to parse (other than selected are quickly skipped).

+ * This method is only used to parse select meta annotations in the construction + * phase of {@link AnnotationType} instances to prevent infinite recursion. + * + * @param selectAnnotationClasses an array of annotation types to select when parsing + */ + @SafeVarargs + static Map, Annotation> parseSelectAnnotations( + byte[] rawAnnotations, + ConstantPool constPool, + Class container, + Class ... selectAnnotationClasses) { + if (rawAnnotations == null) + return Collections.emptyMap(); + + try { + return parseAnnotations2(rawAnnotations, constPool, container, selectAnnotationClasses); } catch(BufferUnderflowException e) { throw new AnnotationFormatError("Unexpected end of annotations."); } catch(IllegalArgumentException e) { @@ -79,22 +107,23 @@ private static Map, Annotation> parseAnnotations2( byte[] rawAnnotations, ConstantPool constPool, - Class container) { + Class container, + Class[] selectAnnotationClasses) { Map, Annotation> result = new LinkedHashMap, Annotation>(); ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); int numAnnotations = buf.getShort() & 0xFFFF; for (int i = 0; i < numAnnotations; i++) { - Annotation a = parseAnnotation(buf, constPool, container, false); + Annotation a = parseAnnotation2(buf, constPool, container, false, selectAnnotationClasses); if (a != null) { Class klass = a.annotationType(); - AnnotationType type = AnnotationType.getInstance(klass); - if (type.retention() == RetentionPolicy.RUNTIME) - if (result.put(klass, a) != null) + if (AnnotationType.getInstance(klass).retention() == RetentionPolicy.RUNTIME && + result.put(klass, a) != null) { throw new AnnotationFormatError( "Duplicate annotation for class: "+klass+": " + a); } } + } return result; } @@ -191,6 +220,15 @@ ConstantPool constPool, Class container, boolean exceptionOnMissingAnnotationClass) { + return parseAnnotation2(buf, constPool, container, exceptionOnMissingAnnotationClass, null); + } + + @SuppressWarnings("unchecked") + private static Annotation parseAnnotation2(ByteBuffer buf, + ConstantPool constPool, + Class container, + boolean exceptionOnMissingAnnotationClass, + Class[] selectAnnotationClasses) { int typeIndex = buf.getShort() & 0xFFFF; Class annotationClass = null; String sig = "[unknown]"; @@ -216,6 +254,10 @@ skipAnnotation(buf, false); return null; } + if (selectAnnotationClasses != null && !contains(selectAnnotationClasses, annotationClass)) { + skipAnnotation(buf, false); + return null; + } AnnotationType type = null; try { type = AnnotationType.getInstance(annotationClass); @@ -791,6 +833,17 @@ skipMemberValue(buf); } + /** + * Searches for given {@code element} in given {@code array} by identity. + * Returns {@code true} if found {@code false} if not. + */ + private static boolean contains(Object[] array, Object element) { + for (Object e : array) + if (e == element) + return true; + return false; + } + /* * This method converts the annotation map returned by the parseAnnotations() * method to an array. It is called by Field.getDeclaredAnnotations(), --- ./jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, 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,6 +25,8 @@ package sun.reflect.annotation; +import sun.misc.JavaLangAccess; + import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; @@ -45,29 +47,28 @@ * types. This matches the return value that must be used for a * dynamic proxy, allowing for a simple isInstance test. */ - private final Map> memberTypes = new HashMap>(); + private final Map> memberTypes; /** * Member name -> default value mapping. */ - private final Map memberDefaults = - new HashMap(); + private final Map memberDefaults; /** - * Member name -> Method object mapping. This (and its assoicated + * Member name -> Method object mapping. This (and its associated * accessor) are used only to generate AnnotationTypeMismatchExceptions. */ - private final Map members = new HashMap(); + private final Map members; /** * The retention policy for this annotation type. */ - private RetentionPolicy retention = RetentionPolicy.RUNTIME;; + private final RetentionPolicy retention; /** * Whether this annotation type is inherited. */ - private boolean inherited = false; + private final boolean inherited; /** * Returns an AnnotationType instance for the specified annotation type. @@ -75,13 +76,20 @@ * @throw IllegalArgumentException if the specified class object for * does not represent a valid annotation type */ - public static synchronized AnnotationType getInstance( + public static AnnotationType getInstance( Class annotationClass) { - AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess(). - getAnnotationType(annotationClass); - if (result == null) - result = new AnnotationType((Class) annotationClass); + JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess(); + AnnotationType result = jla.getAnnotationType(annotationClass); // volatile read + if (result == null) { + result = new AnnotationType(annotationClass); + // try to CAS the AnnotationType: null -> result + if (!jla.casAnnotationType(annotationClass, null, result)) { + // somebody was quicker -> read it's result + result = jla.getAnnotationType(annotationClass); + assert result != null; + } + } return result; } @@ -105,6 +113,9 @@ } }); + memberTypes = new HashMap>(methods.length+1, 1.0f); + memberDefaults = new HashMap(0); + members = new HashMap(methods.length+1, 1.0f); for (Method method : methods) { if (method.getParameterTypes().length != 0) @@ -117,20 +128,27 @@ Object defaultValue = method.getDefaultValue(); if (defaultValue != null) memberDefaults.put(name, defaultValue); - - members.put(name, method); } - sun.misc.SharedSecrets.getJavaLangAccess(). - setAnnotationType(annotationClass, this); - // Initialize retention, & inherited fields. Special treatment // of the corresponding annotation types breaks infinite recursion. if (annotationClass != Retention.class && annotationClass != Inherited.class) { - Retention ret = annotationClass.getAnnotation(Retention.class); + JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess(); + Map, Annotation> metaAnnotations = + AnnotationParser.parseSelectAnnotations( + jla.getRawClassAnnotations(annotationClass), + jla.getConstantPool(annotationClass), + annotationClass, + Retention.class, Inherited.class + ); + Retention ret = (Retention) metaAnnotations.get(Retention.class); retention = (ret == null ? RetentionPolicy.CLASS : ret.value()); - inherited = annotationClass.isAnnotationPresent(Inherited.class); + inherited = metaAnnotations.containsKey(Inherited.class); + } + else { + retention = RetentionPolicy.RUNTIME; + inherited = false; } } @@ -205,11 +223,10 @@ * For debugging. */ public String toString() { - StringBuffer s = new StringBuffer("Annotation Type:" + "\n"); - s.append(" Member types: " + memberTypes + "\n"); - s.append(" Member defaults: " + memberDefaults + "\n"); - s.append(" Retention policy: " + retention + "\n"); - s.append(" Inherited: " + inherited); - return s.toString(); + return "Annotation Type:\n" + + " Member types: " + memberTypes + "\n" + + " Member defaults: " + memberDefaults + "\n" + + " Retention policy: " + retention + "\n" + + " Inherited: " + inherited; } } --- ./jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -123,19 +123,19 @@ try { - long[] handles = generateECKeyPair(keySize, encodedParams, seed); + Object[] keyBytes = generateECKeyPair(keySize, encodedParams, seed); // The 'params' object supplied above is equivalent to the native // one so there is no need to fetch it. - // handles[0] points to the native private key - BigInteger s = new BigInteger(1, getEncodedBytes(handles[0])); + // keyBytes[0] is the encoding of the native private key + BigInteger s = new BigInteger(1, (byte[])keyBytes[0]); PrivateKey privateKey = new ECPrivateKeyImpl(s, (ECParameterSpec)params); - // handles[1] points to the native public key - ECPoint w = ECParameters.decodePoint(getEncodedBytes(handles[1]), + // keyBytes[1] is the encoding of the native public key + ECPoint w = ECParameters.decodePoint((byte[])keyBytes[1], ((ECParameterSpec)params).getCurve()); PublicKey publicKey = new ECPublicKeyImpl(w, (ECParameterSpec)params); @@ -160,14 +160,9 @@ } /* - * Generates the keypair and returns a 2-element array of handles. - * The first handle points to the private key, the second to the public key. + * Generates the keypair and returns a 2-element array of encoding bytes. + * The first one is for the private key, the second for the public key. */ - private static native long[] generateECKeyPair(int keySize, + private static native Object[] generateECKeyPair(int keySize, byte[] encodedParams, byte[] seed) throws GeneralSecurityException; - - /* - * Extracts the encoded key data using the supplied handle. - */ - private static native byte[] getEncodedBytes(long handle); } --- ./jdk/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Wed Apr 16 12:37:49 2014 +0400 @@ -26,11 +26,11 @@ package sun.security.internal.spec; import java.security.spec.AlgorithmParameterSpec; +import java.security.AccessController; +import java.security.PrivilegedAction; /** - * Parameters for SSL/TLS RSA Premaster secret generation. - * This class is used by SSL/TLS client to initialize KeyGenerators of the - * type "TlsRsaPremasterSecret". + * Parameters for SSL/TLS RSA premaster secret. * *

Instances of this class are immutable. * @@ -43,90 +43,108 @@ public class TlsRsaPremasterSecretParameterSpec implements AlgorithmParameterSpec { - private final int majorVersion; - private final int minorVersion; - private final byte[] encodedSecret; + /* + * The TLS spec says that the version in the RSA premaster secret must + * be the maximum version supported by the client (i.e. the version it + * requested in its client hello version). However, we (and other + * implementations) used to send the active negotiated version. The + * system property below allows to toggle the behavior. + */ + private final static String PROP_NAME = + "com.sun.net.ssl.rsaPreMasterSecretFix"; + + /* + * Default is "false" (old behavior) for compatibility reasons in + * SSLv3/TLSv1. Later protocols (TLSv1.1+) do not use this property. + */ + private final static boolean rsaPreMasterSecretFix = + AccessController.doPrivileged(new PrivilegedAction() { + public Boolean run() { + String value = System.getProperty(PROP_NAME); + if (value != null && value.equalsIgnoreCase("true")) { + return Boolean.TRUE; + } + + return Boolean.FALSE; + } + }); + + private final int clientVersion; + private final int serverVersion; /** * Constructs a new TlsRsaPremasterSecretParameterSpec. - *

- * The version numbers will be placed inside the premaster secret to - * detect version rollbacks attacks as described in the TLS specification. - * Note that they do not indicate the protocol version negotiated for - * the handshake. * - * @param majorVersion the major number of the protocol version - * @param minorVersion the minor number of the protocol version + * @param clientVersion the version of the TLS protocol by which the + * client wishes to communicate during this session + * @param serverVersion the negotiated version of the TLS protocol which + * contains the lower of that suggested by the client in the client + * hello and the highest supported by the server. * - * @throws IllegalArgumentException if minorVersion or majorVersion are - * negative or larger than 255 + * @throws IllegalArgumentException if clientVersion or serverVersion are + * negative or larger than (2^16 - 1) */ - public TlsRsaPremasterSecretParameterSpec(int majorVersion, - int minorVersion) { - this.majorVersion = - TlsMasterSecretParameterSpec.checkVersion(majorVersion); - this.minorVersion = - TlsMasterSecretParameterSpec.checkVersion(minorVersion); - this.encodedSecret = null; + public TlsRsaPremasterSecretParameterSpec( + int clientVersion, int serverVersion) { + + this.clientVersion = checkVersion(clientVersion); + this.serverVersion = checkVersion(serverVersion); } /** - * Constructs a new TlsRsaPremasterSecretParameterSpec. - *

- * The version numbers will be placed inside the premaster secret to - * detect version rollbacks attacks as described in the TLS specification. - * Note that they do not indicate the protocol version negotiated for - * the handshake. - *

- * Usually, the encoded secret key is a random number that acts as - * dummy pre_master_secret to avoid vulnerabilities described by - * section 7.4.7.1, RFC 5246. + * Returns the version of the TLS protocol by which the client wishes to + * communicate during this session. * - * @param majorVersion the major number of the protocol version - * @param minorVersion the minor number of the protocol version - * @param encodedSecret the encoded secret key - * - * @throws IllegalArgumentException if minorVersion or majorVersion are - * negative or larger than 255, or encodedSecret is not exactly 48 bytes. + * @return the version of the TLS protocol in ClientHello message */ - public TlsRsaPremasterSecretParameterSpec(int majorVersion, - int minorVersion, byte[] encodedSecret) { - this.majorVersion = - TlsMasterSecretParameterSpec.checkVersion(majorVersion); - this.minorVersion = - TlsMasterSecretParameterSpec.checkVersion(minorVersion); - - if (encodedSecret == null || encodedSecret.length != 48) { - throw new IllegalArgumentException( - "Encoded secret is not exactly 48 bytes"); - } - this.encodedSecret = encodedSecret.clone(); + public int getClientVersion() { + return clientVersion; } /** - * Returns the major version. + * Returns the negotiated version of the TLS protocol which contains the + * lower of that suggested by the client in the client hello and the + * highest supported by the server. * - * @return the major version. + * @return the negotiated version of the TLS protocol in ServerHello message */ - public int getMajorVersion() { - return majorVersion; + public int getServerVersion() { + return serverVersion; } /** - * Returns the minor version. + * Returns the major version used in RSA premaster secret. * - * @return the minor version. + * @return the major version used in RSA premaster secret. */ - public int getMinorVersion() { - return minorVersion; + public int getMajorVersion() { + if (rsaPreMasterSecretFix || clientVersion >= 0x0302) { + // 0x0302: TLSv1.1 + return (clientVersion >>> 8) & 0xFF; + } + + return (serverVersion >>> 8) & 0xFF; } /** - * Returns the encoded secret. + * Returns the minor version used in RSA premaster secret. * - * @return the encoded secret, may be null if no encoded secret. + * @return the minor version used in RSA premaster secret. */ - public byte[] getEncodedSecret() { - return encodedSecret == null ? null : encodedSecret.clone(); + public int getMinorVersion() { + if (rsaPreMasterSecretFix || clientVersion >= 0x0302) { + // 0x0302: TLSv1.1 + return clientVersion & 0xFF; + } + + return serverVersion & 0xFF; + } + + private int checkVersion(int version) { + if ((version < 0) || (version > 0xFFFF)) { + throw new IllegalArgumentException( + "Version must be between 0 and 65,535"); + } + return version; } } --- ./jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Wed Apr 16 12:37:49 2014 +0400 @@ -37,6 +37,8 @@ import static sun.security.pkcs11.TemplateManager.*; import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; +import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; +import sun.security.util.KeyUtil; /** * RSA Cipher implementation class. We currently only support @@ -102,6 +104,12 @@ // maximum output size. this is the length of the key private int outputSize; + // cipher parameter for TLS RSA premaster secret + private AlgorithmParameterSpec spec = null; + + // the source of randomness + private SecureRandom random; + P11RSACipher(Token token, String algorithm, long mechanism) throws PKCS11Exception { super(); @@ -165,8 +173,12 @@ AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { if (params != null) { - throw new InvalidAlgorithmParameterException - ("Parameters not supported"); + if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new InvalidAlgorithmParameterException( + "Parameters not supported"); + } + spec = params; + this.random = random; // for TLS RSA premaster secret } implInit(opmode, key); } @@ -176,8 +188,8 @@ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { if (params != null) { - throw new InvalidAlgorithmParameterException - ("Parameters not supported"); + throw new InvalidAlgorithmParameterException( + "Parameters not supported"); } implInit(opmode, key); } @@ -452,21 +464,101 @@ protected Key engineUnwrap(byte[] wrappedKey, String algorithm, int type) throws InvalidKeyException, NoSuchAlgorithmException { - // XXX implement unwrap using C_Unwrap() for all keys - implInit(Cipher.DECRYPT_MODE, p11Key); - if (wrappedKey.length > maxInputSize) { - throw new InvalidKeyException("Key is too long for unwrapping"); + boolean isTlsRsaPremasterSecret = + algorithm.equals("TlsRsaPremasterSecret"); + Exception failover = null; + + SecureRandom secureRandom = random; + if (secureRandom == null && isTlsRsaPremasterSecret) { + secureRandom = new SecureRandom(); } - implUpdate(wrappedKey, 0, wrappedKey.length); - try { - byte[] encoded = doFinal(); + + // Should C_Unwrap be preferred for non-TLS RSA premaster secret? + if (token.supportsRawSecretKeyImport()) { + // XXX implement unwrap using C_Unwrap() for all keys + implInit(Cipher.DECRYPT_MODE, p11Key); + if (wrappedKey.length > maxInputSize) { + throw new InvalidKeyException("Key is too long for unwrapping"); + } + + byte[] encoded = null; + implUpdate(wrappedKey, 0, wrappedKey.length); + try { + encoded = doFinal(); + } catch (BadPaddingException e) { + if (isTlsRsaPremasterSecret) { + failover = e; + } else { + throw new InvalidKeyException("Unwrapping failed", e); + } + } catch (IllegalBlockSizeException e) { + // should not occur, handled with length check above + throw new InvalidKeyException("Unwrapping failed", e); + } + + if (isTlsRsaPremasterSecret) { + if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new IllegalStateException( + "No TlsRsaPremasterSecretParameterSpec specified"); + } + + // polish the TLS premaster secret + TlsRsaPremasterSecretParameterSpec psps = + (TlsRsaPremasterSecretParameterSpec)spec; + encoded = KeyUtil.checkTlsPreMasterSecretKey( + psps.getClientVersion(), psps.getServerVersion(), + secureRandom, encoded, (failover != null)); + } + return ConstructKeys.constructKey(encoded, algorithm, type); - } catch (BadPaddingException e) { - // should not occur - throw new InvalidKeyException("Unwrapping failed", e); - } catch (IllegalBlockSizeException e) { - // should not occur, handled with length check above - throw new InvalidKeyException("Unwrapping failed", e); + } else { + Session s = null; + SecretKey secretKey = null; + try { + try { + s = token.getObjSession(); + long keyType = CKK_GENERIC_SECRET; + CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY), + new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType), + }; + attributes = token.getAttributes( + O_IMPORT, CKO_SECRET_KEY, keyType, attributes); + long keyID = token.p11.C_UnwrapKey(s.id(), + new CK_MECHANISM(mechanism), p11Key.keyID, + wrappedKey, attributes); + secretKey = P11Key.secretKey(s, keyID, + algorithm, 48 << 3, attributes); + } catch (PKCS11Exception e) { + if (isTlsRsaPremasterSecret) { + failover = e; + } else { + throw new InvalidKeyException("unwrap() failed", e); + } + } + + if (isTlsRsaPremasterSecret) { + byte[] replacer = new byte[48]; + if (failover == null) { + // Does smart compiler dispose this operation? + secureRandom.nextBytes(replacer); + } + + TlsRsaPremasterSecretParameterSpec psps = + (TlsRsaPremasterSecretParameterSpec)spec; + + // Please use the tricky failover and replacer byte array + // as the parameters so that smart compiler won't dispose + // the unused variable . + secretKey = polishPreMasterSecretKey(token, s, + failover, replacer, secretKey, + psps.getClientVersion(), psps.getServerVersion()); + } + + return secretKey; + } finally { + token.releaseSession(s); + } } } @@ -475,6 +567,34 @@ int n = P11KeyFactory.convertKey(token, key, algorithm).length(); return n; } + + private static SecretKey polishPreMasterSecretKey( + Token token, Session session, + Exception failover, byte[] replacer, SecretKey secretKey, + int clientVersion, int serverVersion) { + + if (failover != null) { + CK_VERSION version = new CK_VERSION( + (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF); + try { + CK_ATTRIBUTE[] attributes = token.getAttributes( + O_GENERATE, CKO_SECRET_KEY, + CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); + long keyID = token.p11.C_GenerateKey(session.id(), + // new CK_MECHANISM(CKM_TLS_PRE_MASTER_KEY_GEN, version), + new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version), + attributes); + return P11Key.secretKey(session, + keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); + } catch (PKCS11Exception e) { + throw new ProviderException( + "Could not generate premaster secret", e); + } + } + + return secretKey; + } + } final class ConstructKeys { --- ./jdk/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Wed Apr 16 12:37:49 2014 +0400 @@ -73,7 +73,7 @@ protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { - if (params instanceof TlsRsaPremasterSecretParameterSpec == false) { + if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } this.spec = (TlsRsaPremasterSecretParameterSpec)params; @@ -83,38 +83,32 @@ throw new InvalidParameterException(MSG); } + // Only can be used in client side to generate TLS RSA premaster secret. protected SecretKey engineGenerateKey() { if (spec == null) { throw new IllegalStateException ("TlsRsaPremasterSecretGenerator must be initialized"); } - byte[] b = spec.getEncodedSecret(); - if (b == null) { - CK_VERSION version = new CK_VERSION( + CK_VERSION version = new CK_VERSION( spec.getMajorVersion(), spec.getMinorVersion()); - Session session = null; - try { - session = token.getObjSession(); - CK_ATTRIBUTE[] attributes = token.getAttributes( - O_GENERATE, CKO_SECRET_KEY, - CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); - long keyID = token.p11.C_GenerateKey(session.id(), - new CK_MECHANISM(mechanism, version), attributes); - SecretKey key = P11Key.secretKey(session, - keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); - return key; - } catch (PKCS11Exception e) { - throw new ProviderException( - "Could not generate premaster secret", e); - } finally { - token.releaseSession(session); - } + Session session = null; + try { + session = token.getObjSession(); + CK_ATTRIBUTE[] attributes = token.getAttributes( + O_GENERATE, CKO_SECRET_KEY, + CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); + long keyID = token.p11.C_GenerateKey(session.id(), + new CK_MECHANISM(mechanism, version), attributes); + SecretKey key = P11Key.secretKey(session, + keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); + return key; + } catch (PKCS11Exception e) { + throw new ProviderException( + "Could not generate premaster secret", e); + } finally { + token.releaseSession(session); } - - // Won't worry, the TlsRsaPremasterSecret will be soon converted to - // TlsMasterSecret. - return new SecretKeySpec(b, "TlsRsaPremasterSecret"); } } --- ./jdk/src/share/classes/sun/security/pkcs11/Token.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/pkcs11/Token.java Wed Apr 16 12:37:49 2014 +0400 @@ -35,6 +35,7 @@ import sun.security.jca.JCAUtil; import sun.security.pkcs11.wrapper.*; +import static sun.security.pkcs11.TemplateManager.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; /** @@ -121,6 +122,9 @@ private final static CK_MECHANISM_INFO INVALID_MECH = new CK_MECHANISM_INFO(0, 0, 0); + // flag indicating whether the token supports raw secret key material import + private Boolean supportsRawSecretKeyImport; + Token(SunPKCS11 provider) throws PKCS11Exception { this.provider = provider; this.removable = provider.removable; @@ -159,6 +163,36 @@ return writeProtected; } + // return whether the token supports raw secret key material import + boolean supportsRawSecretKeyImport() { + if (supportsRawSecretKeyImport == null) { + SecureRandom random = JCAUtil.getSecureRandom(); + byte[] encoded = new byte[48]; + random.nextBytes(encoded); + + CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[3]; + attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY); + attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET); + attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded); + + Session session = null; + try { + attributes = getAttributes(O_IMPORT, + CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes); + session = getObjSession(); + long keyID = p11.C_CreateObject(session.id(), attributes); + + supportsRawSecretKeyImport = Boolean.TRUE; + } catch (PKCS11Exception e) { + supportsRawSecretKeyImport = Boolean.FALSE; + } finally { + releaseSession(session); + } + } + + return supportsRawSecretKeyImport; + } + // return whether we are logged in // uses cached result if current. session is optional and may be null boolean isLoggedIn(Session session) throws PKCS11Exception { --- ./jdk/src/share/classes/sun/security/rsa/RSACore.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/rsa/RSACore.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -50,6 +50,15 @@ */ public final class RSACore { + // globally enable/disable use of blinding + private final static boolean ENABLE_BLINDING = true; + + // cache for blinding parameters. Map + // use a weak hashmap so that cached values are automatically cleared + // when the modulus is GC'ed + private final static Map + blindingCache = new WeakHashMap<>(); + private RSACore() { // empty } @@ -100,12 +109,12 @@ if (key instanceof RSAPrivateCrtKey) { return crtCrypt(msg, (RSAPrivateCrtKey)key); } else { - return crypt(msg, key.getModulus(), key.getPrivateExponent()); + return priCrypt(msg, key.getModulus(), key.getPrivateExponent()); } } /** - * RSA public key ops and non-CRT private key ops. Simple modPow(). + * RSA public key ops. Simple modPow(). */ private static byte[] crypt(byte[] msg, BigInteger n, BigInteger exp) throws BadPaddingException { @@ -115,22 +124,29 @@ } /** + * RSA non-CRT private key operations. + */ + private static byte[] priCrypt(byte[] msg, BigInteger n, BigInteger exp) + throws BadPaddingException { + + BigInteger c = parseMsg(msg, n); + BlindingRandomPair brp = null; + BigInteger m; + if (ENABLE_BLINDING) { + brp = getBlindingRandomPair(null, exp, n); + c = c.multiply(brp.u).mod(n); + m = c.modPow(exp, n); + m = m.multiply(brp.v).mod(n); + } else { + m = c.modPow(exp, n); + } + + return toByteArray(m, getByteLength(n)); + } + + /** * RSA private key operations with CRT. Algorithm and variable naming * are taken from PKCS#1 v2.1, section 5.1.2. - * - * The only difference is the addition of blinding to twart timing attacks. - * This is described in the RSA Bulletin#2 (Jan 96) among other places. - * This means instead of implementing RSA as - * m = c ^ d mod n (or RSA in CRT variant) - * we do - * r = random(0, n-1) - * c' = c * r^e mod n - * m' = c' ^ d mod n (or RSA in CRT variant) - * m = m' * r^-1 mod n (where r^-1 is the modular inverse of r mod n) - * This works because r^(e*d) * r^-1 = r * r^-1 = 1 (all mod n) - * - * We do not generate new blinding parameters for each operation but reuse - * them BLINDING_MAX_REUSE times (see definition below). */ private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key) throws BadPaddingException { @@ -141,13 +157,13 @@ BigInteger dP = key.getPrimeExponentP(); BigInteger dQ = key.getPrimeExponentQ(); BigInteger qInv = key.getCrtCoefficient(); + BigInteger e = key.getPublicExponent(); + BigInteger d = key.getPrivateExponent(); - BlindingParameters params; + BlindingRandomPair brp; if (ENABLE_BLINDING) { - params = getBlindingParameters(key); - c = c.multiply(params.re).mod(n); - } else { - params = null; + brp = getBlindingRandomPair(e, d, n); + c = c.multiply(brp.u).mod(n); } // m1 = c ^ dP mod p @@ -165,8 +181,8 @@ // m = m2 + q * h BigInteger m = h.multiply(q).add(m2); - if (params != null) { - m = m.multiply(params.rInv).mod(n); + if (ENABLE_BLINDING) { + m = m.multiply(brp.v).mod(n); } return toByteArray(m, getByteLength(n)); @@ -208,82 +224,221 @@ return t; } - // globally enable/disable use of blinding - private final static boolean ENABLE_BLINDING = true; + /** + * Parameters (u,v) for RSA Blinding. This is described in the RSA + * Bulletin#2 (Jan 96) and other places: + * + * ftp://ftp.rsa.com/pub/pdfs/bull-2.pdf + * + * The standard RSA Blinding decryption requires the public key exponent + * (e) and modulus (n), and converts ciphertext (c) to plaintext (p). + * + * Before the modular exponentiation operation, the input message should + * be multiplied by (u (mod n)), and afterward the result is corrected + * by multiplying with (v (mod n)). The system should reject messages + * equal to (0 (mod n)). That is: + * + * 1. Generate r between 0 and n-1, relatively prime to n. + * 2. Compute x = (c*u) mod n + * 3. Compute y = (x^d) mod n + * 4. Compute p = (y*v) mod n + * + * The Java APIs allows for either standard RSAPrivateKey or + * RSAPrivateCrtKey RSA keys. + * + * If the public exponent is available to us (e.g. RSAPrivateCrtKey), + * choose a random r, then let (u, v): + * + * u = r ^ e mod n + * v = r ^ (-1) mod n + * + * The proof follows: + * + * p = (((c * u) ^ d mod n) * v) mod n + * = ((c ^ d) * (u ^ d) * v) mod n + * = ((c ^ d) * (r ^ e) ^ d) * (r ^ (-1))) mod n + * = ((c ^ d) * (r ^ (e * d)) * (r ^ (-1))) mod n + * = ((c ^ d) * (r ^ 1) * (r ^ (-1))) mod n (see below) + * = (c ^ d) mod n + * + * because in RSA cryptosystem, d is the multiplicative inverse of e: + * + * (r^(e * d)) mod n + * = (r ^ 1) mod n + * = r mod n + * + * However, if the public exponent is not available (e.g. RSAPrivateKey), + * we mitigate the timing issue by using a similar random number blinding + * approach using the private key: + * + * u = r + * v = ((r ^ (-1)) ^ d) mod n + * + * This returns the same plaintext because: + * + * p = (((c * u) ^ d mod n) * v) mod n + * = ((c ^ d) * (u ^ d) * v) mod n + * = ((c ^ d) * (u ^ d) * ((u ^ (-1)) ^d)) mod n + * = (c ^ d) mod n + * + * Computing inverses mod n and random number generation is slow, so + * it is often not practical to generate a new random (u, v) pair for + * each new exponentiation. The calculation of parameters might even be + * subject to timing attacks. However, (u, v) pairs should not be + * reused since they themselves might be compromised by timing attacks, + * leaving the private exponent vulnerable. An efficient solution to + * this problem is update u and v before each modular exponentiation + * step by computing: + * + * u = u ^ 2 + * v = v ^ 2 + * + * The total performance cost is small. + */ + private final static class BlindingRandomPair { + final BigInteger u; + final BigInteger v; - // maximum number of times that we will use a set of blinding parameters - // value suggested by Paul Kocher (quoted by NSS) - private final static int BLINDING_MAX_REUSE = 50; - - // cache for blinding parameters. Map - // use a weak hashmap so that cached values are automatically cleared - // when the modulus is GC'ed - private final static Map blindingCache = - new WeakHashMap<>(); + BlindingRandomPair(BigInteger u, BigInteger v) { + this.u = u; + this.v = v; + } + } /** * Set of blinding parameters for a given RSA key. * * The RSA modulus is usually unique, so we index by modulus in - * blindingCache. However, to protect against the unlikely case of two - * keys sharing the same modulus, we also store the public exponent. - * This means we cannot cache blinding parameters for multiple keys that - * share the same modulus, but since sharing moduli is fundamentally broken - * an insecure, this does not matter. + * {@code blindingCache}. However, to protect against the unlikely + * case of two keys sharing the same modulus, we also store the public + * or the private exponent. This means we cannot cache blinding + * parameters for multiple keys that share the same modulus, but + * since sharing moduli is fundamentally broken and insecure, this + * does not matter. */ - private static final class BlindingParameters { - // e (RSA public exponent) - final BigInteger e; - // r ^ e mod n - final BigInteger re; - // inverse of r mod n - final BigInteger rInv; - // how many more times this parameter object can be used - private volatile int remainingUses; - BlindingParameters(BigInteger e, BigInteger re, BigInteger rInv) { + private final static class BlindingParameters { + private final static BigInteger BIG_TWO = BigInteger.valueOf(2L); + + // RSA public exponent + private final BigInteger e; + + // hash code of RSA private exponent + private final BigInteger d; + + // r ^ e mod n (CRT), or r mod n (Non-CRT) + private BigInteger u; + + // r ^ (-1) mod n (CRT) , or ((r ^ (-1)) ^ d) mod n (Non-CRT) + private BigInteger v; + + // e: the public exponent + // d: the private exponent + // n: the modulus + BlindingParameters(BigInteger e, BigInteger d, BigInteger n) { + this.u = null; + this.v = null; this.e = e; - this.re = re; - this.rInv = rInv; - // initialize remaining uses, subtract current use now - remainingUses = BLINDING_MAX_REUSE - 1; + this.d = d; + + int len = n.bitLength(); + SecureRandom random = JCAUtil.getSecureRandom(); + u = new BigInteger(len, random).mod(n); + // Although the possibility is very much limited that u is zero + // or is not relatively prime to n, we still want to be careful + // about the special value. + // + // Secure random generation is expensive, try to use BigInteger.ONE + // this time if this new generated random number is zero or is not + // relatively prime to n. Next time, new generated secure random + // number will be used instead. + if (u.equals(BigInteger.ZERO)) { + u = BigInteger.ONE; // use 1 this time + } + + try { + // The call to BigInteger.modInverse() checks that u is + // relatively prime to n. Otherwise, ArithmeticException is + // thrown. + v = u.modInverse(n); + } catch (ArithmeticException ae) { + // if u is not relatively prime to n, use 1 this time + u = BigInteger.ONE; + v = BigInteger.ONE; + } + + if (e != null) { + u = u.modPow(e, n); // e: the public exponent + // u: random ^ e + // v: random ^ (-1) + } else { + v = v.modPow(d, n); // d: the private exponent + // u: random + // v: random ^ (-d) + } } - boolean valid(BigInteger e) { - int k = remainingUses--; - return (k > 0) && this.e.equals(e); + + // return null if need to reset the parameters + BlindingRandomPair getBlindingRandomPair( + BigInteger e, BigInteger d, BigInteger n) { + + if ((this.e != null && this.e.equals(e)) || + (this.d != null && this.d.equals(d))) { + + BlindingRandomPair brp = null; + synchronized (this) { + if (!u.equals(BigInteger.ZERO) && + !v.equals(BigInteger.ZERO)) { + + brp = new BlindingRandomPair(u, v); + if (u.compareTo(BigInteger.ONE) <= 0 || + v.compareTo(BigInteger.ONE) <= 0) { + + // need to reset the random pair next time + u = BigInteger.ZERO; + v = BigInteger.ZERO; + } else { + u = u.modPow(BIG_TWO, n); + v = v.modPow(BIG_TWO, n); + } + } // Otherwise, need to reset the random pair. + } + return brp; + } + + return null; } } - /** - * Return valid RSA blinding parameters for the given private key. - * Use cached parameters if available. If not, generate new parameters - * and cache. - */ - private static BlindingParameters getBlindingParameters - (RSAPrivateCrtKey key) { - BigInteger modulus = key.getModulus(); - BigInteger e = key.getPublicExponent(); - BlindingParameters params; - // we release the lock between get() and put() - // that means threads might concurrently generate new blinding - // parameters for the same modulus. this is only a slight waste - // of cycles and seems preferable in terms of scalability - // to locking out all threads while generating new parameters + private static BlindingRandomPair getBlindingRandomPair( + BigInteger e, BigInteger d, BigInteger n) { + + BlindingParameters bps = null; synchronized (blindingCache) { - params = blindingCache.get(modulus); + bps = blindingCache.get(n); } - if ((params != null) && params.valid(e)) { - return params; + + if (bps == null) { + bps = new BlindingParameters(e, d, n); + synchronized (blindingCache) { + if (blindingCache.get(n) == null) { + blindingCache.put(n, bps); + } + } } - int len = modulus.bitLength(); - SecureRandom random = JCAUtil.getSecureRandom(); - BigInteger r = new BigInteger(len, random).mod(modulus); - BigInteger re = r.modPow(e, modulus); - BigInteger rInv = r.modInverse(modulus); - params = new BlindingParameters(e, re, rInv); - synchronized (blindingCache) { - blindingCache.put(modulus, params); + + BlindingRandomPair brp = bps.getBlindingRandomPair(e, d, n); + if (brp == null) { + // need to reset the blinding parameters + bps = new BlindingParameters(e, d, n); + synchronized (blindingCache) { + if (blindingCache.get(n) != null) { + blindingCache.put(n, bps); + } + } + brp = bps.getBlindingRandomPair(e, d, n); } - return params; + + return brp; } } --- ./jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Wed Apr 16 12:37:49 2014 +0400 @@ -50,23 +50,6 @@ */ final class RSAClientKeyExchange extends HandshakeMessage { - /** - * The TLS spec says that the version in the RSA premaster secret must - * be the maximum version supported by the client (i.e. the version it - * requested in its client hello version). However, we (and other - * implementations) used to send the active negotiated version. The - * system property below allows to toggle the behavior. - */ - private final static String PROP_NAME = - "com.sun.net.ssl.rsaPreMasterSecretFix"; - - /* - * Default is "false" (old behavior) for compatibility reasons in - * SSLv3/TLSv1. Later protocols (TLSv1.1+) do not use this property. - */ - private final static boolean rsaPreMasterSecretFix = - Debug.getBooleanProperty(PROP_NAME, false); - /* * The following field values were encrypted with the server's public * key (or temp key from server key exchange msg) and are presented @@ -90,22 +73,12 @@ } this.protocolVersion = protocolVersion; - int major, minor; - - if (rsaPreMasterSecretFix || maxVersion.v >= ProtocolVersion.TLS11.v) { - major = maxVersion.major; - minor = maxVersion.minor; - } else { - major = protocolVersion.major; - minor = protocolVersion.minor; - } - try { String s = ((protocolVersion.v >= ProtocolVersion.TLS12.v) ? "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret"); KeyGenerator kg = JsseJce.getKeyGenerator(s); - kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor), - generator); + kg.init(new TlsRsaPremasterSecretParameterSpec( + maxVersion.v, protocolVersion.v), generator); preMaster = kg.generateKey(); Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); @@ -140,18 +113,17 @@ } } - Exception failover = null; - byte[] encoded = null; try { Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); // Cannot generate key here, please don't use Cipher.UNWRAP_MODE! - cipher.init(Cipher.DECRYPT_MODE, privateKey); - encoded = cipher.doFinal(encrypted); - } catch (BadPaddingException bpe) { - failover = bpe; - encoded = null; - } catch (IllegalBlockSizeException ibse) { - // the message it too big to process with RSA + cipher.init(Cipher.UNWRAP_MODE, privateKey, + new TlsRsaPremasterSecretParameterSpec( + maxVersion.v, currentVersion.v), + generator); + preMaster = (SecretKey)cipher.unwrap(encrypted, + "TlsRsaPremasterSecret", Cipher.SECRET_KEY); + } catch (InvalidKeyException ibk) { + // the message is too big to process with RSA throw new SSLProtocolException( "Unable to process PreMasterSecret, may be too big"); } catch (Exception e) { @@ -162,124 +134,6 @@ } throw new RuntimeException("Could not generate dummy secret", e); } - - // polish the premaster secret - preMaster = polishPreMasterSecretKey( - currentVersion, maxVersion, generator, encoded, failover); - } - - /** - * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246, - * treating incorrectly formatted message blocks and/or mismatched - * version numbers in a manner indistinguishable from correctly - * formatted RSA blocks. - * - * RFC 5246 describes the approach as : - * - * 1. Generate a string R of 48 random bytes - * - * 2. Decrypt the message to recover the plaintext M - * - * 3. If the PKCS#1 padding is not correct, or the length of message - * M is not exactly 48 bytes: - * pre_master_secret = R - * else If ClientHello.client_version <= TLS 1.0, and version - * number check is explicitly disabled: - * premaster secret = M - * else If M[0..1] != ClientHello.client_version: - * premaster secret = R - * else: - * premaster secret = M - * - * Note that #2 has completed before the call of this method. - */ - private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion, - ProtocolVersion clientHelloVersion, SecureRandom generator, - byte[] encoded, Exception failoverException) { - - this.protocolVersion = clientHelloVersion; - if (generator == null) { - generator = new SecureRandom(); - } - byte[] random = new byte[48]; - generator.nextBytes(random); - - if (failoverException == null && encoded != null) { - // check the length - if (encoded.length != 48) { - if (debug != null && Debug.isOn("handshake")) { - System.out.println( - "incorrect length of premaster secret: " + - encoded.length); - } - - return generatePreMasterSecret( - clientHelloVersion, random, generator); - } - - if (clientHelloVersion.major != encoded[0] || - clientHelloVersion.minor != encoded[1]) { - - if (clientHelloVersion.v <= ProtocolVersion.TLS10.v && - currentVersion.major == encoded[0] && - currentVersion.minor == encoded[1]) { - /* - * For compatibility, we maintain the behavior that the - * version in pre_master_secret can be the negotiated - * version for TLS v1.0 and SSL v3.0. - */ - this.protocolVersion = currentVersion; - } else { - if (debug != null && Debug.isOn("handshake")) { - System.out.println("Mismatching Protocol Versions, " + - "ClientHello.client_version is " + - clientHelloVersion + - ", while PreMasterSecret.client_version is " + - ProtocolVersion.valueOf(encoded[0], encoded[1])); - } - - encoded = random; - } - } - - return generatePreMasterSecret( - clientHelloVersion, encoded, generator); - } - - if (debug != null && Debug.isOn("handshake") && - failoverException != null) { - System.out.println("Error decrypting premaster secret:"); - failoverException.printStackTrace(System.out); - } - - return generatePreMasterSecret(clientHelloVersion, random, generator); - } - - // generate a premaster secret with the specified version number - private static SecretKey generatePreMasterSecret( - ProtocolVersion version, byte[] encodedSecret, - SecureRandom generator) { - - if (debug != null && Debug.isOn("handshake")) { - System.out.println("Generating a random fake premaster secret"); - } - - try { - String s = ((version.v >= ProtocolVersion.TLS12.v) ? - "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret"); - KeyGenerator kg = JsseJce.getKeyGenerator(s); - kg.init(new TlsRsaPremasterSecretParameterSpec( - version.major, version.minor, encodedSecret), generator); - return kg.generateKey(); - } catch (InvalidAlgorithmParameterException | - NoSuchAlgorithmException iae) { - // unlikely to happen, otherwise, must be a provider exception - if (debug != null && Debug.isOn("handshake")) { - System.out.println("RSA premaster secret generation error:"); - iae.printStackTrace(System.out); - } - throw new RuntimeException("Could not generate dummy secret", iae); - } } @Override --- ./jdk/src/share/classes/sun/security/util/KeyUtil.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/classes/sun/security/util/KeyUtil.java Wed Apr 16 12:37:49 2014 +0400 @@ -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 @@ -32,6 +32,7 @@ import java.security.interfaces.ECKey; import java.security.interfaces.RSAKey; import java.security.interfaces.DSAKey; +import java.security.SecureRandom; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHKey; @@ -157,6 +158,79 @@ } /** + * Check the format of TLS PreMasterSecret. + *

+ * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246, + * treating incorrectly formatted message blocks and/or mismatched + * version numbers in a manner indistinguishable from correctly + * formatted RSA blocks. + * + * RFC 5246 describes the approach as : + * + * 1. Generate a string R of 48 random bytes + * + * 2. Decrypt the message to recover the plaintext M + * + * 3. If the PKCS#1 padding is not correct, or the length of message + * M is not exactly 48 bytes: + * pre_master_secret = R + * else If ClientHello.client_version <= TLS 1.0, and version + * number check is explicitly disabled: + * premaster secret = M + * else If M[0..1] != ClientHello.client_version: + * premaster secret = R + * else: + * premaster secret = M + * + * Note that #2 should have completed before the call to this method. + * + * @param clientVersion the version of the TLS protocol by which the + * client wishes to communicate during this session + * @param serverVersion the negotiated version of the TLS protocol which + * contains the lower of that suggested by the client in the client + * hello and the highest supported by the server. + * @param encoded the encoded key in its "RAW" encoding format + * @param isFailover whether or not the previous decryption of the + * encrypted PreMasterSecret message run into problem + * @return the polished PreMasterSecret key in its "RAW" encoding format + */ + public static byte[] checkTlsPreMasterSecretKey( + int clientVersion, int serverVersion, SecureRandom random, + byte[] encoded, boolean isFailOver) { + + if (random == null) { + random = new SecureRandom(); + } + byte[] replacer = new byte[48]; + random.nextBytes(replacer); + + if (!isFailOver && (encoded != null)) { + // check the length + if (encoded.length != 48) { + // private, don't need to clone the byte array. + return replacer; + } + + int encodedVersion = + ((encoded[0] & 0xFF) << 8) | (encoded[1] & 0xFF); + if (clientVersion != encodedVersion) { + if (clientVersion > 0x0301 || // 0x0301: TLSv1 + serverVersion != encodedVersion) { + encoded = replacer; + } // Otherwise, For compatibility, we maintain the behavior + // that the version in pre_master_secret can be the + // negotiated version for TLS v1.0 and SSL v3.0. + } + + // private, don't need to clone the byte array. + return encoded; + } + + // private, don't need to clone the byte array. + return replacer; + } + + /** * Returns whether the Diffie-Hellman public key is valid or not. * * Per RFC 2631 and NIST SP800-56A, the following algorithm is used to @@ -198,7 +272,16 @@ "Diffie-Hellman public key is too large"); } - // Don't bother to check against the y^q mod p if safe primes are used. + // y^q mod p == 1? + // Unable to perform this check as q is unknown in this circumstance. + + // p is expected to be prime. However, it is too expensive to check + // that p is prime. Instead, in order to mitigate the impact of + // non-prime values, we check that y is not a factor of p. + BigInteger r = p.remainder(y); + if (r.equals(BigInteger.ZERO)) { + throw new InvalidKeyException("Invalid Diffie-Hellman parameters"); + } } /** --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/src/share/classes/sun/util/resources/CalendarData_pt_BR.properties Wed Apr 16 12:37:49 2014 +0400 @@ -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. +# + +# (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved +# (C) Copyright IBM Corp. 1996 - 1999 - All Rights Reserved +# +# The original version of this source code and documentation +# is copyrighted and owned by Taligent, Inc., a wholly-owned +# subsidiary of IBM. These materials are provided under terms +# of a License Agreement between Taligent and Sun. This technology +# is protected by multiple US and International patents. +# +# This notice and attribution to Taligent may not be removed. +# Taligent is a registered trademark of Taligent, Inc. + + +firstDayOfWeek=1 +minimalDaysInFirstWeek=1 --- ./jdk/src/share/native/com/sun/java/util/jar/pack/defines.h Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/native/com/sun/java/util/jar/pack/defines.h Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -79,6 +79,7 @@ #define ERROR_RESOURCE "Cannot extract resource file" #define ERROR_OVERFLOW "Internal buffer overflow" #define ERROR_INTERNAL "Internal error" +#define ERROR_INIT "cannot init class members" #define LOGFILE_STDOUT "-" #define LOGFILE_STDERR "" --- ./jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp Wed Apr 16 12:37:49 2014 +0400 @@ -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 @@ -56,6 +56,45 @@ #define THROW_IOE(x) JNU_ThrowIOException(env,x) +#define CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(CERVTI_exception, CERVTI_message) \ + do { \ + if ((env)->ExceptionOccurred()) { \ + THROW_IOE(CERVTI_message); \ + return; \ + } \ + if ((CERVTI_exception) == NULL) { \ + THROW_IOE(CERVTI_message); \ + return; \ + } \ + } while (JNI_FALSE) + + +#define CHECK_EXCEPTION_RETURN_VALUE(CERL_exception, CERL_return_value) \ + do { \ + if ((env)->ExceptionOccurred()) { \ + return CERL_return_value; \ + } \ + if ((CERL_exception) == NULL) { \ + return CERL_return_value; \ + } \ + } while (JNI_FALSE) + + +// If these useful macros aren't defined in jni_util.h then define them here +#ifndef CHECK_NULL_RETURN +#define CHECK_NULL_RETURN(x, y) \ + do { \ + if ((x) == NULL) return (y); \ + } while (JNI_FALSE) +#endif + +#ifndef CHECK_EXCEPTION_RETURN +#define CHECK_EXCEPTION_RETURN(env, y) \ + do { \ + if ((*env)->ExceptionCheck(env)) return (y); \ + } while (JNI_FALSE) +#endif + static jlong read_input_via_jni(unpacker* self, void* buf, jlong minlen, jlong maxlen); @@ -92,9 +131,11 @@ vm->GetEnv(&envRaw, JNI_VERSION_1_1); JNIEnv* env = (JNIEnv*) envRaw; //fprintf(stderr, "get_unpacker() env=%p\n", env); - if (env == null) - return null; + CHECK_NULL_RETURN(env, NULL); jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); + // We should check upon the known non-null variable because here we want to check + // only for pending exceptions. If pObj is null we'll deal with it later. + CHECK_EXCEPTION_RETURN_VALUE(env, NULL); //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj); if (pObj != null) { // Got pObj and env; now do it the easy way. @@ -137,20 +178,20 @@ while( dbg != null) { sleep(10); } #endif NIclazz = (jclass) env->NewGlobalRef(clazz); + unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(unpackerPtrFID, ERROR_INIT); + currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", "()Ljava/lang/Object;"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(currentInstMID, ERROR_INIT); + readInputMID = env->GetMethodID(clazz, "readInputFn", "(Ljava/nio/ByteBuffer;J)J"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(readInputMID, ERROR_INIT); + getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J"); - - if (unpackerPtrFID == null || - currentInstMID == null || - readInputMID == null || - NIclazz == null || - getUnpackerPtrMID == null) { - THROW_IOE("cannot init class members"); - } + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(getUnpackerPtrMID, ERROR_INIT); } JNIEXPORT jlong JNICALL @@ -160,9 +201,7 @@ // valid object pointers and env is intact, if not now is good time to bail. unpacker* uPtr = get_unpacker(); //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr); - if (uPtr == null) { - return -1; - } + CHECK_EXCEPTION_RETURN_VALUE(uPtr, -1); // redirect our io to the default log file or whatever. uPtr->redirect_stdio(); @@ -200,6 +239,7 @@ jobjectArray pParts) { unpacker* uPtr = get_unpacker(env, pObj); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); unpacker::file* filep = uPtr->get_next_file(); if (uPtr->aborting()) { @@ -207,32 +247,38 @@ return false; } - if (filep == null) { - return false; // end of the sequence - } + CHECK_NULL_RETURN(filep, false); assert(filep == &uPtr->cur_file); int pidx = 0, iidx = 0; jintArray pIntParts = (jintArray) env->GetObjectArrayElement(pParts, pidx++); + CHECK_EXCEPTION_RETURN_VALUE(pIntParts, false); jint* intParts = env->GetIntArrayElements(pIntParts, null); intParts[iidx++] = (jint)( (julong)filep->size >> 32 ); intParts[iidx++] = (jint)( (julong)filep->size >> 0 ); intParts[iidx++] = filep->modtime; intParts[iidx++] = filep->deflate_hint() ? 1 : 0; env->ReleaseIntArrayElements(pIntParts, intParts, JNI_COMMIT); - - env->SetObjectArrayElement(pParts, pidx++, env->NewStringUTF(filep->name)); - + jstring filename = env->NewStringUTF(filep->name); + CHECK_EXCEPTION_RETURN_VALUE(filename, false); + env->SetObjectArrayElement(pParts, pidx++, filename); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); jobject pDataBuf = null; - if (filep->data[0].len > 0) + if (filep->data[0].len > 0) { pDataBuf = env->NewDirectByteBuffer(filep->data[0].ptr, filep->data[0].len); + CHECK_EXCEPTION_RETURN_VALUE(pDataBuf, false); + } env->SetObjectArrayElement(pParts, pidx++, pDataBuf); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); pDataBuf = null; - if (filep->data[1].len > 0) + if (filep->data[1].len > 0) { pDataBuf = env->NewDirectByteBuffer(filep->data[1].ptr, filep->data[1].len); + CHECK_EXCEPTION_RETURN_VALUE(pDataBuf, false); + } env->SetObjectArrayElement(pParts, pidx++, pDataBuf); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); return true; } @@ -241,6 +287,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject pObj) { unpacker* uPtr = get_unpacker(env, pObj); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL); unpacker::file* filep = &uPtr->cur_file; if (uPtr->aborting()) { @@ -263,7 +310,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) { unpacker* uPtr = get_unpacker(env, pObj, false); - if (uPtr == null) return 0; + CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL); size_t consumed = uPtr->input_consumed(); free_unpacker(env, pObj, uPtr); return consumed; @@ -274,7 +321,9 @@ jstring pProp, jstring pValue) { unpacker* uPtr = get_unpacker(env, pObj); const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); + CHECK_EXCEPTION_RETURN_VALUE(prop, false); const char* value = env->GetStringUTFChars(pValue, JNI_FALSE); + CHECK_EXCEPTION_RETURN_VALUE(value, false); jboolean retval = uPtr->set_option(prop, value); env->ReleaseStringUTFChars(pProp, prop); env->ReleaseStringUTFChars(pValue, value); @@ -286,9 +335,11 @@ jstring pProp) { unpacker* uPtr = get_unpacker(env, pObj); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL); const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); + CHECK_EXCEPTION_RETURN_VALUE(prop, NULL); const char* value = uPtr->get_option(prop); + CHECK_EXCEPTION_RETURN_VALUE(value, NULL); env->ReleaseStringUTFChars(pProp, prop); - if (value == null) return null; return env->NewStringUTF(value); } --- ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -373,14 +373,14 @@ /* Parse the source image */ - if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) { /* Can't handle any custom images */ free(dkern); return 0; } /* Parse the destination image */ - if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) { /* Can't handle any custom images */ awt_freeParsedImage(srcImageP, TRUE); free(dkern); @@ -627,7 +627,7 @@ } /* Parse the source raster */ - if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { /* Can't handle any custom rasters */ free(srcRasterP); free(dstRasterP); @@ -636,7 +636,7 @@ } /* Parse the destination raster */ - if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { + if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { /* Can't handle any custom images */ awt_freeParsedRaster(srcRasterP, TRUE); free(dstRasterP); @@ -839,13 +839,13 @@ (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT); /* Parse the source image */ - if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) { /* Can't handle any custom images */ return 0; } /* Parse the destination image */ - if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) { /* Can't handle any custom images */ awt_freeParsedImage(srcImageP, TRUE); return 0; @@ -1059,7 +1059,7 @@ (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT); /* Parse the source raster */ - if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { /* Can't handle any custom rasters */ free(srcRasterP); free(dstRasterP); @@ -1067,7 +1067,7 @@ } /* Parse the destination raster */ - if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { + if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { /* Can't handle any custom images */ awt_freeParsedRaster(srcRasterP, TRUE); free(dstRasterP); @@ -1305,13 +1305,13 @@ if (s_timeIt) (*start_timer)(3600); /* Parse the source image */ - if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) { /* Can't handle any custom images */ return 0; } /* Parse the destination image */ - if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) { /* Can't handle any custom images */ awt_freeParsedImage(srcImageP, TRUE); return 0; @@ -1553,14 +1553,14 @@ } /* Parse the source raster - reject custom images */ - if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { free(srcRasterP); free(dstRasterP); return 0; } /* Parse the destination image - reject custom images */ - if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { + if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { awt_freeParsedRaster(srcRasterP, TRUE); free(dstRasterP); return 0; --- ./jdk/src/share/native/sun/font/freetypeScaler.c Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/native/sun/font/freetypeScaler.c Wed Apr 16 12:37:49 2014 +0400 @@ -177,18 +177,10 @@ if (numBytes > FILEDATACACHESIZE) { bBuffer = (*env)->NewDirectByteBuffer(env, destBuffer, numBytes); if (bBuffer != NULL) { - /* Loop until the read succeeds (or EOF). - * This should improve robustness in the event of a problem in - * the I/O system. If we find that we ever end up spinning here - * we are going to have to do some serious work to recover. - * Just returning without reading the data will cause a crash. - */ - while (bread == 0) { - bread = (*env)->CallIntMethod(env, - scalerInfo->font2D, - sunFontIDs.ttReadBlockMID, - bBuffer, offset, numBytes); - } + bread = (*env)->CallIntMethod(env, + scalerInfo->font2D, + sunFontIDs.ttReadBlockMID, + bBuffer, offset, numBytes); return bread; } else { /* We probably hit bug bug 4845371. For reasons that @@ -224,19 +216,10 @@ (offset + FILEDATACACHESIZE > scalerInfo->fileSize) ? scalerInfo->fileSize - offset : FILEDATACACHESIZE; bBuffer = scalerInfo->directBuffer; - /* Loop until all the read succeeds (or EOF). - * This should improve robustness in the event of a problem in - * the I/O system. If we find that we ever end up spinning here - * we are going to have to do some serious work to recover. - * Just returning without reading the data will cause a crash. - */ - while (bread == 0) { - bread = (*env)->CallIntMethod(env, scalerInfo->font2D, - sunFontIDs.ttReadBlockMID, - bBuffer, offset, - scalerInfo->fontDataLength); - } - + bread = (*env)->CallIntMethod(env, scalerInfo->font2D, + sunFontIDs.ttReadBlockMID, + bBuffer, offset, + scalerInfo->fontDataLength); memcpy(destBuffer, scalerInfo->fontData, numBytes); return numBytes; } --- ./jdk/src/share/native/sun/management/GcInfoBuilder.c Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/native/sun/management/GcInfoBuilder.c Wed Apr 16 12:37:49 2014 +0400 @@ -190,7 +190,7 @@ if (ext_att_count <= 0) { JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count"); - return; + return 0; } gc_stat.usage_before_gc = usageBeforeGC; --- ./jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -62,24 +62,42 @@ SECITEM_FreeItem(&ecparams->curveOID, B_FALSE); if (freeStruct) free(ecparams); + +} + +jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem) +{ + SECItem *s = (SECItem *)hSECItem; + + jbyteArray jEncodedBytes = env->NewByteArray(s->len); + if (jEncodedBytes == NULL) { + return NULL; + } + // Copy bytes from a native SECItem buffer to java byte array + env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data); + if (env->ExceptionCheck()) { //should never happen + return NULL; + } + return jEncodedBytes; } /* * Class: sun_security_ec_ECKeyPairGenerator * Method: generateECKeyPair - * Signature: (I[B[B)[J + * Signature: (I[B[B)[B */ -JNIEXPORT jlongArray +JNIEXPORT jobjectArray JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair (JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed) { - ECPrivateKey *privKey; /* contains both public and private values */ + ECPrivateKey *privKey = NULL; /* contains both public and private values */ ECParams *ecparams = NULL; SECKEYECParams params_item; jint jSeedLength; jbyte* pSeedBuffer = NULL; - jlongArray result = NULL; - jlong* resultElements = NULL; + jobjectArray result = NULL; + jclass baCls = NULL; + jbyteArray jba; // Initialize the ECParams struct params_item.len = env->GetArrayLength(encodedParams); @@ -106,61 +124,64 @@ } jboolean isCopy; - result = env->NewLongArray(2); - resultElements = env->GetLongArrayElements(result, &isCopy); + baCls = env->FindClass("[B"); + if (baCls == NULL) { + goto cleanup; + } + result = env->NewObjectArray(2, baCls, NULL); + if (result == NULL) { + goto cleanup; + } + jba = getEncodedBytes(env, &(privKey->privateValue)); + if (jba == NULL) { + result = NULL; + goto cleanup; + } + env->SetObjectArrayElement(result, 0, jba); // big integer + if (env->ExceptionCheck()) { // should never happen + result = NULL; + goto cleanup; + } - resultElements[0] = (jlong) &(privKey->privateValue); // private big integer - resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point - - // If the array is a copy then we must write back our changes - if (isCopy == JNI_TRUE) { - env->ReleaseLongArrayElements(result, resultElements, 0); + jba = getEncodedBytes(env, &(privKey->publicValue)); + if (jba == NULL) { + result = NULL; + goto cleanup; + } + env->SetObjectArrayElement(result, 1, jba); // encoded ec point + if (env->ExceptionCheck()) { // should never happen + result = NULL; + goto cleanup; } cleanup: { - if (params_item.data) + if (params_item.data) { env->ReleaseByteArrayElements(encodedParams, (jbyte *) params_item.data, JNI_ABORT); + } - if (ecparams) + if (ecparams) { FreeECParams(ecparams, true); + } if (privKey) { FreeECParams(&privKey->ecParams, false); SECITEM_FreeItem(&privKey->version, B_FALSE); - // Don't free privKey->privateValue and privKey->publicValue + SECITEM_FreeItem(&privKey->privateValue, B_FALSE); + SECITEM_FreeItem(&privKey->publicValue, B_FALSE); + free(privKey); } - if (pSeedBuffer) + if (pSeedBuffer) { delete [] pSeedBuffer; + } } return result; } /* - * Class: sun_security_ec_ECKeyPairGenerator - * Method: getEncodedBytes - * Signature: (J)[B - */ -JNIEXPORT jbyteArray -JNICALL Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes - (JNIEnv *env, jclass clazz, jlong hSECItem) -{ - SECItem *s = (SECItem *)hSECItem; - jbyteArray jEncodedBytes = env->NewByteArray(s->len); - - // Copy bytes from a native SECItem buffer to Java byte array - env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data); - - // Use B_FALSE to free only the SECItem->data - SECITEM_FreeItem(s, B_FALSE); - - return jEncodedBytes; -} - -/* * Class: sun_security_ec_ECDSASignature * Method: signDigest * Signature: ([B[B[B[B)[B @@ -234,21 +255,31 @@ cleanup: { - if (params_item.data) + if (params_item.data) { env->ReleaseByteArrayElements(encodedParams, (jbyte *) params_item.data, JNI_ABORT); + } - if (pDigestBuffer) + if (privKey.privateValue.data) { + env->ReleaseByteArrayElements(privateKey, + (jbyte *) privKey.privateValue.data, JNI_ABORT); + } + + if (pDigestBuffer) { delete [] pDigestBuffer; + } - if (pSignedDigestBuffer) + if (pSignedDigestBuffer) { delete [] pSignedDigestBuffer; + } - if (pSeedBuffer) + if (pSeedBuffer) { delete [] pSeedBuffer; + } - if (ecparams) + if (ecparams) { FreeECParams(ecparams, true); + } } return jSignedDigest; --- ./jdk/src/solaris/classes/sun/font/FcFontConfiguration.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/solaris/classes/sun/font/FcFontConfiguration.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -33,6 +33,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.HashMap; import java.util.HashSet; @@ -173,8 +174,16 @@ } @Override - public FontDescriptor[] getFontDescriptors(String fontName, int style) { - return new FontDescriptor[0]; + protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { + CompositeFontDescriptor[] cfi = get2DCompositeFontInfo(); + int idx = fontIndex * NUM_STYLES + styleIndex; + String[] componentFaceNames = cfi[idx].getComponentFaceNames(); + FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length]; + for (int i = 0; i < componentFaceNames.length; i++) { + ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.UTF_8.newEncoder(), new int[0]); + } + + return ret; } @Override @@ -250,10 +259,12 @@ } String[] fileNames = new String[numFonts]; + String[] faceNames = new String[numFonts]; int index; for (index = 0; index < fcFonts.length; index++) { fileNames[index] = fcFonts[index].fontFile; + faceNames[index] = fcFonts[index].familyName; } if (installedFallbackFontFiles != null) { @@ -266,7 +277,7 @@ = new CompositeFontDescriptor( faceName, 1, - null, + faceNames, fileNames, null, null); } --- ./jdk/src/windows/bin/java_md.c Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/bin/java_md.c Wed Apr 16 12:37:49 2014 +0400 @@ -1301,6 +1301,14 @@ /* save path length */ jrePathLen = JLI_StrLen(libraryPath); + if (jrePathLen + JLI_StrLen("\\bin\\verify.dll") >= MAXPATHLEN) { + /* jre path is too long, the library path will not fit there; + * report and abort preloading + */ + JLI_ReportErrorMessage(JRE_ERROR11); + break; + } + /* load msvcrt 1st */ LoadMSVCRT(); --- ./jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Wed Apr 16 12:37:49 2014 +0400 @@ -583,11 +583,18 @@ // Needs to be accessible to Win32ShellFolderManager2 static String getFileSystemPath(final int csidl) throws IOException, InterruptedException { - return invoke(new Callable() { + String path = invoke(new Callable() { public String call() throws IOException { return getFileSystemPath0(csidl); } }, IOException.class); + if (path != null) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkRead(path); + } + } + return path; } // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details --- ./jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Wed Apr 16 12:37:49 2014 +0400 @@ -138,6 +138,8 @@ if (desktop == null) { try { desktop = new Win32ShellFolder2(DESKTOP); + } catch (SecurityException e) { + // Ignore error } catch (IOException e) { // Ignore error } catch (InterruptedException e) { @@ -151,6 +153,8 @@ if (drives == null) { try { drives = new Win32ShellFolder2(DRIVES); + } catch (SecurityException e) { + // Ignore error } catch (IOException e) { // Ignore error } catch (InterruptedException e) { @@ -167,6 +171,8 @@ if (path != null) { recent = createShellFolder(getDesktop(), new File(path)); } + } catch (SecurityException e) { + // Ignore error } catch (InterruptedException e) { // Ignore error } catch (IOException e) { @@ -180,6 +186,8 @@ if (network == null) { try { network = new Win32ShellFolder2(NETWORK); + } catch (SecurityException e) { + // Ignore error } catch (IOException e) { // Ignore error } catch (InterruptedException e) { @@ -203,6 +211,8 @@ personal.setIsPersonal(); } } + } catch (SecurityException e) { + // Ignore error } catch (InterruptedException e) { // Ignore error } catch (IOException e) { --- ./jdk/src/windows/classes/sun/awt/windows/ThemeReader.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/classes/sun/awt/windows/ThemeReader.java Wed Apr 16 12:37:49 2014 +0400 @@ -56,18 +56,12 @@ new ReentrantReadWriteLock(); private static final Lock readLock = readWriteLock.readLock(); private static final Lock writeLock = readWriteLock.writeLock(); + private static volatile boolean valid = false; static void flush() { - writeLock.lock(); - try { - // Close old themes. - for (Long value : widgetToTheme.values()) { - closeTheme(value.longValue()); - } - widgetToTheme.clear(); - } finally { - writeLock.unlock(); - } + // Could be called on Toolkit thread, so do not try to aquire locks + // to avoid deadlock with theme initialization + valid = false; } public native static boolean isThemed(); @@ -94,6 +88,24 @@ // returns theme value // this method should be invoked with readLock locked private static Long getTheme(String widget) { + if (!valid) { + readLock.unlock(); + writeLock.lock(); + try { + if (!valid) { + // Close old themes. + for (Long value : widgetToTheme.values()) { + closeTheme(value); + } + widgetToTheme.clear(); + valid = true; + } + } finally { + readLock.lock(); + writeLock.unlock(); + } + } + // mostly copied from the javadoc for ReentrantReadWriteLock Long theme = widgetToTheme.get(widget); if (theme == null) { --- ./jdk/src/windows/classes/sun/awt/windows/WToolkit.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/classes/sun/awt/windows/WToolkit.java Wed Apr 16 12:37:49 2014 +0400 @@ -864,12 +864,18 @@ * Windows doesn't always send WM_SETTINGCHANGE when it should. */ private void windowsSettingChange() { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - updateProperties(); - } - }); + if (AppContext.getAppContext() == null) { + // We cannot post the update to any EventQueue. Listeners will + // be called on EDTs by DesktopPropertyChangeSupport + updateProperties(); + } else { + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + updateProperties(); + } + }); + } } private synchronized void updateProperties() { --- ./jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Apr 16 12:37:49 2014 +0400 @@ -421,6 +421,7 @@ */ public static long[] getActiveWindowHandles() { AppContext appContext = AppContext.getAppContext(); + if (appContext == null) return null; synchronized (appContext) { List l = (List)appContext.get(ACTIVE_WINDOWS_KEY); if (l == null) { --- ./jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Wed Apr 16 12:37:49 2014 +0400 @@ -35,6 +35,8 @@ import javax.crypto.spec.*; import sun.security.rsa.RSAKeyFactory; +import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; +import sun.security.util.KeyUtil; /** * RSA cipher implementation using the Microsoft Crypto API. @@ -92,9 +94,16 @@ // the public key, if we were initialized using a public key private sun.security.mscapi.Key publicKey; + // the private key, if we were initialized using a private key private sun.security.mscapi.Key privateKey; + // cipher parameter for TLS RSA premaster secret + private AlgorithmParameterSpec spec = null; + + // the source of randomness + private SecureRandom random; + public RSACipher() { paddingType = PAD_PKCS1; } @@ -155,8 +164,12 @@ throws InvalidKeyException, InvalidAlgorithmParameterException { if (params != null) { - throw new InvalidAlgorithmParameterException - ("Parameters not supported"); + if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new InvalidAlgorithmParameterException( + "Parameters not supported"); + } + spec = params; + this.random = random; // for TLS RSA premaster secret } init(opmode, key); } @@ -356,39 +369,47 @@ } // see JCE spec - protected java.security.Key engineUnwrap(byte[] wrappedKey, String algorithm, + protected java.security.Key engineUnwrap(byte[] wrappedKey, + String algorithm, int type) throws InvalidKeyException, NoSuchAlgorithmException { if (wrappedKey.length > buffer.length) { throw new InvalidKeyException("Key is too long for unwrapping"); } + + boolean isTlsRsaPremasterSecret = + algorithm.equals("TlsRsaPremasterSecret"); + Exception failover = null; + byte[] encoded = null; + update(wrappedKey, 0, wrappedKey.length); - try { - byte[] encoding = doFinal(); - - switch (type) { - case Cipher.PUBLIC_KEY: - return constructPublicKey(encoding, algorithm); - - case Cipher.PRIVATE_KEY: - return constructPrivateKey(encoding, algorithm); - - case Cipher.SECRET_KEY: - return constructSecretKey(encoding, algorithm); - - default: - throw new InvalidKeyException("Unknown key type " + type); + encoded = doFinal(); + } catch (BadPaddingException e) { + if (isTlsRsaPremasterSecret) { + failover = e; + } else { + throw new InvalidKeyException("Unwrapping failed", e); } - - } catch (BadPaddingException e) { - // should not occur - throw new InvalidKeyException("Unwrapping failed", e); - } catch (IllegalBlockSizeException e) { // should not occur, handled with length check above throw new InvalidKeyException("Unwrapping failed", e); } + + if (isTlsRsaPremasterSecret) { + if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new IllegalStateException( + "No TlsRsaPremasterSecretParameterSpec specified"); + } + + // polish the TLS premaster secret + encoded = KeyUtil.checkTlsPreMasterSecretKey( + ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(), + ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(), + random, encoded, (failover != null)); + } + + return constructKey(encoded, algorithm, type); } // see JCE spec @@ -452,6 +473,22 @@ return new SecretKeySpec(encodedKey, encodedKeyAlgorithm); } + private static Key constructKey(byte[] encodedKey, + String encodedKeyAlgorithm, + int keyType) throws InvalidKeyException, NoSuchAlgorithmException { + + switch (keyType) { + case Cipher.PUBLIC_KEY: + return constructPublicKey(encodedKey, encodedKeyAlgorithm); + case Cipher.PRIVATE_KEY: + return constructPrivateKey(encodedKey, encodedKeyAlgorithm); + case Cipher.SECRET_KEY: + return constructSecretKey(encodedKey, encodedKeyAlgorithm); + default: + throw new InvalidKeyException("Unknown key type " + keyType); + } + } + /* * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY. * It expects and returns ciphertext data in big-endian form. --- ./jdk/src/windows/native/sun/windows/awt_Component.cpp Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/native/sun/windows/awt_Component.cpp Wed Apr 16 12:37:49 2014 +0400 @@ -1719,9 +1719,11 @@ case WM_IME_SETCONTEXT: // lParam is passed as pointer and it can be modified. mr = WmImeSetContext(static_cast(wParam), &lParam); + CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_IME_NOTIFY: mr = WmImeNotify(wParam, lParam); + CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_IME_STARTCOMPOSITION: mr = WmImeStartComposition(); @@ -4066,7 +4068,7 @@ { if (mr != mrConsume) { HWND proxy = GetProxyFocusOwner(); - if (proxy != NULL) { + if (proxy != NULL && ::IsWindowEnabled(proxy)) { retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); mr = mrConsume; } --- ./jdk/src/windows/native/sun/windows/awt_Frame.cpp Wed May 07 19:26:47 2014 -0700 +++ ./jdk/src/windows/native/sun/windows/awt_Frame.cpp Wed Apr 16 12:37:49 2014 +0400 @@ -319,6 +319,8 @@ case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: case WM_IME_CONTROL: case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: --- ./jdk/test/com/sun/crypto/provider/TLS/TestPremaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/com/sun/crypto/provider/TLS/TestPremaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -33,6 +33,7 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import java.util.Formatter; import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; @@ -52,27 +53,51 @@ System.out.println("OK: " + e); } - test(kg, 3, 0); - test(kg, 3, 1); - test(kg, 3, 2); - test(kg, 4, 0); + int[] protocolVersions = {0x0300, 0x0301, 0x0302, 0x0400}; + for (int clientVersion : protocolVersions) { + for (int serverVersion : protocolVersions) { + test(kg, clientVersion, serverVersion); + if (serverVersion >= clientVersion) { + break; + } + } + } System.out.println("Done."); } - private static void test(KeyGenerator kg, int major, int minor) - throws Exception { + private static void test(KeyGenerator kg, + int clientVersion, int serverVersion) throws Exception { - kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor)); + System.out.printf( + "Testing RSA pre-master secret key generation between " + + "client (0x%04X) and server(0x%04X)%n", + clientVersion, serverVersion); + kg.init(new TlsRsaPremasterSecretParameterSpec( + clientVersion, serverVersion)); + SecretKey key = kg.generateKey(); byte[] encoded = key.getEncoded(); - if (encoded.length != 48) { - throw new Exception("length: " + encoded.length); - } - if ((encoded[0] != major) || (encoded[1] != minor)) { - throw new Exception("version mismatch: " + encoded[0] + - "." + encoded[1]); - } - System.out.println("OK: " + major + "." + minor); + if (encoded != null) { // raw key material may be not extractable + if (encoded.length != 48) { + throw new Exception("length: " + encoded.length); + } + int v = versionOf(encoded[0], encoded[1]); + if (clientVersion != v) { + if (serverVersion != v || clientVersion >= 0x0302) { + throw new Exception(String.format( + "version mismatch: (0x%04X) rather than (0x%04X) " + + "is used in pre-master secret", v, clientVersion)); + } + System.out.printf("Use compatible version (0x%04X)%n", v); + } + System.out.println("Passed, version matches!"); + } else { + System.out.println("Raw key material is not extractable"); + } + } + + private static int versionOf(int major, int minor) { + return ((major & 0xFF) << 8) | (minor & 0xFF); } } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/awt/Focus/8013611/JDK8013611.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,111 @@ +/* + * 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 8013611 + @summary Tests showing a modal dialog with requesting focus in frame. + @author Anton.Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main JDK8013611 +*/ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; + +public class JDK8013611 extends JFrame { + static JTextField textField = new JTextField("text"); + static JButton button1 = new JButton("button1"); + static JButton button2 = new JButton("button2"); + static Robot robot; + + static JDialog dialog; + static JButton button3 = new JButton("button3"); + + public static void main(String[] args) { + robot = Util.createRobot(); + + JDK8013611 frame = new JDK8013611(); + frame.setLayout(new FlowLayout()); + frame.add(textField); + frame.add(button1); + frame.add(button2); + frame.pack(); + + dialog = new JDialog(frame, true); + dialog.add(button3); + dialog.pack(); + + textField.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + dialog.setVisible(true); + } + }); + + button1.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + button2.requestFocusInWindow(); + } + }); + + frame.setVisible(true); + + frame.test(); + } + + public void test() { + if (!testFocused(textField)) { + Util.clickOnComp(textField, robot); + if (!testFocused(textField)) { + throw new RuntimeException("Error: couldn't focus " + textField); + } + } + + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_TAB); + + if (!testFocused(button3)) { + throw new RuntimeException("Test failed: dialog didn't get focus!"); + } + + System.out.println("Test passed."); + } + + boolean testFocused(Component c) { + for (int i=0; i<10; i++) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == c) { + return true; + } + Util.waitForIdle(robot); + } + return false; + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/awt/Focus/DialogTraversFocusBackTest/DialogTraversFocusBackTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,94 @@ +/* + * 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 8031075 + @summary Regression: focus disappears with shift+tab on dialogue having a focus component + @author mcherkas + @run main DialogTraversFocusBackTest +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + +public class DialogTraversFocusBackTest { + + private static Robot robot; + private volatile static JButton button; + private static Component currentFocusOwner; + + public static void main(String[] args) throws Exception { + initUI(); + sync(); + initRobot(); + runScript(); + sync(); + validate(); + } + + public static void sync() { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + } + + private static void validate() throws Exception { + currentFocusOwner = FocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if(currentFocusOwner + != button) { + throw new Exception("Test failed! Wrong focus owner: " + + String.valueOf(currentFocusOwner) + "\n but must be: " + + button); + } + } + + private static void runScript() { + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + + } + + private static void initRobot() throws AWTException { + robot = new Robot(); + robot.setAutoDelay(100); + + } + + private static void initUI() throws Exception { + SwingUtilities.invokeAndWait( new Runnable() { + @Override + public void run() { + JDialog dialog = new JDialog((Frame)null, "Test Dialog"); + button = new JButton("Button 1"); + dialog.add(button); + dialog.pack(); + dialog.setVisible(true); + } + }); + + } +} --- ./jdk/test/java/awt/Frame/7024749/bug7024749.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/awt/Frame/7024749/bug7024749.java Wed Apr 16 12:37:49 2014 +0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 7024749 7184326 + * @bug 7024749 7184326 8019990 * @summary JDK7 b131---a crash in: Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined+0x75 * @library ../../regtesthelpers * @build Util --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2005, 2006, 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 7154048 + * @summary Window created under a mouse does not receive mouse enter event. + * Mouse Entered/Exited events are wrongly generated during dragging the window + * from one component to another + * @library ../../regtesthelpers + * @build Util + * @author alexandr.scherbatiy area=awt.event + * @run main DragWindowTest + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +import java.util.concurrent.*; +import sun.awt.SunToolkit; + +import test.java.awt.regtesthelpers.Util; + +public class DragWindowTest { + + private static volatile int dragWindowMouseEnteredCount = 0; + private static volatile int dragWindowMouseReleasedCount = 0; + private static volatile int buttonMouseEnteredCount = 0; + private static volatile int labelMouseReleasedCount = 0; + private static MyDragWindow dragWindow; + private static JLabel label; + private static JButton button; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + Point pointToClick = Util.invokeOnEDT(new Callable() { + + @Override + public Point call() throws Exception { + return getCenterPoint(label); + } + }); + + + robot.mouseMove(pointToClick.x, pointToClick.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (dragWindowMouseEnteredCount != 1) { + throw new RuntimeException("No MouseEntered event on Drag Window!"); + } + + Point pointToDrag = Util.invokeOnEDT(new Callable() { + + @Override + public Point call() throws Exception { + button.addMouseListener(new ButtonMouseListener()); + return getCenterPoint(button); + } + }); + + robot.mouseMove(pointToDrag.x, pointToDrag.y); + toolkit.realSync(); + + if (buttonMouseEnteredCount != 0) { + throw new RuntimeException("Extra MouseEntered event on button!"); + } + + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (labelMouseReleasedCount != 1) { + throw new RuntimeException("No MouseReleased event on label!"); + } + + } + + private static Point getCenterPoint(Component comp) { + Point p = comp.getLocationOnScreen(); + Rectangle rect = comp.getBounds(); + return new Point(p.x + rect.width / 2, p.y + rect.height / 2); + } + + private static void createAndShowGUI() { + + JFrame frame = new JFrame("Main Frame"); + frame.setSize(300, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + label = new JLabel("Label"); + + LabelMouseListener listener = new LabelMouseListener(frame); + label.addMouseListener(listener); + label.addMouseMotionListener(listener); + + button = new JButton("Button"); + Panel panel = new Panel(new BorderLayout()); + + panel.add(label, BorderLayout.NORTH); + panel.add(button, BorderLayout.CENTER); + + frame.getContentPane().add(panel); + frame.setVisible(true); + + } + + private static Point getAbsoluteLocation(MouseEvent e) { + return new Point(e.getXOnScreen(), e.getYOnScreen()); + } + + static class MyDragWindow extends Window { + + static int d = 30; + + public MyDragWindow(Window parent, Point location) { + super(parent); + setSize(150, 150); + setVisible(true); + JPanel panel = new JPanel(); + add(panel); + setLocation(location.x - d, location.y - d); + addMouseListener(new DragWindowMouseListener()); + } + + void dragTo(Point point) { + setLocation(point.x - d, point.y - d); + } + } + + static class LabelMouseListener extends MouseAdapter { + + Point origin; + Window parent; + + public LabelMouseListener(Window parent) { + this.parent = parent; + } + + @Override + public void mousePressed(MouseEvent e) { + if (dragWindow == null) { + dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e)); + } else { + dragWindow.setVisible(true); + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + labelMouseReleasedCount++; + if (dragWindow != null) { + dragWindow.setVisible(false); + } + } + + public void mouseDragged(MouseEvent e) { + if (dragWindow != null) { + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + } + + static class DragWindowMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + dragWindowMouseEnteredCount++; + } + + @Override + public void mouseReleased(MouseEvent e) { + dragWindowMouseReleasedCount++; + } + } + + static class ButtonMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + buttonMouseEnteredCount++; + } + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,108 @@ +/* + * 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 test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithOverlay.java + * @run main/othervm GetMousePositionWithOverlay + */ + +public class GetMousePositionWithOverlay { + + static Frame backFrame; + static Frame frontFrame; + + public static void main(String[] args) throws Throwable { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + Util.waitForIdle(null); + + Robot r = new Robot(); + Util.pointOnComp(frontFrame, r); + Util.waitForIdle(null); + + Point pos = getMousePosition(backFrame); + if (pos != null) { + throw new RuntimeException("Test failed. Mouse position should be null but was" + pos); + } + + pos = getMousePosition(frontFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + + r.mouseMove(189, 189); + Util.waitForIdle(null); + + pos = getMousePosition(backFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + backFrame.dispose(); + frontFrame.dispose(); + } + }); + } + } + + private static Point getMousePosition(final Component component) throws Exception { + final AtomicReference pos = new AtomicReference(); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + pos.set(component.getMousePosition()); + } + }); + return pos.get(); + } + + private static void constructTestUI() { + backFrame = new Frame(); + backFrame.setBounds(100, 100, 100, 100); + backFrame.setVisible(true); + + frontFrame = new Frame(); + frontFrame.setBounds(120, 120, 60, 60); + frontFrame.setVisible(true); + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,111 @@ +/* + * 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 test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithPopup.java + * @run main/othervm GetMousePositionWithPopup + */ + +public class GetMousePositionWithPopup { + + private static Frame frame1; + private static Frame frame2; + + public static void main(String[] args) throws Exception { + try { + Robot r = Util.createRobot(); + r.mouseMove(0, 0); + Util.waitForIdle(null); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + + Util.waitForIdle(null); + r.mouseMove(149, 149); + Util.waitForIdle(null); + r.mouseMove(150, 150); + Util.waitForIdle(null); + + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + frame1.dispose(); + frame2.dispose(); + } + }); + } + } + + private static void constructTestUI() { + frame1 = new Frame(); + frame1.setBounds(100, 100, 100, 100); + frame1.addMouseMotionListener(new MouseMotionAdapter() { + + private boolean shown = false; + + @Override + public void mouseMoved(MouseEvent e) { + if (shown) { + return; + } + + shown = true; + + frame2 = new Frame(); + frame2.setBounds(120, 120, 120, 120); + frame2.setVisible(true); + + Point positionInFrame2 = frame2.getMousePosition(); + if (positionInFrame2.x != 30 || positionInFrame2.y != 30) { + throw new RuntimeException("Wrong position reported. Should be [30, 30] but was [" + + positionInFrame2.x + ", " + positionInFrame2.y + "]"); + } + + Point positionInFrame1 = frame1.getMousePosition(); + if (positionInFrame1 != null) { + throw new RuntimeException("Wrong position reported. Should be null"); + } + + } + }); + frame1.setVisible(true); + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/io/Serializable/unresolvableObjectStreamClass/UnresolvableObjectStreamClass.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,68 @@ +/* + * 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 8039396 + * @run main UnresolvableObjectStreamClass serialize + * @clean MySerializable + * @run main UnresolvableObjectStreamClass deserialize + * + * @summary NPE when writing a class descriptor object to a custom + * ObjectOutputStream + */ + +import java.io.*; + +public class UnresolvableObjectStreamClass { + public static void main(String[] args) throws Throwable { + if (args.length > 0 && args[0].equals("serialize")) { + try (FileOutputStream fos = new FileOutputStream("temp1.ser"); + ObjectOutputStream oos = new ObjectOutputStream(fos)) { + ObjectStreamClass osc = + ObjectStreamClass.lookup(MySerializable.class); + oos.writeObject(osc); + } + } else if (args.length > 0 && args[0].equals("deserialize")) { + try (FileInputStream fis = new FileInputStream("temp1.ser"); + ObjectInputStream ois = new ObjectInputStream(fis); + FileOutputStream fos = new FileOutputStream("temp2.ser"); + ObjectOutputStream oos = new ObjectOutputStream(fos) { + /*must be subclassed*/}) { + ObjectStreamClass osc = (ObjectStreamClass)ois.readObject(); + // serialize it again + try { + oos.writeObject(osc); + } catch (NullPointerException e) { + throw new RuntimeException("Failed to write" + + " unresolvable ObjectStreamClass", e); + } + } + } else { + throw new RuntimeException("The command line option must be" + + " one of: serialize or deserialize"); + } + } +} + +class MySerializable implements Serializable { +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7122142 + * @summary Test deadlock situation when recursive annotations are parsed + */ + +import java.lang.annotation.Retention; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +public class AnnotationTypeDeadlockTest { + + @Retention(RUNTIME) + @AnnB + public @interface AnnA { + } + + @Retention(RUNTIME) + @AnnA + public @interface AnnB { + } + + static class Task extends Thread { + final CountDownLatch prepareLatch; + final AtomicInteger goLatch; + final Class clazz; + + Task(CountDownLatch prepareLatch, AtomicInteger goLatch, Class clazz) { + super(clazz.getSimpleName()); + setDaemon(true); // in case it deadlocks + this.prepareLatch = prepareLatch; + this.goLatch = goLatch; + this.clazz = clazz; + } + + @Override + public void run() { + prepareLatch.countDown(); // notify we are prepared + while (goLatch.get() > 0); // spin-wait before go + clazz.getDeclaredAnnotations(); + } + } + + public static void main(String[] args) throws Exception { + CountDownLatch prepareLatch = new CountDownLatch(2); + AtomicInteger goLatch = new AtomicInteger(1); + Task taskA = new Task(prepareLatch, goLatch, AnnA.class); + Task taskB = new Task(prepareLatch, goLatch, AnnB.class); + taskA.start(); + taskB.start(); + // wait until both threads start-up + prepareLatch.await(); + // let them go + goLatch.set(0); + // obtain ThreadMXBean + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + // wait for threads to finish or dead-lock + while (taskA.isAlive() || taskB.isAlive()) { + // attempt to join threads + taskA.join(500L); + taskB.join(500L); + // detect dead-lock + long[] deadlockedIds = threadBean.findMonitorDeadlockedThreads(); + if (deadlockedIds != null && deadlockedIds.length > 0) { + StringBuilder sb = new StringBuilder("deadlock detected:\n\n"); + for (ThreadInfo ti : threadBean.getThreadInfo(deadlockedIds, Integer.MAX_VALUE)) { + sb.append(ti); + } + throw new IllegalStateException(sb.toString()); + } + } + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 7122142 + * @summary Test consistent parsing of ex-RUNTIME annotations that + * were changed and separately compiled to have CLASS retention + */ + +import sun.misc.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import static java.lang.annotation.RetentionPolicy.CLASS; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * This test simulates a situation where there are two mutually recursive + * {@link RetentionPolicy#RUNTIME RUNTIME} annotations {@link AnnA_v1 AnnA_v1} + * and {@link AnnB AnnB} and then the first is changed to have + * {@link RetentionPolicy#CLASS CLASS} retention and separately compiled. + * When {@link AnnA_v1 AnnA_v1} annotation is looked-up on {@link AnnB AnnB} + * it still appears to have {@link RetentionPolicy#RUNTIME RUNTIME} retention. + */ +public class AnnotationTypeRuntimeAssumptionTest { + + @Retention(RUNTIME) + @AnnB + public @interface AnnA_v1 { + } + + // An alternative version of AnnA_v1 with CLASS retention instead. + // Used to simulate separate compilation (see AltClassLoader below). + @Retention(CLASS) + @AnnB + public @interface AnnA_v2 { + } + + @Retention(RUNTIME) + @AnnA_v1 + public @interface AnnB { + } + + @AnnA_v1 + public static class TestTask implements Runnable { + @Override + public void run() { + AnnA_v1 ann1 = getDeclaredAnnotation(TestTask.class, AnnA_v1.class); + if (ann1 != null) { + throw new IllegalStateException( + "@" + ann1.annotationType().getSimpleName() + + " found on: " + TestTask.class.getName() + + " should not be visible at runtime"); + } + AnnA_v1 ann2 = getDeclaredAnnotation(AnnB.class, AnnA_v1.class); + if (ann2 != null) { + throw new IllegalStateException( + "@" + ann2.annotationType().getSimpleName() + + " found on: " + AnnB.class.getName() + + " should not be visible at runtime"); + } + } + + private static A getDeclaredAnnotation(Class clazz, Class annotationClass) { + for (Annotation ann : clazz.getDeclaredAnnotations()) { + if (ann.annotationType() == annotationClass) { + return annotationClass.cast(ann); + } + } + return null; + } + } + + public static void main(String[] args) throws Exception { + ClassLoader altLoader = new AltClassLoader( + AnnotationTypeRuntimeAssumptionTest.class.getClassLoader()); + + Runnable altTask = (Runnable) Class.forName( + TestTask.class.getName(), + true, + altLoader).newInstance(); + + altTask.run(); + } + + /** + * A ClassLoader implementation that loads alternative implementations of + * classes. If class name ends with "_v1" it locates instead a class with + * name ending with "_v2" and loads that class instead. + */ + static class AltClassLoader extends ClassLoader { + AltClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + protected Class loadClass(String name, boolean resolve) + throws ClassNotFoundException { + if (name.indexOf('.') < 0) { // root package is our class + synchronized (getClassLoadingLock(name)) { + // First, check if the class has already been loaded + Class c = findLoadedClass(name); + if (c == null) { + c = findClass(name); + } + if (resolve) { + resolveClass(c); + } + return c; + } + } + else { // not our class + return super.loadClass(name, resolve); + } + } + + @Override + protected Class findClass(String name) + throws ClassNotFoundException { + // special class name -> replace it with alternative name + if (name.endsWith("_v1")) { + String altName = name.substring(0, name.length() - 3) + "_v2"; + String altPath = altName.replace('.', '/').concat(".class"); + try (InputStream is = getResourceAsStream(altPath)) { + if (is != null) { + byte[] bytes = IOUtils.readFully(is, -1, true); + // patch class bytes to contain original name + for (int i = 0; i < bytes.length - 2; i++) { + if (bytes[i] == '_' && + bytes[i + 1] == 'v' && + bytes[i + 2] == '2') { + bytes[i + 2] = '1'; + } + } + return defineClass(name, bytes, 0, bytes.length); + } + else { + throw new ClassNotFoundException(name); + } + } + catch (IOException e) { + throw new ClassNotFoundException(name, e); + } + } + else { // not special class name -> just load the class + String path = name.replace('.', '/').concat(".class"); + try (InputStream is = getResourceAsStream(path)) { + if (is != null) { + byte[] bytes = IOUtils.readFully(is, -1, true); + return defineClass(name, bytes, 0, bytes.length); + } + else { + throw new ClassNotFoundException(name); + } + } + catch (IOException e) { + throw new ClassNotFoundException(name, e); + } + } + } + } +} --- ./jdk/test/java/lang/invoke/JavaDocExamplesTest.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/lang/invoke/JavaDocExamplesTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -64,7 +64,11 @@ new JavaDocExamplesTest().run(); } public void run() throws Throwable { + testMisc(); + testFindStatic(); + testFindConstructor(); testFindVirtual(); + testFindSpecial(); testPermuteArguments(); testDropArguments(); testFilterArguments(); @@ -110,7 +114,8 @@ {} - @Test public void testFindVirtual() throws Throwable { + @Test public void testMisc() throws Throwable { +// Extra tests, not from javadoc: {} MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class, "concat", methodType(String.class, String.class)); @@ -125,6 +130,92 @@ {} } + @Test public void testFindStatic() throws Throwable { +{} +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, + "asList", methodType(List.class, Object[].class)); +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); +{} + } + + @Test public void testFindVirtual() throws Throwable { +{} +MethodHandle MH_concat = publicLookup().findVirtual(String.class, + "concat", methodType(String.class, String.class)); +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, + "hashCode", methodType(int.class)); +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, + "hashCode", methodType(int.class)); +assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); +// interface method: +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, + "subSequence", methodType(CharSequence.class, int.class, int.class)); +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); +// constructor "internal method" must be accessed differently: +MethodType MT_newString = methodType(void.class); //()V for new String() +try { assertEquals("impossible", lookup() + .findVirtual(String.class, "", MT_newString)); + } catch (NoSuchMethodException ex) { } // OK +MethodHandle MH_newString = publicLookup() + .findConstructor(String.class, MT_newString); +assertEquals("", (String) MH_newString.invokeExact()); +{} + } + + @Test public void testFindConstructor() throws Throwable { +{} +MethodHandle MH_newArrayList = publicLookup().findConstructor( + ArrayList.class, methodType(void.class, Collection.class)); +Collection orig = Arrays.asList("x", "y"); +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); +assert(orig != copy); +assertEquals(orig, copy); +// a variable-arity constructor: +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( + ProcessBuilder.class, methodType(void.class, String[].class)); +ProcessBuilder pb = (ProcessBuilder) + MH_newProcessBuilder.invoke("x", "y", "z"); +assertEquals("[x, y, z]", pb.command().toString()); +{} + } + +// for testFindSpecial +{} +static class Listie extends ArrayList { + public String toString() { return "[wee Listie]"; } + static Lookup lookup() { return MethodHandles.lookup(); } +} +{} + + @Test public void testFindSpecial() throws Throwable { +{} +// no access to constructor via invokeSpecial: +MethodHandle MH_newListie = Listie.lookup() + .findConstructor(Listie.class, methodType(void.class)); +Listie l = (Listie) MH_newListie.invokeExact(); +try { assertEquals("impossible", Listie.lookup().findSpecial( + Listie.class, "", methodType(void.class), Listie.class)); + } catch (NoSuchMethodException ex) { } // OK +// access to super and self methods via invokeSpecial: +MethodHandle MH_super = Listie.lookup().findSpecial( + ArrayList.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_this = Listie.lookup().findSpecial( + Listie.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_duper = Listie.lookup().findSpecial( + Object.class, "toString" , methodType(String.class), Listie.class); +assertEquals("[]", (String) MH_super.invokeExact(l)); +assertEquals(""+l, (String) MH_this.invokeExact(l)); +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method +try { assertEquals("inaccessible", Listie.lookup().findSpecial( + String.class, "toString", methodType(String.class), Listie.class)); + } catch (IllegalAccessException ex) { } // OK +Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method +{} + } + @Test public void testPermuteArguments() throws Throwable { {{ {} /// JAVADOC @@ -275,6 +366,12 @@ MethodHandle eq2 = equals.asSpreader(Object[].class, 2); assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" })); assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" })); +// try to spread from anything but a 2-array: +for (int n = 0; n <= 10; n++) { + Object[] badArityArgs = (n == 2 ? null : new Object[n]); + try { assert((boolean) eq2.invokeExact(badArityArgs) && false); } + catch (IllegalArgumentException ex) { } // OK +} // spread both arguments from a String array: MethodHandle eq2s = equals.asSpreader(String[].class, 2); assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" })); --- ./jdk/test/java/lang/invoke/MethodHandlesTest.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/lang/invoke/MethodHandlesTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -363,6 +363,7 @@ protected Example(String name) { this.name = name; } @SuppressWarnings("LeakingThisInConstructor") protected Example(int x) { this(); called("protected ", this, x); } + //Example(Void x) { does not exist; lookup elicts NoSuchMethodException } @Override public String toString() { return name; } public void v0() { called("v0", this); } @@ -463,6 +464,9 @@ return lookup.in(defc); } + /** Is findVirtual (etc.) of "" supposed to elicit a NoSuchMethodException? */ + final static boolean INIT_REF_CAUSES_NSME = true; + @Test public void testFindStatic() throws Throwable { if (CAN_SKIP_WORKING) return; @@ -483,6 +487,8 @@ testFindStatic(Example.class, Object.class, "s7", float.class, double.class); testFindStatic(false, PRIVATE, Example.class, void.class, "bogus"); + testFindStatic(false, PRIVATE, Example.class, void.class, "", int.class); + testFindStatic(false, PRIVATE, Example.class, void.class, "", Void.class); testFindStatic(false, PRIVATE, Example.class, void.class, "v0"); } @@ -505,11 +511,12 @@ target = maybeMoveIn(lookup, defc).findStatic(defc, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findStatic "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target @@ -527,6 +534,13 @@ System.out.print(':'); } + static void assertExceptionClass(Class expected, + Throwable actual) { + if (expected.isInstance(actual)) return; + actual.printStackTrace(); + assertEquals(expected, actual.getClass()); + } + static final boolean DEBUG_METHOD_HANDLE_NAMES = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); // rough check of name string @@ -556,6 +570,8 @@ testFindVirtual(PubExample.class, void.class, "Pub/pro_v0"); testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus"); + testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "", int.class); + testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "", Void.class); testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "s0"); // test dispatch @@ -591,11 +607,12 @@ target = maybeMoveIn(lookup, defc).findVirtual(defc, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findVirtual "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target @@ -632,11 +649,11 @@ testFindSpecial(SubExample.class, Example.class, void.class, "pkg_v0"); testFindSpecial(RemoteExample.class, PubExample.class, void.class, "Pub/pro_v0"); // Do some negative testing: - testFindSpecial(false, EXAMPLE, SubExample.class, Example.class, void.class, "bogus"); - testFindSpecial(false, PRIVATE, SubExample.class, Example.class, void.class, "bogus"); for (Lookup lookup : new Lookup[]{ PRIVATE, EXAMPLE, PACKAGE, PUBLIC }) { testFindSpecial(false, lookup, Object.class, Example.class, void.class, "v0"); + testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "bogus"); testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "", int.class); + testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "", Void.class); testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "s0"); } } @@ -662,19 +679,25 @@ countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo MethodType type = MethodType.methodType(ret, params); + Lookup specialLookup = maybeMoveIn(lookup, specialCaller); + boolean specialAccessOK = (specialLookup.lookupClass() == specialCaller && + (specialLookup.lookupModes() & Lookup.PRIVATE) != 0); MethodHandle target = null; Exception noAccess = null; try { if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type); - if (verbosity >= 5) System.out.println(" lookup => "+maybeMoveIn(lookup, specialCaller)); - target = maybeMoveIn(lookup, specialCaller).findSpecial(defc, methodName, type, specialCaller); + if (verbosity >= 5) System.out.println(" lookup => "+specialLookup); + target = specialLookup.findSpecial(defc, methodName, type, specialCaller); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (!specialAccessOK) // this check should happen first + ? IllegalAccessException.class + : (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target @@ -719,7 +742,7 @@ target = lookup.findConstructor(defc, type); } catch (ReflectiveOperationException ex) { noAccess = ex; - assertTrue(noAccess instanceof IllegalAccessException); + assertTrue(noAccess.getClass().getName(), noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findConstructor "+defc.getName()+"./"+type+" => "+target @@ -750,6 +773,8 @@ testBind(Example.class, Object.class, "v2", int.class, Object.class); testBind(Example.class, Object.class, "v2", int.class, int.class); testBind(false, PRIVATE, Example.class, void.class, "bogus"); + testBind(false, PRIVATE, Example.class, void.class, "", int.class); + testBind(false, PRIVATE, Example.class, void.class, "", Void.class); testBind(SubExample.class, void.class, "Sub/v0"); testBind(SubExample.class, void.class, "Sub/pkg_v0"); testBind(IntExample.Impl.class, void.class, "Int/v0"); @@ -773,11 +798,12 @@ target = maybeMoveIn(lookup, defc).bind(receiver, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("bind "+receiver+"."+name+"/"+type+" => "+target @@ -840,6 +866,10 @@ countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo MethodType type = MethodType.methodType(ret, params); + Lookup specialLookup = (specialCaller != null ? maybeMoveIn(lookup, specialCaller) : null); + boolean specialAccessOK = (specialCaller != null && + specialLookup.lookupClass() == specialCaller && + (specialLookup.lookupModes() & Lookup.PRIVATE) != 0); Method rmethod = defc.getDeclaredMethod(methodName, params); MethodHandle target = null; Exception noAccess = null; @@ -848,16 +878,15 @@ try { if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type); if (isSpecial) - target = maybeMoveIn(lookup, specialCaller).unreflectSpecial(rmethod, specialCaller); + target = specialLookup.unreflectSpecial(rmethod, specialCaller); else target = maybeMoveIn(lookup, defc).unreflect(rmethod); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + IllegalAccessException.class, // NSME is impossible, since it was already reflected + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("unreflect"+(isSpecial?"Special":"")+" "+defc.getName()+"."+name+"/"+type @@ -1091,11 +1120,12 @@ } catch (ReflectiveOperationException ex) { mh = null; noAccess = ex; + assertExceptionClass( + (fname.contains("bogus")) + ? NoSuchFieldException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (fname.contains("bogus")) - assertTrue(noAccess instanceof NoSuchFieldException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/lang/invoke/ProtectedMemberDifferentPackage/Test.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,33 @@ +/* + * 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 8032585 8033278 + * @summary JSR292: IllegalAccessError when attempting to invoke protected method from different package + * + * @compile p1/T2.java p2/T3.java + * @run main/othervm p2.T3 + */ +public class Test {} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/lang/invoke/ProtectedMemberDifferentPackage/p1/T2.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,127 @@ +/* + * 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 p1; + +import p2.T3; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.util.concurrent.Callable; + +class T1 { + protected void m1() {} + protected static void m2() {} +} + +public class T2 extends T1 { + public static void main(String[] args) throws Throwable { + final Lookup LOOKUP = T3.lookup(); + Class IAE = IllegalAccessException.class; + + assertFailure(IAE, new Callable() { + public Integer call() throws Exception { + LOOKUP.findVirtual(T1.class, "m1", MethodType.methodType(void.class)); + return null; + } + } + ); + assertFailure(IAE, new Callable() { + public Integer call() throws Exception { + LOOKUP.findStatic(T1.class, "m2", MethodType.methodType(void.class)); + return null; + } + } + ); + + assertSuccess(new Callable() { + public Integer call() throws Exception { + LOOKUP.findVirtual(T2.class, "m1", MethodType.methodType(void.class)); + return null; + } + } + ); + assertSuccess(new Callable() { + public Integer call() throws Exception { + LOOKUP.findVirtual(T3.class, "m1", MethodType.methodType(void.class)); + return null; + } + } + ); + + assertSuccess(new Callable() { + public Integer call() throws Exception { + LOOKUP.findStatic(T2.class, "m2", MethodType.methodType(void.class)); + return null; + } + } + ); + assertSuccess(new Callable() { + public Integer call() throws Exception { + LOOKUP.findStatic(T3.class, "m2", MethodType.methodType(void.class)); + return null; + } + } + ); + + assertFailure(IAE, new Callable() { + public Integer call() throws Exception { + LOOKUP.unreflect(T1.class.getDeclaredMethod("m1")); + return null; + } + } + ); + assertFailure(IAE, new Callable() { + public Integer call() throws Exception { + LOOKUP.unreflect(T1.class.getDeclaredMethod("m2")); + return null; + } + } + ); + + System.out.println("TEST PASSED"); + } + + public static void assertFailure(Class expectedError, Callable r) { + try { + r.call(); + } catch(Throwable e) { + if (expectedError.isAssignableFrom(e.getClass())) { + return; // expected error + } else { + throw new Error("Unexpected error type: "+e.getClass()+"; expected type: "+expectedError, e); + } + } + throw new Error("No error"); + } + + public static void assertSuccess(Callable r) { + try { + r.call(); + } catch(Throwable e) { + throw new Error("Unexpected error", e); + } + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/java/lang/invoke/ProtectedMemberDifferentPackage/p2/T3.java Wed Apr 16 12:37:49 2014 +0400 @@ -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. + * + */ +package p2; + +import p1.T2; + +import java.lang.invoke.MethodHandles; + +public class T3 extends T2 { + public static MethodHandles.Lookup lookup() { return MethodHandles.lookup(); } +} --- ./jdk/test/java/nio/channels/Selector/ByteServer.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/nio/channels/Selector/ByteServer.java Wed Apr 16 12:37:49 2014 +0400 @@ -22,52 +22,54 @@ */ /** - * - * Utility class for tests. A simple server, which waits for a connection, - * writes out n bytes and waits. + * Utility class for tests. A simple "in-thread" server to accept connections + * and write bytes. * @author kladko */ import java.net.Socket; import java.net.ServerSocket; +import java.net.SocketAddress; +import java.net.InetSocketAddress; +import java.io.IOException; +import java.io.Closeable; -public class ByteServer { +public class ByteServer implements Closeable { - public static final String LOCALHOST = "localhost"; - private int bytecount; - private Socket socket; - private ServerSocket serversocket; - private Thread serverthread; - volatile Exception savedException; + private final ServerSocket ss; + private Socket s; - public ByteServer(int bytecount) throws Exception{ - this.bytecount = bytecount; - serversocket = new ServerSocket(0); + ByteServer() throws IOException { + this.ss = new ServerSocket(0); } - public int port() { - return serversocket.getLocalPort(); + SocketAddress address() { + return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort()); } - public void start() { - serverthread = new Thread() { - public void run() { - try { - socket = serversocket.accept(); - socket.getOutputStream().write(new byte[bytecount]); - socket.getOutputStream().flush(); - } catch (Exception e) { - System.err.println("Exception in ByteServer: " + e); - System.exit(1); - } - } - }; - serverthread.start(); + void acceptConnection() throws IOException { + if (s != null) + throw new IllegalStateException("already connected"); + this.s = ss.accept(); } - public void exit() throws Exception { - serverthread.join(); - socket.close(); - serversocket.close(); + void closeConnection() throws IOException { + Socket s = this.s; + if (s != null) { + this.s = null; + s.close(); + } + } + + void write(int count) throws IOException { + if (s == null) + throw new IllegalStateException("no connection"); + s.getOutputStream().write(new byte[count]); + } + + public void close() throws IOException { + if (s != null) + s.close(); + ss.close(); } } --- ./jdk/test/java/nio/channels/Selector/ReadAfterConnect.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/nio/channels/Selector/ReadAfterConnect.java Wed Apr 16 12:37:49 2014 +0400 @@ -27,27 +27,25 @@ * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class ReadAfterConnect { + public static void main(String[] argv) throws Exception { + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { - public static void main(String[] argv) throws Exception { - ByteServer server = new ByteServer(0); // server: accept connection and do nothing - server.start(); - InetSocketAddress isa = new InetSocketAddress( - InetAddress.getByName(ByteServer.LOCALHOST), server.port()); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(isa); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_READ); - // Previously channel would get selected here, although there is nothing to read - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - server.exit(); + server.acceptConnection(); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + // Previously channel would get selected here, although there is nothing to read + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } } } --- ./jdk/test/java/nio/channels/Selector/SelectAfterRead.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/nio/channels/Selector/SelectAfterRead.java Wed Apr 16 12:37:49 2014 +0400 @@ -28,60 +28,62 @@ * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.nio.ByteBuffer; +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class SelectAfterRead { - final static int TIMEOUT = 1000; + private static final int TIMEOUT = 1000; public static void main(String[] argv) throws Exception { - InetAddress lh = InetAddress.getByName(ByteServer.LOCALHOST); // server: accept connection and write one byte - ByteServer server = new ByteServer(1); - server.start(); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(new InetSocketAddress(lh, server.port())); - sc.read(ByteBuffer.allocate(1)); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_READ); - // previously on Windows select would select channel here, although there was - // nothing to read - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - sel.close(); - server.exit(); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + server.write(1); + + try (Selector sel = Selector.open()) { + sc.read(ByteBuffer.allocate(1)); + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + // previously on Windows select would select channel here, although there was + // nothing to read + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } // Now we will test a two reads combination // server: accept connection and write two bytes - server = new ByteServer(2); - server.start(); - sc = SocketChannel.open(); - sc.connect(new InetSocketAddress(lh, server.port())); - sc.configureBlocking(false); - sel = Selector.open(); - sc.register(sel, SelectionKey.OP_READ); - if (sel.select(TIMEOUT) != 1) - throw new Exception("One selected key expected"); - sel.selectedKeys().clear(); - // previously on Windows a channel would get selected only once - if (sel.selectNow() != 1) - throw new Exception("One selected key expected"); - // Previously on Windows two consequent reads would cause select() - // to select a channel, although there was nothing remaining to - // read in the channel - if (sc.read(ByteBuffer.allocate(1)) != 1) - throw new Exception("One byte expected"); - if (sc.read(ByteBuffer.allocate(1)) != 1) - throw new Exception("One byte expected"); - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - sel.close(); - server.exit(); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + server.write(2); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + if (sel.select(TIMEOUT) != 1) + throw new Exception("One selected key expected"); + sel.selectedKeys().clear(); + // previously on Windows a channel would get selected only once + if (sel.selectNow() != 1) + throw new Exception("One selected key expected"); + // Previously on Windows two consequent reads would cause select() + // to select a channel, although there was nothing remaining to + // read in the channel + if (sc.read(ByteBuffer.allocate(1)) != 1) + throw new Exception("One byte expected"); + if (sc.read(ByteBuffer.allocate(1)) != 1) + throw new Exception("One byte expected"); + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } } } --- ./jdk/test/java/nio/channels/Selector/SelectWrite.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/java/nio/channels/Selector/SelectWrite.java Wed Apr 16 12:37:49 2014 +0400 @@ -22,36 +22,33 @@ */ /* @test - @bug 4645302 - @summary Socket with OP_WRITE would get selected only once - @author kladko + * @bug 4645302 + * @summary Socket with OP_WRITE would get selected only once + * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; - +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class SelectWrite { public static void main(String[] argv) throws Exception { - ByteServer server = new ByteServer(0); - // server: accept connection and do nothing - server.start(); - InetSocketAddress isa = new InetSocketAddress( - InetAddress.getByName(ByteServer.LOCALHOST), server.port()); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(isa); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_WRITE); - sel.select(); - sel.selectedKeys().clear(); - if (sel.select() == 0) { - throw new Exception("Select returned zero"); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_WRITE); + sel.select(); + sel.selectedKeys().clear(); + if (sel.select() == 0) { + throw new Exception("Select returned zero"); + } + } } - sc.close(); - sel.close(); } } --- ./jdk/test/javax/management/remote/mandatory/util/CacheMapTest.java Wed May 07 19:26:47 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2003, 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 7654321 - * @summary Tests the CacheMap class. - * @author Eamonn McManus - * @run clean CacheMapTest - * @run build CacheMapTest - * @run main CacheMapTest - */ - -import java.util.Iterator; -import java.util.Map; - -import com.sun.jmx.remote.util.CacheMap; - -public class CacheMapTest { - public static void main(String[] args) { - try { - boolean ok = test(5) && test(100); - if (ok) { - System.out.println("Test completed"); - return; - } else { - System.out.println("Test failed!"); - System.exit(1); - } - } catch (Exception e) { - System.err.println("Unexpected exception: " + e); - e.printStackTrace(); - System.exit(1); - } - } - - private static boolean test(int cacheSize) throws Exception { - System.out.println("CacheMap test with cache size " + cacheSize); - CacheMap map = new CacheMap(cacheSize); - int size = 0; - int maxIterations = cacheSize * 10; - while (map.size() == size && size < maxIterations) { - Integer key = new Integer(size); - Object x = map.put(key, "x"); - if (x != null) { - System.out.println("Map already had entry " + key + "!"); - return false; - } - x = map.get(key); - if (!"x".equals(x)) { - System.out.println("Got back surprising value: " + x); - return false; - } - size++; - } - System.out.println("Map size is " + map.size() + " after inserting " + - size + " elements"); - do { - System.gc(); - Thread.sleep(1); - System.out.println("Map size is " + map.size() + " after GC"); - } while (map.size() > cacheSize); - if (map.size() < cacheSize) { - System.out.println("Map shrank to less than cache size: " + - map.size() + " (surprising but not wrong)"); - } else - System.out.println("Map shrank to cache size as expected"); - int lowest = size - cacheSize; - // lowest value that can still be in cache if LRU is respected - for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry) it.next(); - Integer x = (Integer) entry.getKey(); - int xx = x.intValue(); - if (xx < lowest || xx >= size) { - System.out.println("Old value remained (" + x + "), " + - "expected none earlier than " + lowest); - return false; - } - Object xxx = entry.getValue(); - if (!"x".equals(xxx)) { - System.out.println("Got back surprising value: " + xxx); - return false; - } - } - if (map.size() > 0) - System.out.println("Remaining elements are the most recent ones"); - System.out.println("Test passed"); - return true; - } -} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/AssertsTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,237 @@ +/* + * 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. + */ + +import static jdk.testlibrary.Asserts.*; + +/* @test + * @summary Tests the different assertions in the Assert class + * @library /testlibrary + */ +public class AssertsTest { + private static class Foo implements Comparable { + final int id; + public Foo(int id) { + this.id = id; + } + + public int compareTo(Foo f) { + return new Integer(id).compareTo(new Integer(f.id)); + } + } + + public static void main(String[] args) throws Exception { + testLessThan(); + testLessThanOrEqual(); + testEquals(); + testGreaterThanOrEqual(); + testGreaterThan(); + testNotEquals(); + testNull(); + testNotNull(); + testTrue(); + testFalse(); + } + + private static void testLessThan() throws Exception { + expectPass(Assertion.LT, 1, 2); + + expectFail(Assertion.LT, 2, 2); + expectFail(Assertion.LT, 2, 1); + expectFail(Assertion.LT, null, 2); + expectFail(Assertion.LT, 2, null); + } + + private static void testLessThanOrEqual() throws Exception { + expectPass(Assertion.LTE, 1, 2); + expectPass(Assertion.LTE, 2, 2); + + expectFail(Assertion.LTE, 3, 2); + expectFail(Assertion.LTE, null, 2); + expectFail(Assertion.LTE, 2, null); + } + + private static void testEquals() throws Exception { + expectPass(Assertion.EQ, 1, 1); + expectPass(Assertion.EQ, null, null); + + Foo f1 = new Foo(1); + expectPass(Assertion.EQ, f1, f1); + + Foo f2 = new Foo(1); + expectFail(Assertion.EQ, f1, f2); + expectFail(Assertion.LTE, null, 2); + expectFail(Assertion.LTE, 2, null); + } + + private static void testGreaterThanOrEqual() throws Exception { + expectPass(Assertion.GTE, 1, 1); + expectPass(Assertion.GTE, 2, 1); + + expectFail(Assertion.GTE, 1, 2); + expectFail(Assertion.GTE, null, 2); + expectFail(Assertion.GTE, 2, null); + } + + private static void testGreaterThan() throws Exception { + expectPass(Assertion.GT, 2, 1); + + expectFail(Assertion.GT, 1, 1); + expectFail(Assertion.GT, 1, 2); + expectFail(Assertion.GT, null, 2); + expectFail(Assertion.GT, 2, null); + } + + private static void testNotEquals() throws Exception { + expectPass(Assertion.NE, null, 1); + expectPass(Assertion.NE, 1, null); + + Foo f1 = new Foo(1); + Foo f2 = new Foo(1); + expectPass(Assertion.NE, f1, f2); + + expectFail(Assertion.NE, null, null); + expectFail(Assertion.NE, f1, f1); + expectFail(Assertion.NE, 1, 1); + } + + private static void testNull() throws Exception { + expectPass(Assertion.NULL, null); + + expectFail(Assertion.NULL, 1); + } + + private static void testNotNull() throws Exception { + expectPass(Assertion.NOTNULL, 1); + + expectFail(Assertion.NOTNULL, null); + } + + private static void testTrue() throws Exception { + expectPass(Assertion.TRUE, true); + + expectFail(Assertion.TRUE, false); + } + + private static void testFalse() throws Exception { + expectPass(Assertion.FALSE, false); + + expectFail(Assertion.FALSE, true); + } + + private static > void expectPass(Assertion assertion, T ... args) + throws Exception { + Assertion.run(assertion, args); + } + + private static > void expectFail(Assertion assertion, T ... args) + throws Exception { + try { + Assertion.run(assertion, args); + } catch (RuntimeException e) { + return; + } + throw new Exception("Expected " + Assertion.format(assertion, (Object[]) args) + + " to throw a RuntimeException"); + } + +} + +enum Assertion { + LT, LTE, EQ, GTE, GT, NE, NULL, NOTNULL, FALSE, TRUE; + + public static > void run(Assertion assertion, T ... args) { + String msg = "Expected " + format(assertion, args) + " to pass"; + switch (assertion) { + case LT: + assertLessThan(args[0], args[1], msg); + break; + case LTE: + assertLessThanOrEqual(args[0], args[1], msg); + break; + case EQ: + assertEquals(args[0], args[1], msg); + break; + case GTE: + assertGreaterThanOrEqual(args[0], args[1], msg); + break; + case GT: + assertGreaterThan(args[0], args[1], msg); + break; + case NE: + assertNotEquals(args[0], args[1], msg); + break; + case NULL: + assertNull(args == null ? args : args[0], msg); + break; + case NOTNULL: + assertNotNull(args == null ? args : args[0], msg); + break; + case FALSE: + assertFalse((Boolean) args[0], msg); + break; + case TRUE: + assertTrue((Boolean) args[0], msg); + break; + default: + // do nothing + } + } + + public static String format(Assertion assertion, Object ... args) { + switch (assertion) { + case LT: + return asString("assertLessThan", args); + case LTE: + return asString("assertLessThanOrEqual", args); + case EQ: + return asString("assertEquals", args); + case GTE: + return asString("assertGreaterThanOrEquals", args); + case GT: + return asString("assertGreaterThan", args); + case NE: + return asString("assertNotEquals", args); + case NULL: + return asString("assertNull", args); + case NOTNULL: + return asString("assertNotNull", args); + case FALSE: + return asString("assertFalse", args); + case TRUE: + return asString("assertTrue", args); + default: + return ""; + } + } + + private static String asString(String assertion, Object ... args) { + if (args == null) { + return String.format("%s(null)", assertion); + } + if (args.length == 1) { + return String.format("%s(%s)", assertion, args[0]); + } else { + return String.format("%s(%s, %s)", assertion, args[0], args[1]); + } + } +} --- ./jdk/test/lib/testlibrary/ClassFileInstaller.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/lib/testlibrary/ClassFileInstaller.java Wed Apr 16 12:37:49 2014 +0400 @@ -45,7 +45,10 @@ // Create the class file's package directory Path p = Paths.get(pathName); - Files.createDirectories(p.getParent()); + Path parent = p.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } // Create the class file Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/OutputAnalyzerReportingTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,122 @@ +/* + * 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 + * @summary Test the OutputAnalyzer reporting functionality, + * such as printing additional diagnostic info + * (exit code, stdout, stderr, command line, etc.) + * @library /testlibrary + */ + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import jdk.testlibrary.OutputAnalyzer; + +public class OutputAnalyzerReportingTest { + + public static void main(String[] args) throws Exception { + // Create the output analyzer under test + String stdout = "aaaaaa"; + String stderr = "bbbbbb"; + OutputAnalyzer output = new OutputAnalyzer(stdout, stderr); + + // Expected summary values should be the same for all cases, + // since the outputAnalyzer object is the same + String expectedExitValue = "-1"; + String expectedSummary = + " stdout: [" + stdout + "];\n" + + " stderr: [" + stderr + "]\n" + + " exitValue = " + expectedExitValue + "\n"; + + + DiagnosticSummaryTestRunner testRunner = + new DiagnosticSummaryTestRunner(); + + // should have exit value + testRunner.init(expectedSummary); + int unexpectedExitValue = 2; + try { + output.shouldHaveExitValue(unexpectedExitValue); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should not contain + testRunner.init(expectedSummary); + try { + output.shouldNotContain(stdout); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should contain + testRunner.init(expectedSummary); + try { + output.shouldContain("unexpected-stuff"); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should not match + testRunner.init(expectedSummary); + try { + output.shouldNotMatch("[a]"); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should match + testRunner.init(expectedSummary); + try { + output.shouldMatch("[qwerty]"); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + } + + private static class DiagnosticSummaryTestRunner { + private ByteArrayOutputStream byteStream = + new ByteArrayOutputStream(10000); + + private String expectedSummary = ""; + private PrintStream errStream; + + + public void init(String expectedSummary) { + this.expectedSummary = expectedSummary; + byteStream.reset(); + errStream = new PrintStream(byteStream); + System.setErr(errStream); + } + + public void closeAndCheckResults() { + // check results + errStream.close(); + String stdErrStr = byteStream.toString(); + if (!stdErrStr.contains(expectedSummary)) { + throw new RuntimeException("The output does not contain " + + "the diagnostic message, or the message is incorrect"); + } + } + } + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Asserts.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,395 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +/** + * Asserts that can be used for verifying assumptions in tests. + * + * An assertion will throw a {@link RuntimeException} if the assertion isn't + * valid. All the asserts can be imported into a test by using a static + * import: + * + *

+ * {@code
+ * import static com.oracle.java.testlibrary.Asserts.*;
+ * }
+ *
+ * Always provide a message describing the assumption if the line number of the
+ * failing assertion isn't enough to understand why the assumption failed. For
+ * example, if the assertion is in a loop or in a method that is called
+ * multiple times, then the line number won't provide enough context to
+ * understand the failure.
+ * 
+ */ +public class Asserts { + + /** + * Shorthand for {@link #assertLessThan(T, T)}. + * + * @see #assertLessThan(T, T) + */ + public static > void assertLT(T lhs, T rhs) { + assertLessThan(lhs, rhs); + } + + /** + * Shorthand for {@link #assertLessThan(T, T, String)}. + * + * @see #assertLessThan(T, T, String) + */ + public static > void assertLT(T lhs, T rhs, String msg) { + assertLessThan(lhs, rhs, msg); + } + + /** + * Calls {@link #assertLessThan(T, T, String)} with a default message. + * + * @see #assertLessThan(T, T, String) + */ + public static > void assertLessThan(T lhs, T rhs) { + String msg = "Expected that " + format(lhs) + " < " + format(rhs); + assertLessThan(lhs, rhs, msg); + } + + /** + * Asserts that {@code lhs} is less than {@code rhs}. + * + * @param lhs The left hand side of the comparison. + * @param rhs The right hand side of the comparison. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static >void assertLessThan(T lhs, T rhs, String msg) { + assertTrue(compare(lhs, rhs, msg) < 0, msg); + } + + /** + * Shorthand for {@link #assertLessThanOrEqual(T, T)}. + * + * @see #assertLessThanOrEqual(T, T) + */ + public static > void assertLTE(T lhs, T rhs) { + assertLessThanOrEqual(lhs, rhs); + } + + /** + * Shorthand for {@link #assertLessThanOrEqual(T, T, String)}. + * + * @see #assertLessThanOrEqual(T, T, String) + */ + public static > void assertLTE(T lhs, T rhs, String msg) { + assertLessThanOrEqual(lhs, rhs, msg); + } + + /** + * Calls {@link #assertLessThanOrEqual(T, T, String)} with a default message. + * + * @see #assertLessThanOrEqual(T, T, String) + */ + public static > void assertLessThanOrEqual(T lhs, T rhs) { + String msg = "Expected that " + format(lhs) + " <= " + format(rhs); + assertLessThanOrEqual(lhs, rhs, msg); + } + + /** + * Asserts that {@code lhs} is less than or equal to {@code rhs}. + * + * @param lhs The left hand side of the comparison. + * @param rhs The right hand side of the comparison. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static > void assertLessThanOrEqual(T lhs, T rhs, String msg) { + assertTrue(compare(lhs, rhs, msg) <= 0, msg); + } + + /** + * Shorthand for {@link #assertEquals(T, T)}. + * + * @see #assertEquals(T, T) + */ + public static void assertEQ(Object lhs, Object rhs) { + assertEquals(lhs, rhs); + } + + /** + * Shorthand for {@link #assertEquals(T, T, String)}. + * + * @see #assertEquals(T, T, String) + */ + public static void assertEQ(Object lhs, Object rhs, String msg) { + assertEquals(lhs, rhs, msg); + } + + /** + * Calls {@link #assertEquals(T, T, String)} with a default message. + * + * @see #assertEquals(T, T, String) + */ + public static void assertEquals(Object lhs, Object rhs) { + String msg = "Expected " + format(lhs) + " to equal " + format(rhs); + assertEquals(lhs, rhs, msg); + } + + /** + * Asserts that {@code lhs} is equal to {@code rhs}. + * + * @param lhs The left hand side of the comparison. + * @param rhs The right hand side of the comparison. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static void assertEquals(Object lhs, Object rhs, String msg) { + if (lhs == null) { + if (rhs != null) { + error(msg); + } + } else { + assertTrue(lhs.equals(rhs), msg); + } + } + + /** + * Shorthand for {@link #assertGreaterThanOrEqual(T, T)}. + * + * @see #assertGreaterThanOrEqual(T, T) + */ + public static > void assertGTE(T lhs, T rhs) { + assertGreaterThanOrEqual(lhs, rhs); + } + + /** + * Shorthand for {@link #assertGreaterThanOrEqual(T, T, String)}. + * + * @see #assertGreaterThanOrEqual(T, T, String) + */ + public static > void assertGTE(T lhs, T rhs, String msg) { + assertGreaterThanOrEqual(lhs, rhs, msg); + } + + /** + * Calls {@link #assertGreaterThanOrEqual(T, T, String)} with a default message. + * + * @see #assertGreaterThanOrEqual(T, T, String) + */ + public static > void assertGreaterThanOrEqual(T lhs, T rhs) { + String msg = "Expected that " + format(lhs) + " >= " + format(rhs); + assertGreaterThanOrEqual(lhs, rhs, msg); + } + + /** + * Asserts that {@code lhs} is greater than or equal to {@code rhs}. + * + * @param lhs The left hand side of the comparison. + * @param rhs The right hand side of the comparison. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static > void assertGreaterThanOrEqual(T lhs, T rhs, String msg) { + assertTrue(compare(lhs, rhs, msg) >= 0, msg); + } + + /** + * Shorthand for {@link #assertGreaterThan(T, T)}. + * + * @see #assertGreaterThan(T, T) + */ + public static > void assertGT(T lhs, T rhs) { + assertGreaterThan(lhs, rhs); + } + + /** + * Shorthand for {@link #assertGreaterThan(T, T, String)}. + * + * @see #assertGreaterThan(T, T, String) + */ + public static > void assertGT(T lhs, T rhs, String msg) { + assertGreaterThan(lhs, rhs, msg); + } + + /** + * Calls {@link #assertGreaterThan(T, T, String)} with a default message. + * + * @see #assertGreaterThan(T, T, String) + */ + public static > void assertGreaterThan(T lhs, T rhs) { + String msg = "Expected that " + format(lhs) + " > " + format(rhs); + assertGreaterThan(lhs, rhs, msg); + } + + /** + * Asserts that {@code lhs} is greater than {@code rhs}. + * + * @param lhs The left hand side of the comparison. + * @param rhs The right hand side of the comparison. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static > void assertGreaterThan(T lhs, T rhs, String msg) { + assertTrue(compare(lhs, rhs, msg) > 0, msg); + } + + /** + * Shorthand for {@link #assertNotEquals(T, T)}. + * + * @see #assertNotEquals(T, T) + */ + public static void assertNE(Object lhs, Object rhs) { + assertNotEquals(lhs, rhs); + } + + /** + * Shorthand for {@link #assertNotEquals(T, T, String)}. + * + * @see #assertNotEquals(T, T, String) + */ + public static void assertNE(Object lhs, Object rhs, String msg) { + assertNotEquals(lhs, rhs, msg); + } + + /** + * Calls {@link #assertNotEquals(T, T, String)} with a default message. + * + * @see #assertNotEquals(T, T, String) + */ + public static void assertNotEquals(Object lhs, Object rhs) { + String msg = "Expected " + format(lhs) + " to not equal " + format(rhs); + assertNotEquals(lhs, rhs, msg); + } + + /** + * Asserts that {@code lhs} is not equal to {@code rhs}. + * + * @param lhs The left hand side of the comparison. + * @param rhs The right hand side of the comparison. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static void assertNotEquals(Object lhs, Object rhs, String msg) { + if (lhs == null) { + if (rhs == null) { + error(msg); + } + } else { + assertFalse(lhs.equals(rhs), msg); + } + } + + /** + * Calls {@link #assertNull(Object, String)} with a default message. + * + * @see #assertNull(Object, String) + */ + public static void assertNull(Object o) { + assertNull(o, "Expected " + format(o) + " to be null"); + } + + /** + * Asserts that {@code o} is null. + * + * @param o The reference assumed to be null. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static void assertNull(Object o, String msg) { + assertEquals(o, null, msg); + } + + /** + * Calls {@link #assertNotNull(Object, String)} with a default message. + * + * @see #assertNotNull(Object, String) + */ + public static void assertNotNull(Object o) { + assertNotNull(o, "Expected non null reference"); + } + + /** + * Asserts that {@code o} is not null. + * + * @param o The reference assumed not to be null, + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static void assertNotNull(Object o, String msg) { + assertNotEquals(o, null, msg); + } + + /** + * Calls {@link #assertFalse(boolean, String)} with a default message. + * + * @see #assertFalse(boolean, String) + */ + public static void assertFalse(boolean value) { + assertFalse(value, "Expected value to be false"); + } + + /** + * Asserts that {@code value} is {@code false}. + * + * @param value The value assumed to be false. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static void assertFalse(boolean value, String msg) { + assertTrue(!value, msg); + } + + /** + * Calls {@link #assertTrue(boolean, String)} with a default message. + * + * @see #assertTrue(boolean, String) + */ + public static void assertTrue(boolean value) { + assertTrue(value, "Expected value to be true"); + } + + /** + * Asserts that {@code value} is {@code true}. + * + * @param value The value assumed to be true. + * @param msg A description of the assumption. + * @throws RuntimeException if the assertion isn't valid. + */ + public static void assertTrue(boolean value, String msg) { + if (!value) { + error(msg); + } + } + + private static > int compare(T lhs, T rhs, String msg) { + assertNotNull(lhs, msg); + assertNotNull(rhs, msg); + return lhs.compareTo(rhs); + } + + private static String format(Object o) { + return o == null? "null" : o.toString(); + } + + private static void error(String msg) { + throw new RuntimeException(msg); + } + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/InputArguments.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,88 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +import java.lang.management.RuntimeMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; + +/** + * This class provides access to the input arguments to the VM. + */ +public class InputArguments { + private static final List args; + + static { + RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); + args = runtimeMxBean.getInputArguments(); + } + + /** + * Returns true if {@code arg} is an input argument to the VM. + * + * This is useful for checking boolean flags such as -XX:+UseSerialGC or + * -XX:-UsePerfData. + * + * @param arg The name of the argument. + * @return {@code true} if the given argument is an input argument, + * otherwise {@code false}. + */ + public static boolean contains(String arg) { + return args.contains(arg); + } + + /** + * Returns true if {@code prefix} is the start of an input argument to the + * VM. + * + * This is useful for checking if flags describing a quantity, such as + * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity. + * To check if the flag -XX:MaxMetaspaceSize is set, use + * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}. + * + * @param prefix The start of the argument. + * @return {@code true} if the given argument is the start of an input + * argument, otherwise {@code false}. + */ + public static boolean containsPrefix(String prefix) { + for (String arg : args) { + if (arg.startsWith(prefix)) { + return true; + } + } + return false; + } + + /** + * Get the string containing input arguments passed to the VM + */ + public static String getInputArguments() { + StringBuilder result = new StringBuilder(); + for (String arg : args) + result.append(arg).append(' '); + + return result.toString(); + } + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/JDKToolFinder.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,106 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.nio.file.Paths; + +public final class JDKToolFinder { + + private JDKToolFinder() { + } + + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite) + * + * @return Full path to an executable in jdk/bin + */ + public static String getJDKTool(String tool) { + + // First try to find the executable in test.jdk + try { + return getTool(tool, "test.jdk"); + } catch (FileNotFoundException e) { + + } + + // Now see if it's available in compile.jdk + try { + return getTool(tool, "compile.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException("Failed to find " + tool + + ", looked in test.jdk (" + System.getProperty("test.jdk") + + ") and compile.jdk (" + System.getProperty("compile.jdk") + ")"); + } + } + + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code compile.jdk} + * + * @return Full path to an executable in jdk/bin + */ + public static String getCompileJDKTool(String tool) { + try { + return getTool(tool, "compile.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code test.jdk} + * + * @return Full path to an executable in jdk/bin + */ + public static String getTestJDKTool(String tool) { + try { + return getTool(tool, "test.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + private static String getTool(String tool, String property) throws FileNotFoundException { + String jdkPath = System.getProperty(property); + + if (jdkPath == null) { + throw new RuntimeException( + "System property '" + property + "' not set. This property is normally set by jtreg. " + + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'."); + } + + Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : "")); + + Path jdkTool = Paths.get(jdkPath, toolName.toString()); + if (!jdkTool.toFile().exists()) { + throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath()); + } + + return jdkTool.toAbsolutePath().toString(); + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,134 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * A utility for constructing command lines for starting JDK tool processes. + * + * The JDKToolLauncher can in particular be combined with a + * java.lang.ProcessBuilder to easily run a JDK tool. For example, the following + * code run {@code jmap -heap} against a process with GC logging turned on for + * the {@code jmap} process: + * + *
+ * {@code
+ * JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+ *                                       .addVMArg("-XX:+PrintGC");
+ *                                       .addVMArg("-XX:+PrintGCDetails")
+ *                                       .addToolArg("-heap")
+ *                                       .addToolArg(pid);
+ * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
+ * Process p = pb.start();
+ * }
+ * 
+ */ +public class JDKToolLauncher { + private final String executable; + private final List vmArgs = new ArrayList(); + private final List toolArgs = new ArrayList(); + + private JDKToolLauncher(String tool, boolean useCompilerJDK) { + if (useCompilerJDK) { + executable = JDKToolFinder.getJDKTool(tool); + } else { + executable = JDKToolFinder.getTestJDKTool(tool); + } + vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs())); + } + + /** + * Creates a new JDKToolLauncher for the specified tool. Using tools path + * from the compiler JDK. + * + * @param tool + * The name of the tool + * @return A new JDKToolLauncher + */ + public static JDKToolLauncher create(String tool) { + return new JDKToolLauncher(tool, true); + } + + /** + * Creates a new JDKToolLauncher for the specified tool in the Tested JDK. + * + * @param tool + * The name of the tool + * + * @return A new JDKToolLauncher + */ + public static JDKToolLauncher createUsingTestJDK(String tool) { + return new JDKToolLauncher(tool, false); + } + + /** + * Adds an argument to the JVM running the tool. + * + * The JVM arguments are passed to the underlying JVM running the tool. + * Arguments will automatically be prepended with "-J". + * + * Any platform specific arguments required for running the tool are + * automatically added. + * + * + * @param arg + * The argument to VM running the tool + * @return The JDKToolLauncher instance + */ + public JDKToolLauncher addVMArg(String arg) { + vmArgs.add(arg); + return this; + } + + /** + * Adds an argument to the tool. + * + * @param arg + * The argument to the tool + * @return The JDKToolLauncher instance + */ + public JDKToolLauncher addToolArg(String arg) { + toolArgs.add(arg); + return this; + } + + /** + * Returns the command that can be used for running the tool. + * + * @return An array whose elements are the arguments of the command. + */ + public String[] getCommand() { + List command = new ArrayList(); + command.add(executable); + // Add -J in front of all vmArgs + for (String arg : vmArgs) { + command.add("-J" + arg); + } + command.addAll(toolArgs); + return command.toArray(new String[command.size()]); + } +} --- ./jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java Wed Apr 16 12:37:49 2014 +0400 @@ -23,8 +23,11 @@ package jdk.testlibrary; -import java.util.ArrayList; +import java.util.Arrays; +/** + * Super class for tests which need to attach jcmd to the current process. + */ public class JcmdBase { private static ProcessBuilder processBuilder = new ProcessBuilder(); @@ -32,46 +35,24 @@ /** * Attach jcmd to the current process * - * @param commandArgs - * jcmd command line parameters, e.g. JFR.start + * @param toolArgs + * jcmd command line parameters, e.g. VM.flags * @return jcmd output * @throws Exception */ - public final static OutputAnalyzer jcmd(String... commandArgs) + public final static OutputAnalyzer jcmd(String... toolArgs) throws Exception { - ArrayList cmd = new ArrayList(); - String cmdString = ""; - - // jcmd from the jdk to be tested - String jcmdPath = JdkFinder.getTool("jcmd", false); - cmd.add(jcmdPath); - cmdString += jcmdPath; - - String pid = Integer.toString(ProcessTools.getProcessId()); - cmd.add(pid); - cmdString += " " + pid; - - for (int i = 0; i < commandArgs.length; i++) { - cmd.add(commandArgs[i]); - cmdString += " " + commandArgs[i]; + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd"); + launcher.addToolArg(Integer.toString(ProcessTools.getProcessId())); + for (String toolArg : toolArgs) { + launcher.addToolArg(toolArg); } - - // Log command line for debugging purpose - System.out.println("Command line:"); - System.out.println(cmdString); - - processBuilder.command(cmd); + processBuilder.command(launcher.getCommand()); + System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", "")); OutputAnalyzer output = new OutputAnalyzer(processBuilder.start()); - - // Log output for debugging purpose - System.out.println("Command output:"); System.out.println(output.getOutput()); - if (output.getExitValue() != 0) { - throw new Exception(processBuilder.command() - + " resulted in exit value " + output.getExitValue() - + " , expected to get 0"); - } + output.shouldHaveExitValue(0); return output; } --- ./jdk/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java Wed May 07 19:26:47 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +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. - */ - -package jdk.testlibrary; - -import java.io.File; - -public final class JdkFinder { - - private JdkFinder() { - } - - private static String getExecutable(String executable, String property) { - String binPath = System.getProperty(property); - if (binPath == null) { - throw new RuntimeException( - "System property '" + property + "' not set"); - } - - binPath += File.separatorChar + "bin" + File.separatorChar + executable; - - return binPath; - } - - /** - * Returns the full path to a java launcher in jdk/bin based on system - * property. - * - * @param stableJdk - * see {@link #getTool(String, boolean)} - * @return Full path to a java launcher in jdk/bin. - */ - public static String getJavaLauncher(boolean stableJdk) { - return getTool("java", stableJdk); - } - - /** - * Returns the full path to an executable in jdk/bin based on system - * property. Depending on value of {@code stableJdk} the method will look for - * either 'compile.jdk' or 'test.jdk' system properties. - * 'test.jdk' is normally set by jtreg. When running test separately, - * set this property using '-Dtest.jdk=/path/to/jdk'. - * - * @param stableJdk - * If {@code true} the {@code tool} will be retrieved - * from the compile (stable) JDK. - * If {@code false} the {@code tool} will be retrieved - * from the test JDK. - * @return Full path to an executable in jdk/bin. - */ - public static String getTool(String tool, boolean stableJdk) { - if (stableJdk) { - return getExecutable(tool, "compile.jdk"); - } else { - return getExecutable(tool, "test.jdk"); - } - } -} --- ./jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java Wed Apr 16 12:37:49 2014 +0400 @@ -27,6 +27,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Utility class for verifying output and exit value from a {@code Process}. + */ public final class OutputAnalyzer { private final String stdout; @@ -85,9 +88,9 @@ public void shouldContain(String expectedString) { if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + expectedString - + "' missing from stdout/stderr: [" + stdout + stderr - + "]\n"); + + "' missing from stdout/stderr \n"); } } @@ -101,8 +104,9 @@ */ public void stdoutShouldContain(String expectedString) { if (!stdout.contains(expectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + expectedString - + "' missing from stdout: [" + stdout + "]\n"); + + "' missing from stdout \n"); } } @@ -116,8 +120,9 @@ */ public void stderrShouldContain(String expectedString) { if (!stderr.contains(expectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + expectedString - + "' missing from stderr: [" + stderr + "]\n"); + + "' missing from stderr \n"); } } @@ -132,12 +137,14 @@ */ public void shouldNotContain(String notExpectedString) { if (stdout.contains(notExpectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + notExpectedString - + "' found in stdout: [" + stdout + "]\n"); + + "' found in stdout \n"); } if (stderr.contains(notExpectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + notExpectedString - + "' found in stderr: [" + stderr + "]\n"); + + "' found in stderr \n"); } } @@ -152,8 +159,9 @@ */ public void stdoutShouldNotContain(String notExpectedString) { if (stdout.contains(notExpectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + notExpectedString - + "' found in stdout: [" + stdout + "]\n"); + + "' found in stdout \n"); } } @@ -168,55 +176,63 @@ */ public void stderrShouldNotContain(String notExpectedString) { if (stderr.contains(notExpectedString)) { + reportDiagnosticSummary(); throw new RuntimeException("'" + notExpectedString - + "' found in stderr: [" + stderr + "]\n"); + + "' found in stderr \n"); } } /** - * Verify that the stdout and stderr contents of output buffer matches - * the pattern + * Verify that the stdout and stderr contents of output buffer matches the + * pattern * * @param pattern - * @throws RuntimeException If the pattern was not found + * @throws RuntimeException + * If the pattern was not found */ public void shouldMatch(String pattern) { - Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); - Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); + Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE) + .matcher(stdout); + Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE) + .matcher(stderr); if (!stdoutMatcher.find() && !stderrMatcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' missing from stdout/stderr: [" + stdout + stderr - + "]\n"); + + "' missing from stdout/stderr \n"); } } /** - * Verify that the stdout contents of output buffer matches the - * pattern + * Verify that the stdout contents of output buffer matches the pattern * * @param pattern - * @throws RuntimeException If the pattern was not found + * @throws RuntimeException + * If the pattern was not found */ public void stdoutShouldMatch(String pattern) { - Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); + Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( + stdout); if (!matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' missing from stdout: [" + stdout + "]\n"); + + "' missing from stdout \n"); } } /** - * Verify that the stderr contents of output buffer matches the - * pattern + * Verify that the stderr contents of output buffer matches the pattern * * @param pattern - * @throws RuntimeException If the pattern was not found + * @throws RuntimeException + * If the pattern was not found */ public void stderrShouldMatch(String pattern) { - Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); + Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( + stderr); if (!matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' missing from stderr: [" + stderr + "]\n"); + + "' missing from stderr \n"); } } @@ -225,18 +241,22 @@ * match the pattern * * @param pattern - * @throws RuntimeException If the pattern was found + * @throws RuntimeException + * If the pattern was found */ public void shouldNotMatch(String pattern) { - Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); + Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( + stdout); if (matcher.find()) { - throw new RuntimeException("'" + pattern - + "' found in stdout: [" + stdout + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + pattern + "' found in stdout: '" + + matcher.group() + "' \n"); } matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (matcher.find()) { - throw new RuntimeException("'" + pattern - + "' found in stderr: [" + stderr + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + pattern + "' found in stderr: '" + + matcher.group() + "' \n"); } } @@ -245,13 +265,15 @@ * pattern * * @param pattern - * @throws RuntimeException If the pattern was found + * @throws RuntimeException + * If the pattern was found */ public void stdoutShouldNotMatch(String pattern) { - Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); + Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( + stdout); if (matcher.find()) { - throw new RuntimeException("'" + pattern - + "' found in stdout: [" + stdout + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + pattern + "' found in stdout \n"); } } @@ -260,18 +282,56 @@ * pattern * * @param pattern - * @throws RuntimeException If the pattern was found + * @throws RuntimeException + * If the pattern was found */ public void stderrShouldNotMatch(String pattern) { - Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); + Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( + stderr); if (matcher.find()) { - throw new RuntimeException("'" + pattern - + "' found in stderr: [" + stderr + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + pattern + "' found in stderr \n"); } } /** - * Verifiy the exit value of the process + * Get the captured group of the first string matching the pattern. stderr + * is searched before stdout. + * + * @param pattern + * The multi-line pattern to match + * @param group + * The group to capture + * @return The matched string or null if no match was found + */ + public String firstMatch(String pattern, int group) { + Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE) + .matcher(stderr); + Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE) + .matcher(stdout); + if (stderrMatcher.find()) { + return stderrMatcher.group(group); + } + if (stdoutMatcher.find()) { + return stdoutMatcher.group(group); + } + return null; + } + + /** + * Get the first string matching the pattern. stderr is searched before + * stdout. + * + * @param pattern + * The multi-line pattern to match + * @return The matched string or null if no match was found + */ + public String firstMatch(String pattern) { + return firstMatch(pattern, 0); + } + + /** + * Verify the exit value of the process * * @param expectedExitValue * Expected exit value from process @@ -281,12 +341,25 @@ */ public void shouldHaveExitValue(int expectedExitValue) { if (getExitValue() != expectedExitValue) { - throw new RuntimeException("Exit value " + getExitValue() - + " , expected to get " + expectedExitValue); + reportDiagnosticSummary(); + throw new RuntimeException("Expected to get exit value of [" + + expectedExitValue + "]\n"); } } /** + * Report summary that will help to diagnose the problem Currently includes: + * - standard input produced by the process under test - standard output - + * exit code Note: the command line is printed by the ProcessTools + */ + private void reportDiagnosticSummary() { + String msg = " stdout: [" + stdout + "];\n" + " stderr: [" + stderr + + "]\n" + " exitValue = " + getExitValue() + "\n"; + + System.err.println(msg); + } + + /** * Get the contents of the output buffer (stdout and stderr) * * @return Content of the output buffer --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,103 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +public class Platform { + private static final String osName = System.getProperty("os.name"); + private static final String dataModel = System.getProperty("sun.arch.data.model"); + private static final String vmVersion = System.getProperty("java.vm.version"); + private static final String osArch = System.getProperty("os.arch"); + + public static boolean is32bit() { + return dataModel.equals("32"); + } + + public static boolean is64bit() { + return dataModel.equals("64"); + } + + public static boolean isSolaris() { + return isOs("sunos"); + } + + public static boolean isWindows() { + return isOs("win"); + } + + public static boolean isOSX() { + return isOs("mac"); + } + + public static boolean isLinux() { + return isOs("linux"); + } + + private static boolean isOs(String osname) { + return osName.toLowerCase().startsWith(osname.toLowerCase()); + } + + public static String getOsName() { + return osName; + } + + public static boolean isDebugBuild() { + return vmVersion.toLowerCase().contains("debug"); + } + + public static String getVMVersion() { + return vmVersion; + } + + // Returns true for sparc and sparcv9. + public static boolean isSparc() { + return isArch("sparc"); + } + + public static boolean isARM() { + return isArch("arm"); + } + + public static boolean isPPC() { + return isArch("ppc"); + } + + public static boolean isX86() { + // On Linux it's 'i386', Windows 'x86' + return (isArch("i386") || isArch("x86")); + } + + public static boolean isX64() { + // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64' + return (isArch("amd64") || isArch("x86_64")); + } + + private static boolean isArch(String archname) { + return osArch.toLowerCase().startsWith(archname.toLowerCase()); + } + + public static String getOsArch() { + return osArch; + } + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/ProcessThread.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,143 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +import static jdk.testlibrary.Asserts.assertNotEquals; +import static jdk.testlibrary.Asserts.assertTrue; + +import java.util.List; +import java.util.concurrent.CountDownLatch; + +/** + * The helper class for starting and stopping {@link Process} in a separate thread. + */ +public class ProcessThread extends TestThread { + + /** + * Creates a new {@code ProcessThread} object. + * + * @param threadName The name of thread + * @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder} + */ + public ProcessThread(String threadName, String... cmd) { + super(new ProcessRunnable(new ProcessBuilder(cmd)), threadName); + } + + /** + * Creates a new {@code ProcessThread} object. + * + * @param threadName The name of thread. + * @param pb The ProcessBuilder to execute. + */ + public ProcessThread(String threadName, ProcessBuilder pb) { + super(new ProcessRunnable(pb), threadName); + } + + /** + * Stops {@link Process} started by {@code ProcessRunnable}. + * + * @throws InterruptedException + */ + public void stopProcess() throws InterruptedException { + ((ProcessRunnable) getRunnable()).stopProcess(); + } + + /** + * @return The process output, or null if the process has not yet completed. + */ + public OutputAnalyzer getOutput() { + return ((ProcessRunnable) getRunnable()).getOutput(); + } + + /** + * {@link Runnable} interface for starting and stopping {@link Process}. + */ + static class ProcessRunnable extends XRun { + + private final ProcessBuilder processBuilder; + private final CountDownLatch latch; + private volatile Process process; + private volatile OutputAnalyzer output; + + /** + * Creates a new {@code ProcessRunnable} object. + * + * @param pb The {@link ProcessBuilder} to run. + */ + public ProcessRunnable(ProcessBuilder pb) { + super(); + this.processBuilder = pb; + this.latch = new CountDownLatch(1); + } + + /** + * Starts the process in {@code ProcessThread}. + * All exceptions which occurs here will be caught and stored in {@code ProcessThread}. + * + * see {@link XRun} + */ + @Override + public void xrun() throws Throwable { + this.process = processBuilder.start(); + // Release when process is started + latch.countDown(); + + // Will block... + try { + output = new OutputAnalyzer(this.process); + } catch (Throwable t) { + String name = Thread.currentThread().getName(); + System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString())); + throw t; + } finally { + String logMsg = ProcessTools.getProcessLog(processBuilder, output); + System.out.println(logMsg); + } + } + + /** + * Stops the process. + * + * @throws InterruptedException + */ + public void stopProcess() throws InterruptedException { + // Wait until process is started + latch.await(); + if (this.process != null) { + System.out.println("ProcessThread.stopProcess() will kill process"); + this.process.destroy(); + } + } + + /** + * Returns the OutputAnalyzer with stdout/stderr from the process. + * @return The process output, or null if process not completed. + * @throws InterruptedException + */ + public OutputAnalyzer getOutput() { + return output; + } + } + +} --- ./jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed Apr 16 12:37:49 2014 +0400 @@ -25,24 +25,107 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import sun.management.VMManagement; public final class ProcessTools { + private static final class LineForwarder extends StreamPumper.LinePump { + private final PrintStream ps; + private final String prefix; + LineForwarder(String prefix, PrintStream os) { + this.ps = os; + this.prefix = prefix; + } + @Override + protected void processLine(String line) { + ps.println("[" + prefix + "] " + line); + } + } private ProcessTools() { } /** + *

Starts a process from its builder.

+ * The default redirects of STDOUT and STDERR are started + * @param name The process name + * @param processBuilder The process builder + * @return Returns the initialized process + * @throws IOException + */ + public static Process startProcess(String name, + ProcessBuilder processBuilder) + throws IOException { + Process p = null; + try { + p = startProcess(name, processBuilder, -1, TimeUnit.NANOSECONDS); + } catch (InterruptedException | TimeoutException e) { + // can't ever happen + } + return p; + } + + /** + *

Starts a process from its builder.

+ * The default redirects of STDOUT and STDERR are started + * @param name The process name + * @param processBuilder The process builder + * @param timeout The timeout for the warmup waiting + * @param unit The timeout {@linkplain TimeUnit} + * @return Returns the initialized {@linkplain Process} + * @throws IOException + * @throws InterruptedException + * @throws TimeoutException + */ + public static Process startProcess(String name, + ProcessBuilder processBuilder, + long timeout, + TimeUnit unit) + throws IOException, InterruptedException, TimeoutException { + Process p = processBuilder.start(); + StreamPumper stdout = new StreamPumper(p.getInputStream()); + StreamPumper stderr = new StreamPumper(p.getErrorStream()); + + stdout.addPump(new LineForwarder(name, System.out)); + stderr.addPump(new LineForwarder(name, System.err)); + final Phaser phs = new Phaser(1); + Future stdoutTask = stdout.process(); + Future stderrTask = stderr.process(); + + try { + if (timeout > -1) { + phs.awaitAdvanceInterruptibly(0, timeout, unit); + } + } catch (TimeoutException | InterruptedException e) { + System.err.println("Failed to start a process (thread dump follows)"); + for(Map.Entry s : Thread.getAllStackTraces().entrySet()) { + printStack(s.getKey(), s.getValue()); + } + stdoutTask.cancel(true); + stderrTask.cancel(true); + throw e; + } + + return p; + } + + /** * Pumps stdout and stderr from running the process into a String. * - * @param processHandler + * @param processBuilder * ProcessHandler to run. * @return Output from process. * @throws IOException @@ -69,22 +152,19 @@ stdoutBuffer); StreamPumper errPumper = new StreamPumper(process.getErrorStream(), stderrBuffer); - Thread outPumperThread = new Thread(outPumper); - Thread errPumperThread = new Thread(errPumper); - outPumperThread.setDaemon(true); - errPumperThread.setDaemon(true); - - outPumperThread.start(); - errPumperThread.start(); + Future outTask = outPumper.process(); + Future errTask = errPumper.process(); try { process.waitFor(); - outPumperThread.join(); - errPumperThread.join(); + outTask.get(); + errTask.get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return null; + } catch (ExecutionException e) { + throw new IOException(e); } return new OutputBuffer(stdoutBuffer.toString(), @@ -137,15 +217,106 @@ */ public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception { - String javapath = JdkFinder.getJavaLauncher(false); + String javapath = JDKToolFinder.getJDKTool("java"); ArrayList args = new ArrayList<>(); args.add(javapath); Collections.addAll(args, getPlatformSpecificVMArgs()); Collections.addAll(args, command); + // Reporting + StringBuilder cmdLine = new StringBuilder(); + for (String cmd : args) + cmdLine.append(cmd).append(' '); + System.out.println("Command line: [" + cmdLine.toString() + "]"); + return new ProcessBuilder(args.toArray(new String[args.size()])); - } + private static void printStack(Thread t, StackTraceElement[] stack) { + System.out.println("\t" + t + + " stack: (length = " + stack.length + ")"); + if (t != null) { + for (StackTraceElement stack1 : stack) { + System.out.println("\t" + stack1); + } + System.out.println(); + } + } + + /** + * Executes a test jvm process, waits for it to finish and returns the process output. + * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. + * The java from the test.jdk is used to execute the command. + * + * The command line will be like: + * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds + * + * @param cmds User specifed arguments. + * @return The output from the process. + */ + public static OutputAnalyzer executeTestJvm(String... cmds) throws Throwable { + ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(cmds)); + return executeProcess(pb); + } + + /** + * Executes a process, waits for it to finish and returns the process output. + * @param pb The ProcessBuilder to execute. + * @return The output from the process. + */ + public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable { + OutputAnalyzer output = null; + try { + output = new OutputAnalyzer(pb.start()); + return output; + } catch (Throwable t) { + System.out.println("executeProcess() failed: " + t); + throw t; + } finally { + System.out.println(getProcessLog(pb, output)); + } + } + + /** + * Executes a process, waits for it to finish and returns the process output. + * @param cmds The command line to execute. + * @return The output from the process. + */ + public static OutputAnalyzer executeProcess(String... cmds) throws Throwable { + return executeProcess(new ProcessBuilder(cmds)); + } + + /** + * Used to log command line, stdout, stderr and exit code from an executed process. + * @param pb The executed process. + * @param output The output from the process. + */ + public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) { + String stderr = output == null ? "null" : output.getStderr(); + String stdout = output == null ? "null" : output.getStdout(); + String exitValue = output == null ? "null": Integer.toString(output.getExitValue()); + StringBuilder logMsg = new StringBuilder(); + final String nl = System.getProperty("line.separator"); + logMsg.append("--- ProcessLog ---" + nl); + logMsg.append("cmd: " + getCommandLine(pb) + nl); + logMsg.append("exitvalue: " + exitValue + nl); + logMsg.append("stderr: " + stderr + nl); + logMsg.append("stdout: " + stdout + nl); + return logMsg.toString(); + } + + /** + * @return The full command line for the ProcessBuilder. + */ + public static String getCommandLine(ProcessBuilder pb) { + if (pb == null) { + return "null"; + } + StringBuilder cmd = new StringBuilder(); + for (String s : pb.command()) { + cmd.append(s).append(" "); + } + return cmd.toString().trim(); + } } --- ./jdk/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java Wed Apr 16 12:37:49 2014 +0400 @@ -23,16 +23,65 @@ package jdk.testlibrary; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.InputStream; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.atomic.AtomicBoolean; public final class StreamPumper implements Runnable { private static final int BUF_SIZE = 256; - private final OutputStream out; + /** + * Pump will be called by the StreamPumper to process the incoming data + */ + abstract public static class Pump { + abstract void register(StreamPumper d); + } + + /** + * OutputStream -> Pump adapter + */ + final public static class StreamPump extends Pump { + private final OutputStream out; + public StreamPump(OutputStream out) { + this.out = out; + } + + @Override + void register(StreamPumper sp) { + sp.addOutputStream(out); + } + } + + /** + * Used to process the incoming data line-by-line + */ + abstract public static class LinePump extends Pump { + @Override + final void register(StreamPumper sp) { + sp.addLineProcessor(this); + } + + abstract protected void processLine(String line); + } + private final InputStream in; + private final Set outStreams = new HashSet<>(); + private final Set linePumps = new HashSet<>(); + + private final AtomicBoolean processing = new AtomicBoolean(false); + private final FutureTask processingTask = new FutureTask(this, null); + + public StreamPumper(InputStream in) { + this.in = in; + } /** * Create a StreamPumper that reads from in and writes to out. @@ -43,8 +92,8 @@ * The stream to write to. */ public StreamPumper(InputStream in, OutputStream out) { - this.in = in; - this.out = out; + this(in); + this.addOutputStream(out); } /** @@ -54,25 +103,97 @@ */ @Override public void run() { - int length; - InputStream localIn = in; - OutputStream localOut = out; - byte[] buffer = new byte[BUF_SIZE]; + try (BufferedInputStream is = new BufferedInputStream(in)) { + ByteArrayOutputStream lineBos = new ByteArrayOutputStream(); + byte[] buf = new byte[BUF_SIZE]; + int len = 0; + int linelen = 0; - try { - while ((length = localIn.read(buffer)) > 0 && !Thread.interrupted()) { - localOut.write(buffer, 0, length); + while ((len = is.read(buf)) > 0 && !Thread.interrupted()) { + for(OutputStream out : outStreams) { + out.write(buf, 0, len); + } + if (!linePumps.isEmpty()) { + int i = 0; + int lastcrlf = -1; + while (i < len) { + if (buf[i] == '\n' || buf[i] == '\r') { + int bufLinelen = i - lastcrlf - 1; + if (bufLinelen > 0) { + lineBos.write(buf, lastcrlf + 1, bufLinelen); + } + linelen += bufLinelen; + + if (linelen > 0) { + lineBos.flush(); + final String line = lineBos.toString(); + for (LinePump lp : linePumps) { + lp.processLine(line); + }; + lineBos.reset(); + linelen = 0; + } + lastcrlf = i; + } + + i++; + } + if (lastcrlf == -1) { + lineBos.write(buf, 0, len); + linelen += len; + } else if (lastcrlf < len - 1) { + lineBos.write(buf, lastcrlf + 1, len - lastcrlf - 1); + linelen += len - lastcrlf - 1; + } + } } + } catch (IOException e) { - // Just abort if something like this happens. e.printStackTrace(); } finally { + for(OutputStream out : outStreams) { + try { + out.flush(); + } catch (IOException e) {} + } try { - localOut.flush(); in.close(); - } catch (IOException e) { - e.printStackTrace(); - } + } catch (IOException e) {} } } + + final void addOutputStream(OutputStream out) { + outStreams.add(out); + } + + final void addLineProcessor(LinePump lp) { + linePumps.add(lp); + } + + final public StreamPumper addPump(Pump ... pump) { + if (processing.get()) { + throw new IllegalStateException("Can not modify pumper while " + + "processing is in progress"); + } + for(Pump p : pump) { + p.register(this); + } + return this; + } + + final public Future process() { + if (!processing.compareAndSet(false, true)) { + throw new IllegalStateException("Can not re-run the processing"); + } + Thread t = new Thread(new Runnable() { + @Override + public void run() { + processingTask.run(); + } + }); + t.setDaemon(true); + t.start(); + + return processingTask; + } } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,249 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.concurrent.TimeoutException; + +/** + * Thread which catches exceptions thrown during the execution + * and stores them for later analysis. + * + *
+ * {@code
+ * TestThread thread = new TestThread(new XRun() {
+ *      public void run() {
+ *      // do something
+ *      }
+ * });
+ * thread.start();
+ * // do something
+ * Throwable uncaught = thread.getUncaught();
+ * }
+ * 
+ */ +public class TestThread extends Thread { + + private final Runnable runnable; + private volatile Throwable uncaught; + + /** + * Returns {@link Runnable} the thread has been created with. + * + * @return The object whose {@code run} method is called + */ + public Runnable getRunnable() { + return runnable; + } + + /** + * Creates a new {@code TestThread} object. + * + * @param target The object whose {@code run} method is called + * @param name The thread name + */ + public TestThread(Runnable target, String name) { + super(target, name); + this.runnable = target; + } + + /** + * Creates a new {@code TestThread} object. + * + * @param target The object whose {@code run} method is called + */ + public TestThread(Runnable target) { + super(target); + this.runnable = target; + } + + /** + * Creates a new {@code TestThread} object. + * + * @param group The thread group + * @param target The object whose {@code run} method is called + * @param name The thread name + * @param stackSize Stack size + */ + public TestThread(ThreadGroup group, Runnable target, String name, + long stackSize) { + super(group, target, name, stackSize); + this.runnable = target; + } + + /** + * Creates a new {@code TestThread} object. + * + * @param group The thread group + * @param target The object whose {@code run} method is called + * @param name The thread name + */ + public TestThread(ThreadGroup group, Runnable target, String name) { + super(group, target, name); + this.runnable = target; + } + + /** + * Creates a new {@code TestThread} object. + * + * @param group The thread group + * @param target The object whose {@code run} method is called + */ + public TestThread(ThreadGroup group, Runnable target) { + super(group, target); + this.runnable = target; + } + + /** + * The thread executor. + */ + @Override + public void run() { + try { + super.run(); + } catch (Throwable t) { + uncaught = t; + } + } + + /** + * Returns exception caught during the execution. + * + * @return {@link Throwable} + */ + public Throwable getUncaught() { + return uncaught; + } + + /** + * Waits for {@link TestThread} to die + * and throws exception caught during the execution. + * + * @throws InterruptedException + * @throws Throwable + */ + public void joinAndThrow() throws InterruptedException, Throwable { + join(); + if (uncaught != null) { + throw uncaught; + } + } + + /** + * Waits during {@code timeout} for {@link TestThread} to die + * and throws exception caught during the execution. + * + * @param timeout The time to wait in milliseconds + * @throws InterruptedException + * @throws Throwable + */ + public void joinAndThrow(long timeout) throws InterruptedException, + Throwable { + join(timeout); + if (isAlive()) { + throw new TimeoutException(); + } + if (uncaught != null) { + throw uncaught; + } + } + + /** + * Waits for {@link TestThread} to die + * and returns exception caught during the execution. + * + * @return Exception caught during the execution + * @throws InterruptedException + */ + public Throwable joinAndReturn() throws InterruptedException { + join(); + if (uncaught != null) { + return uncaught; + } + return null; + } + + /** + * Waits during {@code timeout} for {@link TestThread} to die + * and returns exception caught during the execution. + * + * @param timeout The time to wait in milliseconds + * @return Exception caught during the execution + * @throws InterruptedException + */ + public Throwable joinAndReturn(long timeout) throws InterruptedException { + join(timeout); + if (isAlive()) { + return new TimeoutException(); + } + if (uncaught != null) { + return uncaught; + } + return null; + } + + /** + * Waits until {@link TestThread} is in the certain {@link State} + * and blocking on {@code object}. + * + * @param state The thread state + * @param object The object to block on + */ + public void waitUntilBlockingOnObject(Thread.State state, Object object) { + String want = object == null ? null : object.getClass().getName() + '@' + + Integer.toHexString(System.identityHashCode(object)); + ThreadMXBean tmx = ManagementFactory.getThreadMXBean(); + while (isAlive()) { + ThreadInfo ti = tmx.getThreadInfo(getId()); + if (ti.getThreadState() == state + && (want == null || want.equals(ti.getLockName()))) { + return; + } + try { + Thread.sleep(1); + } catch (InterruptedException e) { + } + } + } + + /** + * Waits until {@link TestThread} is in native. + */ + public void waitUntilInNative() { + ThreadMXBean tmx = ManagementFactory.getThreadMXBean(); + while (isAlive()) { + ThreadInfo ti = tmx.getThreadInfo(getId()); + if (ti.isInNative()) { + return; + } + try { + Thread.sleep(1); + } catch (InterruptedException e) { + } + } + } + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,232 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +import static jdk.testlibrary.Asserts.assertTrue; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Arrays; +import java.util.Collections; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +/** + * Common library for various test helper functions. + */ +public final class Utils { + + /** + * Returns the sequence used by operating system to separate lines. + */ + public static final String NEW_LINE = System.getProperty("line.separator"); + + /** + * Returns the value of 'test.vm.opts'system property. + */ + public static final String VM_OPTIONS = System.getProperty("test.vm.opts", "").trim(); + + /** + * Returns the value of 'test.java.opts'system property. + */ + public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim(); + + + private Utils() { + // Private constructor to prevent class instantiation + } + + /** + * Returns the list of VM options. + * + * @return List of VM options + */ + public static List getVmOptions() { + return Arrays.asList(safeSplitString(VM_OPTIONS)); + } + + /** + * Returns the list of VM options with -J prefix. + * + * @return The list of VM options with -J prefix + */ + public static List getForwardVmOptions() { + String[] opts = safeSplitString(VM_OPTIONS); + for (int i = 0; i < opts.length; i++) { + opts[i] = "-J" + opts[i]; + } + return Arrays.asList(opts); + } + + /** + * Returns the default JTReg arguments for a jvm running a test. + * This is the combination of JTReg arguments test.vm.opts and test.java.opts. + * @return An array of options, or an empty array if no opptions. + */ + public static String[] getTestJavaOpts() { + List opts = new ArrayList(); + Collections.addAll(opts, safeSplitString(VM_OPTIONS)); + Collections.addAll(opts, safeSplitString(JAVA_OPTIONS)); + return opts.toArray(new String[0]); + } + + /** + * Combines given arguments with default JTReg arguments for a jvm running a test. + * This is the combination of JTReg arguments test.vm.opts and test.java.opts + * @return The combination of JTReg test java options and user args. + */ + public static String[] addTestJavaOpts(String... userArgs) { + List opts = new ArrayList(); + Collections.addAll(opts, getTestJavaOpts()); + Collections.addAll(opts, userArgs); + return opts.toArray(new String[0]); + } + + /** + * Splits a string by white space. + * Works like String.split(), but returns an empty array + * if the string is null or empty. + */ + private static String[] safeSplitString(String s) { + if (s == null || s.trim().isEmpty()) { + return new String[] {}; + } + return s.trim().split("\\s+"); + } + + /** + * @return The full command line for the ProcessBuilder. + */ + public static String getCommandLine(ProcessBuilder pb) { + StringBuilder cmd = new StringBuilder(); + for (String s : pb.command()) { + cmd.append(s).append(" "); + } + return cmd.toString(); + } + + /** + * Returns the free port on the local host. + * The function will spin until a valid port number is found. + * + * @return The port number + * @throws InterruptedException if any thread has interrupted the current thread + * @throws IOException if an I/O error occurs when opening the socket + */ + public static int getFreePort() throws InterruptedException, IOException { + int port = -1; + + while (port <= 0) { + Thread.sleep(100); + + ServerSocket serverSocket = null; + try { + serverSocket = new ServerSocket(0); + port = serverSocket.getLocalPort(); + } finally { + serverSocket.close(); + } + } + + return port; + } + + /** + * Returns the name of the local host. + * + * @return The host name + * @throws UnknownHostException if IP address of a host could not be determined + */ + public static String getHostname() throws UnknownHostException { + InetAddress inetAddress = InetAddress.getLocalHost(); + String hostName = inetAddress.getHostName(); + + assertTrue((hostName != null && !hostName.isEmpty()), + "Cannot get hostname"); + + return hostName; + } + + /** + * Uses "jcmd -l" to search for a jvm pid. This function will wait + * forever (until jtreg timeout) for the pid to be found. + * @param key Regular expression to search for + * @return The found pid. + */ + public static int waitForJvmPid(String key) throws Throwable { + final long iterationSleepMillis = 250; + System.out.println("waitForJvmPid: Waiting for key '" + key + "'"); + System.out.flush(); + while (true) { + int pid = tryFindJvmPid(key); + if (pid >= 0) { + return pid; + } + Thread.sleep(iterationSleepMillis); + } + } + + /** + * Searches for a jvm pid in the output from "jcmd -l". + * + * Example output from jcmd is: + * 12498 sun.tools.jcmd.JCmd -l + * 12254 /tmp/jdk8/tl/jdk/JTwork/classes/com/sun/tools/attach/Application.jar + * + * @param key A regular expression to search for. + * @return The found pid, or -1 if Enot found. + * @throws Exception If multiple matching jvms are found. + */ + public static int tryFindJvmPid(String key) throws Throwable { + ProcessBuilder pb = null; + OutputAnalyzer output = null; + try { + JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd"); + jcmdLauncher.addToolArg("-l"); + output = ProcessTools.executeProcess(jcmdLauncher.getCommand()); + output.shouldHaveExitValue(0); + + // Search for a line starting with numbers (pid), follwed by the key. + Pattern pattern = Pattern.compile("([0-9]+)\\s.*(" + key + ").*\\r?\\n"); + Matcher matcher = pattern.matcher(output.getStdout()); + + int pid = -1; + if (matcher.find()) { + pid = Integer.parseInt(matcher.group(1)); + System.out.println("findJvmPid.pid: " + pid); + if (matcher.find()) { + throw new Exception("Found multiple JVM pids for key: " + key); + } + } + return pid; + } catch (Throwable t) { + System.out.println(String.format("Utils.findJvmPid(%s) failed: %s", key, t)); + throw t; + } + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/lib/testlibrary/jdk/testlibrary/XRun.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,56 @@ +/* + * 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. + */ + +package jdk.testlibrary; + +/** + * This type serves no other purpose than to simply allow automatically running + * something in a thread, and have all exceptions propagated to + * RuntimeExceptions, which are thrown up to thread, which in turn should + * probably be a {@link TestThread} to they are stored. + */ +public abstract class XRun implements Runnable { + + /** + * Invokes {@code xrun()} and throws all exceptions caught in it + * up to the thread. + */ + public final void run() { + try { + xrun(); + } catch (Error e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + /** + * Override this method to implement what to run in the thread. + * + * @throws Throwable + */ + protected abstract void xrun() throws Throwable; +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ ./jdk/test/sun/awt/image/bug8038000.java Wed Apr 16 12:37:49 2014 +0400 @@ -0,0 +1,153 @@ +/* + * 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 8038000 + * + * @summary Verifies that we could create different type of Rasters with height 1 + * and strideline which exceeds raster width. + * Also checks that a set of RasterOp work correctly with such kind of Rasters. + * + * @run main bug8038000 + */ + +import java.awt.*; +import java.awt.color.ColorSpace; +import java.awt.geom.AffineTransform; +import java.awt.image.*; +import java.util.Arrays; + +public class bug8038000 { + + public static void main(String[] args) throws Exception { + new bug8038000().checkOps(); + + // No exceptions - Passed + } + + private void checkOps() throws Exception { + + RasterOp[] ops = new RasterOp[] { + new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), + ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), null), + new AffineTransformOp(AffineTransform.getScaleInstance(1, 1.1), null) + }; + + + for (RasterOp op: ops) { + // Banded rasters + checkOp(Raster.createBandedRaster(DataBuffer.TYPE_BYTE, 10, 1, 10, + new int[] {0, 1, 2}, new int[]{2,1,0}, null), + Raster.createBandedRaster(DataBuffer.TYPE_BYTE, 10, 1, 1001, + new int[] {0, 1, 2}, new int[]{2,1,0}, null), op); + checkOp(Raster.createBandedRaster(DataBuffer.TYPE_USHORT, 10, 1, 10, + new int[] {0, 1, 2}, new int[]{2,1,0}, null), + Raster.createBandedRaster(DataBuffer.TYPE_USHORT, 10, 1, 1001, + new int[] {0, 1, 2}, new int[]{2,1,0}, null), op); + checkOp(Raster.createBandedRaster(DataBuffer.TYPE_INT, 10, 1, 10, + new int[] {0, 1, 2}, new int[]{2,1,0}, null), + Raster.createBandedRaster(DataBuffer.TYPE_INT, 10, 1, 1001, + new int[] {0, 1, 2}, new int[]{2,1,0}, null), op); + + // Interleaved rasters + checkOp(Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + 10, 1, 30, 3, new int[]{0, 1, 2}, null), + Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + 10, 1, 1001, 3, new int[]{0, 1, 2}, null), + op); + + checkOp(Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, + 10, 1, 30, 3, new int[]{0, 1, 2}, null), + Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, + 10, 1, 1001, 3, new int[]{0, 1, 2}, null), + op); + + // Packed rasters + checkOp(Raster.createPackedRaster(new DataBufferByte(10), 10, 1, 10, + new int[] {0x01, 0x02, 0x04}, null), + Raster.createPackedRaster(new DataBufferByte(10), 10, 1, 2000, + new int[] {0x01, 0x02, 0x04}, null), + op); + checkOp(Raster.createPackedRaster(new DataBufferInt(10), 10, 1, 10, + new int[] {0xff0000, 0x00ff00, 0x0000ff}, null), + Raster.createPackedRaster(new DataBufferInt(10), 10, 1, 20, + new int[] {0xff0000, 0x00ff00, 0x0000ff}, null), + op); + + } + } + + /** + * Takes two identical rasters (identical with the exception of scanline stride) + * fills their pixels with identical data, applies the RasterOp to both rasters + * and checks that the result is the same + */ + private void checkOp(WritableRaster wr1, WritableRaster wr2, RasterOp op) { + System.out.println("Checking " + op + " with rasters: \n " + wr1 + + "\n " + wr2); + try { + WritableRaster r1 = op.filter(fillRaster(wr1), null); + WritableRaster r2 = op.filter(fillRaster(wr2), null); + compareRasters(r1, r2); + } catch (ImagingOpException e) { + System.out.println(" Skip: Op is not supported: " + e); + } + } + + private WritableRaster fillRaster(WritableRaster wr) { + int c = 0; + for(int x = wr.getMinX(); x < wr.getMinX() + wr.getWidth(); x++) { + for(int y = wr.getMinY(); y < wr.getMinY() + wr.getHeight(); y++) { + for (int b = 0; b < wr.getNumBands(); b++) { + wr.setSample(x, y, b, c++); + } + } + } + return wr; + } + + private void compareRasters(Raster r1, Raster r2) { + Rectangle bounds = r1.getBounds(); + if (!bounds.equals(r2.getBounds())) { + throw new RuntimeException("Bounds differ."); + } + + if (r1.getNumBands() != r2.getNumBands()) { + throw new RuntimeException("Bands differ."); + } + + int[] b1 = new int[r1.getNumBands()]; + int[] b2 = new int[r1.getNumBands()]; + + for (int x = (int) bounds.getX(); x < bounds.getMaxX(); x++) { + for (int y = (int) bounds.getY(); y < bounds.getMaxY(); y++) { + r1.getPixel(x,y, b1); + r2.getPixel(x,y, b2); + if (!Arrays.equals(b1, b2)) { + throw new RuntimeException("Pixels differ."); + } + } + } + } +} --- ./jdk/test/sun/security/pkcs11/fips/CipherTest.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/sun/security/pkcs11/fips/CipherTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -458,8 +458,21 @@ return false; } + // No ECDH-capable certificate in key store. May restructure + // this in the future. + if (cipherSuite.contains("ECDHE_ECDSA") || + cipherSuite.contains("ECDH_ECDSA") || + cipherSuite.contains("ECDH_RSA")) { + System.out.println("Skipping unsupported test for " + + cipherSuite + " of " + protocol); + return false; + } + // skip SSLv2Hello protocol - if (protocol.equals("SSLv2Hello")) { + // + // skip TLSv1.2 protocol, we have not implement "SunTls12Prf" and + // SunTls12RsaPremasterSecret in SunPKCS11 provider + if (protocol.equals("SSLv2Hello") || protocol.equals("TLSv1.2")) { System.out.println("Skipping unsupported test for " + cipherSuite + " of " + protocol); return false; --- ./jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java Wed Apr 16 12:37:49 2014 +0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 6313675 6323647 + * @bug 6313675 6323647 8028192 * @summary Verify that all ciphersuites work in FIPS mode * @library .. * @ignore JSSE supported cipher suites are changed with CR 6916074, @@ -44,9 +44,13 @@ return; } - if ("sparc".equals(System.getProperty("os.arch")) == false) { - // we have not updated other platforms with the proper NSS libraries yet - System.out.println("Test currently works only on solaris-sparc, skipping"); + String arch = System.getProperty("os.arch"); + if (!("sparc".equals(arch) || "sparcv9".equals(arch))) { + // we have not updated other platforms with the proper NSS + // libraries yet + System.out.println( + "Test currently works only on solaris-sparc " + + "and solaris-sparcv9. Skipping on " + arch); return; } --- ./jdk/test/sun/security/pkcs11/tls/TestPremaster.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/sun/security/pkcs11/tls/TestPremaster.java Wed Apr 16 12:37:49 2014 +0400 @@ -34,6 +34,7 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import java.util.Formatter; import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; @@ -59,27 +60,51 @@ System.out.println("OK: " + e); } - test(kg, 3, 0); - test(kg, 3, 1); - test(kg, 3, 2); - test(kg, 4, 0); + int[] protocolVersions = {0x0300, 0x0301, 0x0302, 0x0400}; + for (int clientVersion : protocolVersions) { + for (int serverVersion : protocolVersions) { + test(kg, clientVersion, serverVersion); + if (serverVersion >= clientVersion) { + break; + } + } + } System.out.println("Done."); } - private static void test(KeyGenerator kg, int major, int minor) - throws Exception { + private static void test(KeyGenerator kg, + int clientVersion, int serverVersion) throws Exception { - kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor)); + System.out.printf( + "Testing RSA pre-master secret key generation between " + + "client (0x%04X) and server(0x%04X)%n", + clientVersion, serverVersion); + kg.init(new TlsRsaPremasterSecretParameterSpec( + clientVersion, serverVersion)); SecretKey key = kg.generateKey(); byte[] encoded = key.getEncoded(); - if (encoded.length != 48) { - throw new Exception("length: " + encoded.length); - } - if ((encoded[0] != major) || (encoded[1] != minor)) { - throw new Exception("version mismatch: " + encoded[0] + - "." + encoded[1]); - } - System.out.println("OK: " + major + "." + minor); + if (encoded != null) { // raw key material may be not extractable + if (encoded.length != 48) { + throw new Exception("length: " + encoded.length); + } + int v = versionOf(encoded[0], encoded[1]); + if (clientVersion != v) { + if (serverVersion != v || clientVersion >= 0x0302) { + throw new Exception(String.format( + "version mismatch: (0x%04X) rather than (0x%04X) " + + "is used in pre-master secret", v, clientVersion)); + } + System.out.printf("Use compatible version (0x%04X)%n", v); + } + System.out.println("Passed, version matches!"); + } else { + System.out.println("Raw key material is not extractable"); + } } + + private static int versionOf(int major, int minor) { + return ((major & 0xFF) << 8) | (minor & 0xFF); + } + } --- ./jdk/test/sun/text/resources/LocaleData Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/sun/text/resources/LocaleData Wed Apr 16 12:37:49 2014 +0400 @@ -11,7 +11,7 @@ # bug #4052679 LocaleNames/fr/fr=fran\u00e7ais -# bug #4055602, 4290801 +# bug #4055602, 4290801, 8013836 CurrencyNames/pt_BR/BRL=R$ FormatData/pt_BR/NumberPatterns/0=#,##0.###;-#,##0.### # FormatData/pt_BR/NumberPatterns/1=R$ #,##0.##;-R$ #,##0.## # Changed; see bug 4122840 @@ -37,7 +37,7 @@ FormatData/pt_BR/DayNames/0=Domingo FormatData/pt_BR/DayNames/1=Segunda-feira FormatData/pt_BR/DayNames/2=Ter\u00e7a-feira -CalendarData/pt_BR/firstDayOfWeek=2 +CalendarData/pt_BR/firstDayOfWeek=1 CalendarData/pt_BR/minimalDaysInFirstWeek=1 FormatData/pt_BR/MonthNames/0=Janeiro FormatData/pt_BR/MonthNames/1=Fevereiro --- ./jdk/test/sun/text/resources/LocaleDataTest.java Wed May 07 19:26:47 2014 -0700 +++ ./jdk/test/sun/text/resources/LocaleDataTest.java Wed Apr 16 12:37:49 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, 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 @@ -34,7 +34,7 @@ * 6509039 6609737 6610748 6645271 6507067 6873931 6450945 6645268 6646611 * 6645405 6650730 6910489 6573250 6870908 6585666 6716626 6914413 6916787 * 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7189611 - * 7171028 + * 7171028 8013836 * @summary Verify locale data * */ --- ./langtools/.hgtags Wed May 07 19:27:09 2014 -0700 +++ ./langtools/.hgtags Wed Jun 25 09:05:13 2014 -0700 @@ -408,6 +408,7 @@ 2a9f5c00ba46f895bc9d16a584bf7d80c1822268 jdk7u55-b02 0479d260ac835eb3f0c7f3d7d15be0599b92a20a jdk7u55-b03 a244cc40ae0b29028ff8503ee516cb5f9e3db6e3 jdk7u55-b04 +25d63d986653d81522b01bbd2664083ae5fdc243 jdk7u65-b00 25d63d986653d81522b01bbd2664083ae5fdc243 jdk7u55-b05 76eeeaace70d38795eef5215f758493421cee0ac jdk7u55-b06 08f7914d6aa947e73269b4e60110ed12573ffa28 jdk7u55-b07 @@ -420,6 +421,11 @@ 96d55b4d88fea1d9f8227e70003210a6c10a1dba jdk7u55-b30 c1964a222000b4884b992fdbaf8f62a45fb893c9 jdk7u55-b14 4f6115ba266e5489b5e1968a28304f82be1f5641 jdk7u55-b31 +ec8793f5aa4fb0aff4aa2f02f458fa6720f3ec6f jdk7u55-b32 +13fed9e9f022e4a7f914c8410cbaa6f6564d4efd jdk7u55-b33 +d9e4f2bb3d75d15dac2c37c6ef9f64ee49ea1728 jdk7u55-b34 +c5cfebcc373607c78d577fad2146821fafc46868 jdk7u55-b35 +284494d407006c826bc434a79cab37b17e1849e3 jdk7u55-b36 849b17bc6e9a08fa41e0ef631e51366a09842e64 jdk7u60-b00 b19e375d9829daf207b1bdc7f908a3e1d548462c jdk7u60-b01 954e1616449af74f68aed57261cbeb62403377f1 jdk7u60-b02 @@ -437,6 +443,28 @@ a8b9c1929e50a9f3ae9ae1a23c06fa73a57afce3 jdk7u60-b14 7568ebdada118da1d1a6addcf6316ffda21801fd jdk7u60-b15 057caf9e0774e7c530c5710127f70c8d5f46deab jdk7u60-b16 +b7cc00c573c294b144317d44803758a291b3deda jdk7u60-b17 b7cc00c573c294b144317d44803758a291b3deda jdk7u60-b18 -b7cc00c573c294b144317d44803758a291b3deda jdk7u60-b17 +7effcbb8d1fd7ced194a294e29eea28bf552ac34 jdk7u65-b01 40aa95c8477aa0a3f090859570f5536afc9026b7 jdk7u60-b19 +b578e801c5f0e41be96d58e213b32f5c0c9278e8 jdk7u60-b30 +c1c8f9d50b3e0d7d8af08be4270649a7572b68d4 jdk7u60-b31 +ab67af57536bf46e54b5b28462d34274aaa67025 jdk7u60-b32 +e7a68fd132f7a2f39ed72d804b4574a4cc3defb2 jdk7u60-b33 +75b8c65f4c148baa4084022035b22de47df9426b jdk7u65-b02 +16bb02dae837566f3c350c6313b09f6110dcba68 jdk7u65-b03 +91677116552f743f3589f3d2ba255fa1079c0c48 jdk7u65-b04 +8f585b94be8c83f89fc481cf010a129ef75cd31b jdk7u65-b05 +c3a8556785e89b7868fc4ece666120dbf8c5c7a7 jdk7u65-b06 +1978b6434c4f717ba1bd715f016ab99dff879857 jdk7u65-b07 +684f0285b699d304d1efff487b550ff2e1679e98 jdk7u65-b08 +2715f752385349274b43a1efaab5733bafc40557 jdk7u65-b09 +98cac38ef1302939a37b85c0208a7969ba4cd8ad jdk7u65-b10 +4c40603840a8ffbf5e30049b52ff336a9aca04c1 jdk7u65-b11 +36b01ef633b2e70836b5914aa6924e81ff4d41ec jdk7u65-b12 +5ba8a1ef0f82d341ede3ec2fdac7e012e42594c4 jdk7u65-b13 +52769f410515f6a7fa66a93b24a1327fa6b6174a jdk7u65-b14 +7f2891e4c6fcd9c0e31f50189a50c8de189d774f jdk7u65-b15 +dea7e67840b68ae6752b37e69e242dae2765b878 jdk7u65-b16 +15a051dfadb6a7d014f0d2739ccf0a63ade56313 jdk7u65-b17 +576e2fd21368ba67f1f19d3180f78bc440b795a1 jdk7u65-b30