diff --git a/.hgtags b/.hgtags index f4a6aaad65c..1e380877a67 100644 --- a/.hgtags +++ b/.hgtags @@ -176,3 +176,4 @@ cecd7026f30cbd83b0601925a7a5e059aec98138 jdk8-b49 b67041a6cb508da18d2f5c7687e6a31e08bea4fc jdk8-b52 c7aa5cca1c01689a7b1a92411daf83684af05a33 jdk8-b53 7c6aa31ff1b2ae48c1c686ebe1aadf0c3da5be15 jdk8-b54 +319f583f66db47395fa86127dd3ddb729eb7c64f jdk8-b55 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index c25c3e9725a..c1eee4053a2 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -176,3 +176,4 @@ c97b99424815c43818e3cc3ffcdd1a60f3198b52 jdk8-b49 8d24def5ceb3b8f2e857f2e18b2804fc59eecf8d jdk8-b52 febd7ff5280067ca482faaeb9418ae88764c1a35 jdk8-b53 c1a277c6022affbc6855bdfb039511e73fbe2395 jdk8-b54 +b85b44cced2406792cfb9baab1377ff03e7001d8 jdk8-b55 diff --git a/corba/.hgtags b/corba/.hgtags index e19b67b7079..ac231ffd80f 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -176,3 +176,4 @@ d20d9eb9f093adbf392918c703960ad24c93a331 jdk8-b50 80689ff9cb499837513f18a1136dac7f0686cd55 jdk8-b52 63aeb7a2472fb299134ad7388e0a111a5340b02d jdk8-b53 16c82fc74695bab9b9e0fb05c086a5a08ba0082f jdk8-b54 +e8a0e84383d6fbd303ce44bd355fb25972b13286 jdk8-b55 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index dbc7d6dbedc..ab823043132 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -274,3 +274,4 @@ e3619706a7253540a2d94e9e841acaab8ace7038 jdk8-b49 9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21 e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54 09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22 +af0c8a0808516317333dcf9af15567cdd52761ce jdk8-b55 diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 1c79925a240..55ffe019b2e 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -176,3 +176,4 @@ dc1ea77ed9d9746e0f98bb1268987c3596c8b4b5 jdk8-b51 bd3c00d5761408954cc29ffb82016a76cbc90b43 jdk8-b52 2c566f25c39f0087464b73e3bcf1c1421d0f2a7e jdk8-b53 7dd81ccb7c1134df70969b3068b1e98def701746 jdk8-b54 +7c2363666890c6675194948fbcd74d81ddb84298 jdk8-b55 diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 45d200468ea..89f54c11cc1 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -176,3 +176,4 @@ bdab72e87b83bcccf3abe6eaaa4cdc7b1cd2d92b jdk8-b50 f62bc618122e87a8bea69865cc02074e9d850426 jdk8-b52 8a35fd644d3c0b75813ff0236adef8a1c6f895c6 jdk8-b53 91970935926a20f19a5cbbf20931745ac1975e91 jdk8-b54 +109c9e1f2d8546e9954e1b7be9a37a4396434544 jdk8-b55 diff --git a/jdk/.hgtags b/jdk/.hgtags index 7b1dd87bd4e..3c028e89658 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -176,3 +176,5 @@ e865efbc71059a414b3b2dd2e0adfcb3d2ab6ff9 jdk8-b51 e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52 2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53 70ad0ed1d6cef0e7712690d1bab21e4769708aad jdk8-b54 +1f3f4b333341873f00da3dee85e4879f0e89c9bb jdk8-b55 +2e9eeef2909b33c9224a024afddb61ccb0b77f14 jdk8-b56 diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 70ce7783053..00646df3e72 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -542,6 +542,21 @@ CFLAGS_$(VARIANT)/BYFILE = $(CFLAGS_$(VARIANT)/$(@F)) \ CXXFLAGS_$(VARIANT)/BYFILE = $(CXXFLAGS_$(VARIANT)/$(@F)) \ $(CXXFLAGS_$(VARIANT)$(CXXFLAGS_$(VARIANT)/$(@F))) +# Command line define to provide basename of file being compiled to source. +# The C macro THIS_FILE can replace the use of __FILE__ in the source +# files for the current filename being compiled. +# The value of the __FILE__ macro is unpredictable and can be anything +# from a relative path to a full path, THIS_FILE will be more consistent.. +# The THIS_FILE macro will always be just the basename of the file being +# compiled. +# Different string literals in the the object files makes it difficult to +# compare shared libraries from different builds. +# +# NOTE: If the THIS_FILE macro is actually expanded while in an included +# source file, it will not return the name of the included file. +# +CPP_THIS_FILE = -DTHIS_FILE='"$( $@ + @$(ECHO) $(sort $(FILES_o)) > $@ ifndef LOCAL_RESOURCE_FILE @$(ECHO) $(OBJDIR)/$(LIBRARY).res >> $@ endif @@ -256,9 +256,9 @@ $(ACTUAL_LIBRARY):: $(COMPILE_FILES_o) $(FILES_m) $(FILES_reorder) @$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), OPTIMIZATION_LEVEL=$(OPTIMIZATION_LEVEL)" @$(ECHO) "Rebuilding $@ because of $?" ifeq ($(LIBRARY), fdlibm) - $(AR) $(ARFLAGS) $@ $(FILES_o) + $(AR) $(ARFLAGS) $@ $(sort $(FILES_o)) else # LIBRARY - $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(FILES_o) $(LDLIBS) + $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(sort $(FILES_o)) $(LDLIBS) @$(call binary_file_verification,$@) ifeq ($(WRITE_LIBVERSION),true) $(MCS) -d -a "$(FULL_VERSION)" $@ diff --git a/jdk/make/common/Program.gmk b/jdk/make/common/Program.gmk index 5a2e7464c73..094d18ff997 100644 --- a/jdk/make/common/Program.gmk +++ b/jdk/make/common/Program.gmk @@ -262,7 +262,7 @@ else $(ECHO) Rebuilding $@ because of $$1 $$2 $$3 $$4 $$5 $$6 $${7:+...}; @$(MKDIR) -p $(TEMPDIR) $(LINK_PRE_CMD) $(CC) $(CC_OBJECT_OUTPUT_FLAG)$@ $(LDFLAGS) \ - $(FILES_o) $(THREADLIBS) $(LDLIBS) + $(sort $(FILES_o)) $(THREADLIBS) $(LDLIBS) ifeq ($(findstring privileged, $(INFO_PLIST_FILE)), privileged) -codesign -s openjdk_codesign $@ endif @@ -392,8 +392,6 @@ VERSION_DEFINES += -DFULL_VERSION='"$(FULL_VERSION)"' VERSION_DEFINES += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' - - $(OBJDIR)/main.$(OBJECT_SUFFIX): $(LAUNCHER_SHARE_SRC)/bin/main.c @$(prep-target) $(COMPILE.c) $(CC_OBJECT_OUTPUT_FLAG)$(OBJDIR)/main.$(OBJECT_SUFFIX) \ diff --git a/jdk/make/docs/Makefile b/jdk/make/docs/Makefile index fcb461ae8c0..e181b66a4ed 100644 --- a/jdk/make/docs/Makefile +++ b/jdk/make/docs/Makefile @@ -73,7 +73,7 @@ ifeq ($(ARCH_DATA_MODEL),64) else ifeq ($(ARCH),universal) MAX_VM_MEMORY = 1024 else - MAX_VM_MEMORY = 612 + MAX_VM_MEMORY = 768 endif # List of all possible directories for javadoc to look for sources diff --git a/jdk/make/sun/security/ec/Makefile b/jdk/make/sun/security/ec/Makefile index 0e92dd59cff..660d8bbd0f8 100644 --- a/jdk/make/sun/security/ec/Makefile +++ b/jdk/make/sun/security/ec/Makefile @@ -128,7 +128,6 @@ AUTO_FILES_JAVA_DIRS = $(PKGDIR) # Exclude the sources that get built by ../other/Makefile # AUTO_JAVA_PRUNE = \ - ECKeyFactory.java \ ECParameters.java \ ECPrivateKeyImpl.java \ ECPublicKeyImpl.java \ diff --git a/jdk/make/sun/security/other/Makefile b/jdk/make/sun/security/other/Makefile index cc869aec2e3..c0ee97711dd 100644 --- a/jdk/make/sun/security/other/Makefile +++ b/jdk/make/sun/security/other/Makefile @@ -53,7 +53,6 @@ AUTO_FILES_JAVA_DIRS = \ # EC classes used by the packages above # FILES_java += \ - sun/security/ec/ECKeyFactory.java \ sun/security/ec/ECParameters.java \ sun/security/ec/ECPrivateKeyImpl.java \ sun/security/ec/ECPublicKeyImpl.java \ diff --git a/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m b/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m index 8dab11cc624..4b49b5b5d79 100644 --- a/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m +++ b/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m @@ -37,7 +37,11 @@ #import "ThreadUtilities.h" #import "CMenuBar.h" - +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + static JNF_CLASS_CACHE(sjc_ScreenMenu, "com/apple/laf/ScreenMenu"); static jint ns2awtModifiers(NSUInteger keyMods) { @@ -97,7 +101,7 @@ static jint ns2awtMouseButton(NSInteger mouseButton) { { if (self.javaObjectWrapper == nil) { #ifdef DEBUG - NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__); + NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__); #endif return; } @@ -115,7 +119,7 @@ JNF_COCOA_EXIT(env); { if (self.javaObjectWrapper == nil) { #ifdef DEBUG - NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__); + NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__); #endif return; } @@ -133,7 +137,7 @@ JNF_COCOA_EXIT(env); { if (self.javaObjectWrapper == nil) { #ifdef DEBUG - NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__); + NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__); #endif return; } diff --git a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c index e9814153e65..fe29efdccfd 100644 --- a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c +++ b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c @@ -26,6 +26,11 @@ //#define USE_ERROR //#define USE_TRACE +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #if USE_PLATFORM_MIDI_OUT == TRUE #include "PLATFORM_API_MacOSX_MidiUtils.h" @@ -128,7 +133,7 @@ INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT case 0xF7: // System exclusive fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n", - __FILE__, __LINE__, data[0]); + THIS_FILE, __LINE__, data[0]); byteIsInvalid = TRUE; break; @@ -154,7 +159,7 @@ INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT default: // Invalid message fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n", - __FILE__, __LINE__, data[0]); + THIS_FILE, __LINE__, data[0]); byteIsInvalid = TRUE; break; } @@ -164,7 +169,7 @@ INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT default: // This can't happen, but handle it anyway. fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n", - __FILE__, __LINE__, data[0]); + THIS_FILE, __LINE__, data[0]); byteIsInvalid = TRUE; break; } diff --git a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c index b044dac0fc7..d5e47fa1f0a 100644 --- a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c +++ b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c @@ -42,6 +42,11 @@ //#define USE_ERROR //#define USE_TRACE +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE) #include "PLATFORM_API_MacOSX_MidiUtils.h" @@ -317,7 +322,7 @@ static void processMessagesForPacket(const MIDIPacket* packet, MacMidiDeviceHand packedMsg = pendingMessageStatus | pendingData[0] << 8; } else { fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n", - __FILE__, __LINE__, pendingMessageStatus, pendingDataLength); + THIS_FILE, __LINE__, pendingMessageStatus, pendingDataLength); byteIsInvalid = TRUE; } pendingDataLength = 0; diff --git a/jdk/src/macosx/native/sun/awt/CSystemColors.m b/jdk/src/macosx/native/sun/awt/CSystemColors.m index 01ab8016116..4e8c64debd2 100644 --- a/jdk/src/macosx/native/sun/awt/CSystemColors.m +++ b/jdk/src/macosx/native/sun/awt/CSystemColors.m @@ -33,6 +33,11 @@ #import "ThreadUtilities.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + NSColor **sColors = nil; NSColor **appleColors = nil; @@ -130,7 +135,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_systemColorsChanged, jc_LWCToolkit, "systemCol result = (useAppleColor ? appleColors : sColors)[colorIndex]; } else { - NSLog(@"%s: %s %sColor: %ld not found, returning black.", __FILE__, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex); + NSLog(@"%s: %s %sColor: %ld not found, returning black.", THIS_FILE, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex); result = [NSColor blackColor]; } diff --git a/jdk/src/macosx/native/sun/awt/CTextPipe.m b/jdk/src/macosx/native/sun/awt/CTextPipe.m index 37e8d4a5eaf..dbf0e01a715 100644 --- a/jdk/src/macosx/native/sun/awt/CTextPipe.m +++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m @@ -36,6 +36,10 @@ #import "QuartzSurfaceData.h" #include "AWTStrike.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 }; @@ -488,7 +492,7 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc if (glyphs == NULL || advances == NULL) { (*env)->DeleteLocalRef(env, glyphsArray); - [NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__]; + [NSException raise:NSMallocException format:@"%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__]; return; } diff --git a/jdk/src/macosx/native/sun/awt/ImageSurfaceData.h b/jdk/src/macosx/native/sun/awt/ImageSurfaceData.h index 0e4d306f252..97094028808 100644 --- a/jdk/src/macosx/native/sun/awt/ImageSurfaceData.h +++ b/jdk/src/macosx/native/sun/awt/ImageSurfaceData.h @@ -41,7 +41,7 @@ void UnlockImagePixels(JNIEnv* env, ImageSDOps* isdo); // If there is an image present, this is a no-op void makeSureImageIsCreated(ImageSDOps* isdo); -struct _ContextInfo +typedef struct _ContextInfo { BOOL useWindowContextReference; BOOL canUseJavaPixelsAsContext; @@ -50,10 +50,9 @@ struct _ContextInfo size_t bytesPerRow; CGImageAlphaInfo alphaInfo; CGColorSpaceRef colorSpace; -} -typedef ContextInfo; +} ContextInfo; -struct _ImageInfo +typedef struct _ImageInfo { size_t bitsPerComponent; size_t bitsPerPixel; @@ -61,8 +60,7 @@ struct _ImageInfo size_t bytesPerRow; CGImageAlphaInfo alphaInfo; CGColorSpaceRef colorSpace; -} -typedef ImageInfo; +} ImageInfo; struct _ImageSDOps { diff --git a/jdk/src/macosx/native/sun/awt/ImageSurfaceData.m b/jdk/src/macosx/native/sun/awt/ImageSurfaceData.m index f2ebd28431f..af7ce4ba38c 100644 --- a/jdk/src/macosx/native/sun/awt/ImageSurfaceData.m +++ b/jdk/src/macosx/native/sun/awt/ImageSurfaceData.m @@ -53,10 +53,6 @@ // for vImage framework headers #include - -// private Quartz routines needed here -CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); - static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] = { {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case @@ -942,7 +938,6 @@ PRINT("createContext") // intitalize the context to match the Java coordinate system // BG, since the context is created above, we can just concat - //CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height)); CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height)); CGContextSaveGState(qsdo->cgRef); // this will make sure we don't go pass device context settings @@ -1114,7 +1109,10 @@ PRINT("syncFromJavaPixels") if (qsdo->cgRef != NULL) { CGContextSaveGState(qsdo->cgRef); - CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0)); + CGAffineTransform currCTM = CGContextGetCTM(qsdo->cgRef); + CGAffineTransform inverse = CGAffineTransformInvert(currCTM); + CGContextConcatCTM(qsdo->cgRef, inverse); + CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0)); CGContextSetBlendMode(qsdo->cgRef, kCGBlendModeCopy); CGContextSetAlpha(qsdo->cgRef, 1.0f); CGContextDrawImage(qsdo->cgRef, CGRectMake(0, 0, width, height), javaImg); diff --git a/jdk/src/macosx/native/sun/awt/QuartzRenderer.m b/jdk/src/macosx/native/sun/awt/QuartzRenderer.m index e5784f69122..7550904096c 100644 --- a/jdk/src/macosx/native/sun/awt/QuartzRenderer.m +++ b/jdk/src/macosx/native/sun/awt/QuartzRenderer.m @@ -50,9 +50,6 @@ // same value as defined in Sun's own code #define XOR_ALPHA_CUTOFF 128 -// private Quartz routines needed here -CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); - static CGFloat gRoundRectCtrlpts[10][12] = { @@ -536,7 +533,7 @@ QUARTZ_RENDERER_INLINE void doImageCG(JNIEnv *env, CGContextRef cgRef, jobject i makeSureImageIsCreated(isdo); - CGAffineTransform ctm = CGContextGetCTM(cgRef); + CGContextSaveGState(cgRef); CGContextConcatCTM(cgRef, CGAffineTransformMake(a, b, c, d, tx, ty)); jint alphaInfo = isdo->contextInfo.alphaInfo & kCGBitmapAlphaInfoMask; @@ -551,7 +548,7 @@ QUARTZ_RENDERER_INLINE void doImageCG(JNIEnv *env, CGContextRef cgRef, jobject i CGImageRelease(subImg); } - CGContextSetCTM(cgRef, ctm); + CGContextRestoreGState(cgRef); UnlockImage(env, isdo); } diff --git a/jdk/src/macosx/native/sun/awt/QuartzSurfaceData.m b/jdk/src/macosx/native/sun/awt/QuartzSurfaceData.m index 8d3784cf2bc..3a0eea126db 100644 --- a/jdk/src/macosx/native/sun/awt/QuartzSurfaceData.m +++ b/jdk/src/macosx/native/sun/awt/QuartzSurfaceData.m @@ -40,9 +40,6 @@ #import #import "ThreadUtilities.h" -// private Quartz routines needed here -CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); - //#define DEBUG #if defined DEBUG #define PRINT(msg) {fprintf(stderr, "%s\n", msg);} @@ -50,9 +47,6 @@ CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); #define PRINT(msg) {} #endif -// from CGAffineTransformPrivate.h -extern CGPoint CGPointApplyInverseAffineTransform(CGPoint point, CGAffineTransform t); - #define kOffset (0.5f) BOOL gAdjustForJavaDrawing; @@ -608,7 +602,8 @@ PRINT(" SetUpCGContext") // We need to flip both y coefficeints to flip the offset point into the java coordinate system. ctm.b = -ctm.b; ctm.d = -ctm.d; ctm.tx = 0.0f; ctm.ty = 0.0f; CGPoint offsets = {kOffset, kOffset}; - offsets = CGPointApplyInverseAffineTransform(offsets, ctm); + CGAffineTransform inverse = CGAffineTransformInvert(ctm); + offsets = CGPointApplyAffineTransform(offsets, inverse); qsdo->graphicsStateInfo.offsetX = offsets.x; qsdo->graphicsStateInfo.offsetY = offsets.y; } diff --git a/jdk/src/macosx/native/sun/font/AWTStrike.m b/jdk/src/macosx/native/sun/font/AWTStrike.m index fbb39791e79..261bd34ae57 100644 --- a/jdk/src/macosx/native/sun/font/AWTStrike.m +++ b/jdk/src/macosx/native/sun/font/AWTStrike.m @@ -33,6 +33,11 @@ #import "CoreTextSupport.h" //#import "jni_util.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + @implementation AWTStrike static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 }; @@ -102,7 +107,7 @@ static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 }; #define AWT_FONT_CLEANUP_FINISH \ if (_fontThrowJavaException == YES) { \ char s[512]; \ - sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \ + sprintf(s, "%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__); \ [JNFException raise:env as:kRuntimeException reason:s]; \ } diff --git a/jdk/src/share/back/error_messages.h b/jdk/src/share/back/error_messages.h index 8e3ae908d9e..b886063f043 100644 --- a/jdk/src/share/back/error_messages.h +++ b/jdk/src/share/back/error_messages.h @@ -42,31 +42,36 @@ const char * jvmtiErrorText(jvmtiError); const char * eventText(int); const char * jdwpErrorText(jdwpError); +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #define EXIT_ERROR(error,msg) \ { \ print_message(stderr, "JDWP exit error ", "\n", \ "%s(%d): %s [%s:%d]", \ jvmtiErrorText((jvmtiError)error), error, (msg==NULL?"":msg), \ - __FILE__, __LINE__); \ + THIS_FILE, __LINE__); \ debugInit_exit((jvmtiError)error, msg); \ } #define JDI_ASSERT(expression) \ do { \ if (gdata && gdata->assertOn && !(expression)) { \ - jdiAssertionFailed(__FILE__, __LINE__, #expression); \ + jdiAssertionFailed(THIS_FILE, __LINE__, #expression); \ } \ } while (0) #define JDI_ASSERT_MSG(expression, msg) \ do { \ if (gdata && gdata->assertOn && !(expression)) { \ - jdiAssertionFailed(__FILE__, __LINE__, msg); \ + jdiAssertionFailed(THIS_FILE, __LINE__, msg); \ } \ } while (0) #define JDI_ASSERT_FAILED(msg) \ - jdiAssertionFailed(__FILE__, __LINE__, msg) + jdiAssertionFailed(THIS_FILE, __LINE__, msg) void do_pause(void); diff --git a/jdk/src/share/back/log_messages.h b/jdk/src/share/back/log_messages.h index bbab3ba826f..507b62a2c08 100644 --- a/jdk/src/share/back/log_messages.h +++ b/jdk/src/share/back/log_messages.h @@ -33,11 +33,15 @@ void finish_logging(int); #define LOG_NULL ((void)0) +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #ifdef JDWP_LOGGING - #define _LOG(flavor,args) \ - (log_message_begin(flavor,__FILE__,__LINE__), \ + (log_message_begin(flavor,THIS_FILE,__LINE__), \ log_message_end args) #define LOG_TEST(flag) (gdata->log_flags & (flag)) diff --git a/jdk/src/share/bin/jli_util.h b/jdk/src/share/bin/jli_util.h index af1ce47e6e4..568318c95c6 100644 --- a/jdk/src/share/bin/jli_util.h +++ b/jdk/src/share/bin/jli_util.h @@ -68,12 +68,23 @@ int JLI_GetStdArgc(); #define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3)) #define JLI_Snprintf _snprintf void JLI_CmdToArgs(char *cmdline); -#else +#define JLI_Lseek _lseeki64 +#else /* NIXES */ #include #include #define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2)) #define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3)) #define JLI_Snprintf snprintf +#ifdef __solaris__ +#define JLI_Lseek llseek +#endif +#ifdef __linux__ +#define _LARGFILE64_SOURCE +#define JLI_Lseek lseek64 +#endif +#ifdef MACOSX +#define JLI_Lseek lseek +#endif #endif /* _WIN32 */ /* diff --git a/jdk/src/share/bin/manifest_info.h b/jdk/src/share/bin/manifest_info.h index 44341f42cf5..cd951d5cb9f 100644 --- a/jdk/src/share/bin/manifest_info.h +++ b/jdk/src/share/bin/manifest_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -37,6 +37,8 @@ #define CENSIG 0x02014b50L /* "PK\001\002" */ #define ENDSIG 0x06054b50L /* "PK\005\006" */ +#define ZIP64_ENDSIG 0x06064b50L /* "PK\006\006" */ +#define ZIP64_LOCSIG 0x07064b50L /* "PK\006\007" */ /* * Header sizes including signatures */ @@ -45,12 +47,21 @@ #define CENHDR 46 #define ENDHDR 22 +#define ZIP64_ENDHDR 56 // ZIP64 end header size +#define ZIP64_LOCHDR 20 // ZIP64 end loc header size +#define ZIP64_EXTHDR 24 // EXT header size +#define ZIP64_EXTID 1 // Extra field Zip64 header ID + +#define ZIP64_MAGICVAL 0xffffffffLL +#define ZIP64_MAGICCOUNT 0xffff + /* * Header field access macros */ #define CH(b, n) (((unsigned char *)(b))[n]) #define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8)) -#define LG(b, n) (SH(b, n) | (SH(b, n+2) << 16)) +#define LG(b, n) ((SH(b, n) | (SH(b, n+2) << 16)) &0xffffffffUL) +#define LL(b, n) (((jlong)LG(b, n)) | (((jlong)LG(b, n+4)) << 32)) #define GETSIG(b) LG(b, 0) /* @@ -101,6 +112,26 @@ #define ENDOFF(b) LG(b, 16) /* central directory offset */ #define ENDCOM(b) SH(b, 20) /* size of zip file comment */ +/* + * Macros for getting Zip64 end of central directory header fields + */ +#define ZIP64_ENDLEN(b) LL(b, 4) /* size of zip64 end of central dir */ +#define ZIP64_ENDVEM(b) SH(b, 12) /* version made by */ +#define ZIP64_ENDVER(b) SH(b, 14) /* version needed to extract */ +#define ZIP64_ENDNMD(b) LG(b, 16) /* number of this disk */ +#define ZIP64_ENDDSK(b) LG(b, 20) /* disk number of start */ +#define ZIP64_ENDTOD(b) LL(b, 24) /* total number of entries on this disk */ +#define ZIP64_ENDTOT(b) LL(b, 32) /* total number of entries */ +#define ZIP64_ENDSIZ(b) LL(b, 40) /* central directory size in bytes */ +#define ZIP64_ENDOFF(b) LL(b, 48) /* offset of first CEN header */ + +/* + * Macros for getting Zip64 end of central directory locator fields + */ +#define ZIP64_LOCDSK(b) LG(b, 4) /* disk number start */ +#define ZIP64_LOCOFF(b) LL(b, 8) /* offset of zip64 end */ +#define ZIP64_LOCTOT(b) LG(b, 16) /* total number of disks */ + /* * A comment of maximum length of 64kb can follow the END record. This * is the furthest the END record can be from the end of the file. @@ -119,7 +150,7 @@ typedef struct zentry { /* Zip file entry */ size_t isize; /* size of inflated data */ size_t csize; /* size of compressed data (zero if uncompressed) */ - off_t offset; /* position of compressed data */ + jlong offset; /* position of compressed data */ int how; /* compression method (if any) */ } zentry; diff --git a/jdk/src/share/bin/parse_manifest.c b/jdk/src/share/bin/parse_manifest.c index eb847bf690c..ec3014931f2 100644 --- a/jdk/src/share/bin/parse_manifest.c +++ b/jdk/src/share/bin/parse_manifest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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,7 +61,7 @@ inflate_file(int fd, zentry *entry, int *size_out) if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 ) return (NULL); - if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0) + if (JLI_Lseek(fd, entry->offset, SEEK_SET) < (jlong)0) return (NULL); if ((in = malloc(entry->csize + 1)) == NULL) return (NULL); @@ -110,6 +110,38 @@ inflate_file(int fd, zentry *entry, int *size_out) return (NULL); } +static jboolean zip64_present = JNI_FALSE; + +/* + * Checks to see if we have ZIP64 archive, and save + * the check for later use + */ +static int +haveZIP64(Byte *p) { + jlong cenlen, cenoff, centot; + cenlen = ENDSIZ(p); + cenoff = ENDOFF(p); + centot = ENDTOT(p); + zip64_present = (cenlen == ZIP64_MAGICVAL || + cenoff == ZIP64_MAGICVAL || + centot == ZIP64_MAGICCOUNT); + return zip64_present; +} + +static jlong +find_end64(int fd, Byte *ep, jlong pos) +{ + jlong end64pos; + jlong bytes; + if ((end64pos = JLI_Lseek(fd, pos - ZIP64_LOCHDR, SEEK_SET)) < (jlong)0) + return -1; + if ((bytes = read(fd, ep, ZIP64_LOCHDR)) < 0) + return -1; + if (GETSIG(ep) == ZIP64_LOCSIG) + return end64pos; + return -1; +} + /* * A very little used routine to handle the case that zip file has * a comment at the end. Believe it or not, the only way to find the @@ -122,12 +154,12 @@ inflate_file(int fd, zentry *entry, int *size_out) * Returns the offset of the END record in the file on success, * -1 on failure. */ -static off_t +static jlong find_end(int fd, Byte *eb) { - off_t len; - off_t pos; - off_t flen; + jlong len; + jlong pos; + jlong flen; int bytes; Byte *cp; Byte *endpos; @@ -136,14 +168,16 @@ find_end(int fd, Byte *eb) /* * 99.44% (or more) of the time, there will be no comment at the * end of the zip file. Try reading just enough to read the END - * record from the end of the file. + * record from the end of the file, at this time we should also + * check to see if we have a ZIP64 archive. */ - if ((pos = lseek(fd, -ENDHDR, SEEK_END)) < (off_t)0) + if ((pos = JLI_Lseek(fd, -ENDHDR, SEEK_END)) < (jlong)0) return (-1); if ((bytes = read(fd, eb, ENDHDR)) < 0) return (-1); - if (GETSIG(eb) == ENDSIG) - return (pos); + if (GETSIG(eb) == ENDSIG) { + return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos; + } /* * Shucky-Darn,... There is a comment at the end of the zip file. @@ -151,10 +185,10 @@ find_end(int fd, Byte *eb) * Allocate and fill a buffer with enough of the zip file * to meet the specification for a maximal comment length. */ - if ((flen = lseek(fd, 0, SEEK_END)) < (off_t)0) + if ((flen = JLI_Lseek(fd, 0, SEEK_END)) < (jlong)0) return (-1); len = (flen < END_MAXLEN) ? flen : END_MAXLEN; - if (lseek(fd, -len, SEEK_END) < (off_t)0) + if (JLI_Lseek(fd, -len, SEEK_END) < (jlong)0) return (-1); if ((buffer = malloc(END_MAXLEN)) == NULL) return (-1); @@ -175,12 +209,92 @@ find_end(int fd, Byte *eb) (cp + ENDHDR + ENDCOM(cp) == endpos)) { (void) memcpy(eb, cp, ENDHDR); free(buffer); - return (flen - (endpos - cp)); + pos = flen - (endpos - cp); + return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos; } free(buffer); return (-1); } +#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ) +#define MINREAD 1024 + +/* + * Computes and positions at the start of the CEN header, ie. the central + * directory, this will also return the offset if there is a zip file comment + * at the end of the archive, for most cases this would be 0. + */ +static jlong +compute_cen(int fd, Byte *bp) +{ + int bytes; + Byte *p; + jlong base_offset; + jlong offset; + char buffer[MINREAD]; + p = buffer; + /* + * Read the END Header, which is the starting point for ZIP files. + * (Clearly designed to make writing a zip file easier than reading + * one. Now isn't that precious...) + */ + if ((base_offset = find_end(fd, bp)) == -1) { + return (-1); + } + p = bp; + /* + * There is a historical, but undocumented, ability to allow for + * additional "stuff" to be prepended to the zip/jar file. It seems + * that this has been used to prepend an actual java launcher + * executable to the jar on Windows. Although this is just another + * form of statically linking a small piece of the JVM to the + * application, we choose to continue to support it. Note that no + * guarantees have been made (or should be made) to the customer that + * this will continue to work. + * + * Therefore, calculate the base offset of the zip file (within the + * expanded file) by assuming that the central directory is followed + * immediately by the end record. + */ + if (zip64_present) { + if ((offset = ZIP64_LOCOFF(p)) < (jlong)0) { + return -1; + } + if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong) 0) { + return (-1); + } + if ((bytes = read(fd, buffer, MINREAD)) < 0) { + return (-1); + } + if (GETSIG(buffer) != ZIP64_ENDSIG) { + return -1; + } + if ((offset = ZIP64_ENDOFF(buffer)) < (jlong)0) { + return -1; + } + if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong)0) { + return (-1); + } + p = buffer; + base_offset = base_offset - ZIP64_ENDSIZ(p) - ZIP64_ENDOFF(p) - ZIP64_ENDHDR; + } else { + base_offset = base_offset - ENDSIZ(p) - ENDOFF(p); + /* + * The END Header indicates the start of the Central Directory + * Headers. Remember that the desired Central Directory Header (CEN) + * will almost always be the second one and the first one is a small + * directory entry ("META-INF/"). Keep the code optimized for + * that case. + * + * Seek to the beginning of the Central Directory. + */ + if (JLI_Lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (jlong) 0) { + return (-1); + } + } + return base_offset; +} + /* * Locate the manifest file with the zip/jar file. * @@ -208,9 +322,6 @@ find_end(int fd, Byte *eb) * a typical jar file (META-INF and META-INF/MANIFEST.MF). Keep this factoid * in mind when optimizing this code. */ -#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ) -#define MINREAD 1024 - static int find_file(int fd, zentry *entry, const char *file_name) { @@ -218,7 +329,7 @@ find_file(int fd, zentry *entry, const char *file_name) int res; int entry_size; int read_size; - int base_offset; + jlong base_offset; Byte *p; Byte *bp; Byte *buffer; @@ -228,54 +339,18 @@ find_file(int fd, zentry *entry, const char *file_name) return(-1); } - p = buffer; bp = buffer; - - /* - * Read the END Header, which is the starting point for ZIP files. - * (Clearly designed to make writing a zip file easier than reading - * one. Now isn't that precious...) - */ - if ((base_offset = find_end(fd, bp)) == -1) { + base_offset = compute_cen(fd, bp); + if (base_offset == -1) { free(buffer); - return (-1); + return -1; } - /* - * There is a historical, but undocumented, ability to allow for - * additional "stuff" to be prepended to the zip/jar file. It seems - * that this has been used to prepend an actual java launcher - * executable to the jar on Windows. Although this is just another - * form of statically linking a small piece of the JVM to the - * application, we choose to continue to support it. Note that no - * guarantees have been made (or should be made) to the customer that - * this will continue to work. - * - * Therefore, calculate the base offset of the zip file (within the - * expanded file) by assuming that the central directory is followed - * immediately by the end record. - */ - base_offset = base_offset - ENDSIZ(p) - ENDOFF(p); - - /* - * The END Header indicates the start of the Central Directory - * Headers. Remember that the desired Central Directory Header (CEN) - * will almost always be the second one and the first one is a small - * directory entry ("META-INF/"). Keep the code optimized for - * that case. - * - * Begin by seeking to the beginning of the Central Directory and - * reading in the first buffer full of bits. - */ - if (lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (off_t)0) { - free(buffer); - return (-1); - } if ((bytes = read(fd, bp, MINREAD)) < 0) { free(buffer); return (-1); } - + p = bp; /* * Loop through the Central Directory Headers. Note that a valid zip/jar * must have an ENDHDR (with ENDSIG) after the Central Directory. @@ -319,7 +394,7 @@ find_file(int fd, zentry *entry, const char *file_name) */ if ((size_t)CENNAM(p) == JLI_StrLen(file_name) && memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) { - if (lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (off_t)0) { + if (JLI_Lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (jlong)0) { free(buffer); return (-1); } @@ -487,6 +562,9 @@ JLI_ParseManifest(char *jarfile, manifest_info *info) char *splashscreen_name = NULL; if ((fd = open(jarfile, O_RDONLY +#ifdef O_LARGEFILE + | O_LARGEFILE /* large file mode on solaris */ +#endif #ifdef O_BINARY | O_BINARY /* use binary mode on windows */ #endif diff --git a/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java index 3c3ef229111..0ae68957c43 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, 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 @@ -47,18 +47,122 @@ import javax.crypto.BadPaddingException; * @see OutputFeedback */ -public final class AESCipher extends CipherSpi { +abstract class AESCipher extends CipherSpi { + public static final class General extends AESCipher { + public General() { + super(-1); + } + } + abstract static class OidImpl extends AESCipher { + protected OidImpl(int keySize, String mode, String padding) { + super(keySize); + try { + engineSetMode(mode); + engineSetPadding(padding); + } catch (GeneralSecurityException gse) { + // internal error; re-throw as provider exception + ProviderException pe =new ProviderException("Internal Error"); + pe.initCause(gse); + throw pe; + } + } + } + public static final class AES128_ECB_NoPadding extends OidImpl { + public AES128_ECB_NoPadding() { + super(16, "ECB", "NOPADDING"); + } + } + public static final class AES192_ECB_NoPadding extends OidImpl { + public AES192_ECB_NoPadding() { + super(24, "ECB", "NOPADDING"); + } + } + public static final class AES256_ECB_NoPadding extends OidImpl { + public AES256_ECB_NoPadding() { + super(32, "ECB", "NOPADDING"); + } + } + public static final class AES128_CBC_NoPadding extends OidImpl { + public AES128_CBC_NoPadding() { + super(16, "CBC", "NOPADDING"); + } + } + public static final class AES192_CBC_NoPadding extends OidImpl { + public AES192_CBC_NoPadding() { + super(24, "CBC", "NOPADDING"); + } + } + public static final class AES256_CBC_NoPadding extends OidImpl { + public AES256_CBC_NoPadding() { + super(32, "CBC", "NOPADDING"); + } + } + public static final class AES128_OFB_NoPadding extends OidImpl { + public AES128_OFB_NoPadding() { + super(16, "OFB", "NOPADDING"); + } + } + public static final class AES192_OFB_NoPadding extends OidImpl { + public AES192_OFB_NoPadding() { + super(24, "OFB", "NOPADDING"); + } + } + public static final class AES256_OFB_NoPadding extends OidImpl { + public AES256_OFB_NoPadding() { + super(32, "OFB", "NOPADDING"); + } + } + public static final class AES128_CFB_NoPadding extends OidImpl { + public AES128_CFB_NoPadding() { + super(16, "CFB", "NOPADDING"); + } + } + public static final class AES192_CFB_NoPadding extends OidImpl { + public AES192_CFB_NoPadding() { + super(24, "CFB", "NOPADDING"); + } + } + public static final class AES256_CFB_NoPadding extends OidImpl { + public AES256_CFB_NoPadding() { + super(32, "CFB", "NOPADDING"); + } + } + + // utility method used by AESCipher and AESWrapCipher + static final void checkKeySize(Key key, int fixedKeySize) + throws InvalidKeyException { + if (fixedKeySize != -1) { + if (key == null) { + throw new InvalidKeyException("The key must not be null"); + } + byte[] value = key.getEncoded(); + if (value == null) { + throw new InvalidKeyException("Key encoding must not be null"); + } else if (value.length != fixedKeySize) { + throw new InvalidKeyException("The key must be " + + fixedKeySize*8 + " bits"); + } + } + } + /* * internal CipherCore object which does the real work. */ private CipherCore core = null; + /* + * needed to support AES oids which associates a fixed key size + * to the cipher object. + */ + private final int fixedKeySize; // in bytes, -1 if no restriction + /** * Creates an instance of AES cipher with default ECB mode and * PKCS5Padding. */ - public AESCipher() { + protected AESCipher(int keySize) { core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE); + fixedKeySize = keySize; } /** @@ -183,6 +287,7 @@ public final class AESCipher extends CipherSpi { */ protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { + checkKeySize(key, fixedKeySize); core.init(opmode, key, random); } @@ -214,6 +319,7 @@ public final class AESCipher extends CipherSpi { AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + checkKeySize(key, fixedKeySize); core.init(opmode, key, params, random); } @@ -221,6 +327,7 @@ public final class AESCipher extends CipherSpi { AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + checkKeySize(key, fixedKeySize); core.init(opmode, key, params, random); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java index 21327dd09f7..29a22ad64b6 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,8 +43,27 @@ import javax.crypto.spec.*; * * @see AESCipher */ -public final class AESWrapCipher extends CipherSpi { - +abstract class AESWrapCipher extends CipherSpi { + public static final class General extends AESWrapCipher { + public General() { + super(-1); + } + } + public static final class AES128 extends AESWrapCipher { + public AES128() { + super(16); + } + } + public static final class AES192 extends AESWrapCipher { + public AES192() { + super(24); + } + } + public static final class AES256 extends AESWrapCipher { + public AES256() { + super(32); + } + } private static final byte[] IV = { (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6 @@ -62,12 +81,20 @@ public final class AESWrapCipher extends CipherSpi { */ private boolean decrypting = false; + /* + * needed to support AES oids which associates a fixed key size + * to the cipher object. + */ + private final int fixedKeySize; // in bytes, -1 if no restriction + /** * Creates an instance of AES KeyWrap cipher with default * mode, i.e. "ECB" and padding scheme, i.e. "NoPadding". */ - public AESWrapCipher() { + public AESWrapCipher(int keySize) { cipher = new AESCrypt(); + fixedKeySize = keySize; + } /** @@ -170,6 +197,7 @@ public final class AESWrapCipher extends CipherSpi { throw new UnsupportedOperationException("This cipher can " + "only be used for key wrapping and unwrapping"); } + AESCipher.checkKeySize(key, fixedKeySize); cipher.init(decrypting, key.getAlgorithm(), key.getEncoded()); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java index 1813bf260e9..533d80d49af 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,10 +80,10 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { * @param random the source of randomness */ public void initialize(int keysize, SecureRandom random) { - if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) { + if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) { throw new InvalidParameterException("Keysize must be multiple " + "of 64, and can only range " - + "from 512 to 1024 " + + "from 512 to 2048 " + "(inclusive)"); } this.pSize = keysize; @@ -115,11 +115,11 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { params = (DHParameterSpec)algParams; pSize = params.getP().bitLength(); - if ((pSize < 512) || (pSize > 1024) || + if ((pSize < 512) || (pSize > 2048) || (pSize % 64 != 0)) { throw new InvalidAlgorithmParameterException ("Prime size must be multiple of 64, and can only range " - + "from 512 to 1024 (inclusive)"); + + "from 512 to 2048 (inclusive)"); } // exponent size is optional, could be 0 @@ -156,10 +156,11 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { BigInteger g = params.getG(); if (lSize <= 0) { + lSize = pSize >> 1; // use an exponent size of (pSize / 2) but at least 384 bits - lSize = Math.max(384, pSize >> 1); - // if lSize is larger than pSize, limit by pSize - lSize = Math.min(lSize, pSize); + if (lSize < 384) { + lSize = 384; + } } BigInteger x; diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java index 0d2eec7c776..0088729d27d 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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,10 +67,10 @@ extends AlgorithmParameterGeneratorSpi { * @param random the source of randomness */ protected void engineInit(int keysize, SecureRandom random) { - if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) { + if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) { throw new InvalidParameterException("Keysize must be multiple " + "of 64, and can only range " - + "from 512 to 1024 " + + "from 512 to 2048 " + "(inclusive)"); } this.primeSize = keysize; @@ -99,10 +99,10 @@ extends AlgorithmParameterGeneratorSpi { DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; primeSize = dhParamSpec.getPrimeSize(); - if ((primeSize<512) || (primeSize>1024) || (primeSize%64 != 0)) { + if ((primeSize<512) || (primeSize>2048) || (primeSize%64 != 0)) { throw new InvalidAlgorithmParameterException ("Modulus size must be multiple of 64, and can only range " - + "from 512 to 1024 (inclusive)"); + + "from 512 to 2048 (inclusive)"); } exponentSize = dhParamSpec.getExponentSize(); diff --git a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java index e7a815283b5..925343e51f0 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java @@ -167,17 +167,67 @@ public final class SunJCE extends Provider { put("Cipher.Blowfish SupportedPaddings", BLOCK_PADS); put("Cipher.Blowfish SupportedKeyFormats", "RAW"); - put("Cipher.AES", "com.sun.crypto.provider.AESCipher"); + put("Cipher.AES", "com.sun.crypto.provider.AESCipher$General"); put("Alg.Alias.Cipher.Rijndael", "AES"); put("Cipher.AES SupportedModes", BLOCK_MODES128); put("Cipher.AES SupportedPaddings", BLOCK_PADS); put("Cipher.AES SupportedKeyFormats", "RAW"); - put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher"); + put("Cipher.AES_128/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding"); + put("Cipher.AES_128/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding"); + put("Cipher.AES_128/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding"); + put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding"); + + put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding"); + put("Cipher.AES_192/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding"); + put("Cipher.AES_192/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding"); + put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding"); + + + put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding"); + put("Cipher.AES_256/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding"); + put("Cipher.AES_256/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding"); + put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding"); + + put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General"); put("Cipher.AESWrap SupportedModes", "ECB"); put("Cipher.AESWrap SupportedPaddings", "NOPADDING"); put("Cipher.AESWrap SupportedKeyFormats", "RAW"); + put("Cipher.AESWrap_128", "com.sun.crypto.provider.AESWrapCipher$AES128"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.5", "AESWrap_128"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.5", "AESWrap_128"); + put("Cipher.AESWrap_192", "com.sun.crypto.provider.AESWrapCipher$AES192"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.25", "AESWrap_192"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.25", "AESWrap_192"); + put("Cipher.AESWrap_256", "com.sun.crypto.provider.AESWrapCipher$AES256"); + put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.45", "AESWrap_256"); + put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.45", "AESWrap_256"); + put("Cipher.RC2", "com.sun.crypto.provider.RC2Cipher"); put("Cipher.RC2 SupportedModes", BLOCK_MODES); @@ -192,7 +242,7 @@ public final class SunJCE extends Provider { put("Cipher.ARCFOUR SupportedKeyFormats", "RAW"); /* - * Key(pair) Generator engines + * Key(pair) Generator engines */ put("KeyGenerator.DES", "com.sun.crypto.provider.DESKeyGenerator"); @@ -221,6 +271,8 @@ public final class SunJCE extends Provider { put("KeyGenerator.HmacSHA1", "com.sun.crypto.provider.HmacSHA1KeyGenerator"); + put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.7", "HmacSHA1"); + put("Alg.Alias.KeyGenerator.1.2.840.113549.2.7", "HmacSHA1"); put("KeyGenerator.HmacSHA224", "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224"); @@ -326,14 +378,12 @@ public final class SunJCE extends Provider { "com.sun.crypto.provider.AESParameters"); put("Alg.Alias.AlgorithmParameters.Rijndael", "AES"); - put("AlgorithmParameters.RC2", "com.sun.crypto.provider.RC2Parameters"); put("AlgorithmParameters.OAEP", "com.sun.crypto.provider.OAEPParameters"); - /* * Key factories */ @@ -403,6 +453,8 @@ public final class SunJCE extends Provider { */ put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5"); put("Mac.HmacSHA1", "com.sun.crypto.provider.HmacSHA1"); + put("Alg.Alias.Mac.OID.1.2.840.113549.2.7", "HmacSHA1"); + put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1"); put("Mac.HmacSHA224", "com.sun.crypto.provider.HmacCore$HmacSHA224"); put("Alg.Alias.Mac.OID.1.2.840.113549.2.8", "HmacSHA224"); diff --git a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java index c4df675c937..d28d397b31c 100644 --- a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java +++ b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2012, 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 @@ -210,21 +210,21 @@ public class ByteArrayOutputStream extends OutputStream { /** * Converts the buffer's contents into a string by decoding the bytes using - * the specified {@link java.nio.charset.Charset charsetName}. The length of - * the new String is a function of the charset, and hence may not be - * equal to the length of the byte array. + * the named {@link java.nio.charset.Charset charset}. The length of the new + * String is a function of the charset, and hence may not be equal + * to the length of the byte array. * *

This method always replaces malformed-input and unmappable-character * sequences with this charset's default replacement string. The {@link * java.nio.charset.CharsetDecoder} class should be used when more control * over the decoding process is required. * - * @param charsetName the name of a supported - * {@linkplain java.nio.charset.Charset charset} - * @return String decoded from the buffer's contents. + * @param charsetName the name of a supported + * {@link java.nio.charset.Charset charset} + * @return String decoded from the buffer's contents. * @exception UnsupportedEncodingException * If the named charset is not supported - * @since JDK1.1 + * @since JDK1.1 */ public synchronized String toString(String charsetName) throws UnsupportedEncodingException diff --git a/jdk/src/share/classes/java/io/InputStreamReader.java b/jdk/src/share/classes/java/io/InputStreamReader.java index 2cda0cef369..1f6d5f6113b 100644 --- a/jdk/src/share/classes/java/io/InputStreamReader.java +++ b/jdk/src/share/classes/java/io/InputStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -86,7 +86,7 @@ public class InputStreamReader extends Reader { * * @param charsetName * The name of a supported - * {@link java.nio.charset.Charset charset} + * {@link java.nio.charset.Charset charset} * * @exception UnsupportedEncodingException * If the named charset is not supported diff --git a/jdk/src/share/classes/java/lang/annotation/ContainerFor.java b/jdk/src/share/classes/java/lang/annotation/ContainerFor.java new file mode 100644 index 00000000000..dd13bf99fcb --- /dev/null +++ b/jdk/src/share/classes/java/lang/annotation/ContainerFor.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, 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 java.lang.annotation; + +/** + * Indicates that an annotation type is a container for repeated + * instances of annotations of the type of the value of the + * {@code ContainerFor}'s value element. + * + * @since 1.8 + * @jls 9.6 Annotation Types + * @jls 9.7 Annotations + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface ContainerFor { + /** + * The repeating annotation type that the annotation type + * annotated with this annotation is a container for. + */ + Class value(); +} diff --git a/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java b/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java index d86bbbc6a4e..96a091ef84a 100644 --- a/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java +++ b/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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,6 +62,9 @@ import java.security.*; * interface is all that is needed when you accept defaults for algorithm-specific * parameters. * + *

Note: Some earlier implementations of this interface may not support + * larger sizes of DSA parameters such as 2048 and 3072-bit. + * * @see java.security.KeyPairGenerator */ public interface DSAKeyPairGenerator { @@ -78,7 +81,7 @@ public interface DSAKeyPairGenerator { * can be null. * * @exception InvalidParameterException if the params - * value is invalid or null. + * value is invalid, null, or unsupported. */ public void initialize(DSAParams params, SecureRandom random) throws InvalidParameterException; @@ -97,7 +100,7 @@ public interface DSAKeyPairGenerator { * default parameters for modulus lengths of 512 and 1024 bits. * * @param modlen the modulus length in bits. Valid values are any - * multiple of 8 between 512 and 1024, inclusive. + * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072. * * @param random the random bit source to use to generate key bits; * can be null. @@ -105,10 +108,9 @@ public interface DSAKeyPairGenerator { * @param genParams whether or not to generate new parameters for * the modulus length requested. * - * @exception InvalidParameterException if modlen is not - * between 512 and 1024, or if genParams is false and - * there are no precomputed parameters for the requested modulus - * length. + * @exception InvalidParameterException if modlen is + * invalid, or unsupported, or if genParams is false and there + * are no precomputed parameters for the requested modulus length. */ public void initialize(int modlen, boolean genParams, SecureRandom random) throws InvalidParameterException; diff --git a/jdk/src/share/classes/java/security/spec/DSAGenParameterSpec.java b/jdk/src/share/classes/java/security/spec/DSAGenParameterSpec.java new file mode 100644 index 00000000000..a354c4807ac --- /dev/null +++ b/jdk/src/share/classes/java/security/spec/DSAGenParameterSpec.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, 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 java.security.spec; + +/** + * This immutable class specifies the set of parameters used for + * generating DSA parameters as specified in + * FIPS 186-3 Digital Signature Standard (DSS). + * + * @see AlgorithmParameterSpec + * + * @since 8 + */ +public final class DSAGenParameterSpec implements AlgorithmParameterSpec { + + private final int pLen; + private final int qLen; + private final int seedLen; + + /** + * Creates a domain parameter specification for DSA parameter + * generation using primePLen and subprimeQLen. + * The value of subprimeQLen is also used as the default + * length of the domain parameter seed in bits. + * @param primePLen the desired length of the prime P in bits. + * @param subprimeQLen the desired length of the sub-prime Q in bits. + * @exception IllegalArgumentException if primePLen + * or subprimeQLen is illegal per the specification of + * FIPS 186-3. + */ + public DSAGenParameterSpec(int primePLen, int subprimeQLen) { + this(primePLen, subprimeQLen, subprimeQLen); + } + + /** + * Creates a domain parameter specification for DSA parameter + * generation using primePLen, subprimeQLen, + * and seedLen. + * @param primePLen the desired length of the prime P in bits. + * @param subprimeQLen the desired length of the sub-prime Q in bits. + * @param seedLen the desired length of the domain parameter seed in bits, + * shall be equal to or greater than subprimeQLen. + * @exception IllegalArgumentException if primePLenLen, + * subprimeQLen, or seedLen is illegal per the + * specification of FIPS 186-3. + */ + public DSAGenParameterSpec(int primePLen, int subprimeQLen, int seedLen) { + switch (primePLen) { + case 1024: + if (subprimeQLen != 160) { + throw new IllegalArgumentException + ("subprimeQLen must be 160 when primePLen=1024"); + } + break; + case 2048: + if (subprimeQLen != 224 && subprimeQLen != 256) { + throw new IllegalArgumentException + ("subprimeQLen must be 224 or 256 when primePLen=2048"); + } + break; + case 3072: + if (subprimeQLen != 256) { + throw new IllegalArgumentException + ("subprimeQLen must be 256 when primePLen=3072"); + } + break; + default: + throw new IllegalArgumentException + ("primePLen must be 1024, 2048, or 3072"); + } + if (seedLen < subprimeQLen) { + throw new IllegalArgumentException + ("seedLen must be equal to or greater than subprimeQLen"); + } + this.pLen = primePLen; + this.qLen = subprimeQLen; + this.seedLen = seedLen; + } + + /** + * Returns the desired length of the prime P of the + * to-be-generated DSA domain parameters in bits. + * @return the length of the prime P. + */ + public int getPrimePLength() { + return pLen; + } + + /** + * Returns the desired length of the sub-prime Q of the + * to-be-generated DSA domain parameters in bits. + * @return the length of the sub-prime Q. + */ + public int getSubprimeQLength() { + return qLen; + } + + /** + * Returns the desired length of the domain parameter seed in bits. + * @return the length of the domain parameter seed. + */ + public int getSeedLength() { + return seedLen; + } +} diff --git a/jdk/src/share/classes/java/sql/DriverManager.java b/jdk/src/share/classes/java/sql/DriverManager.java index 785b7334936..819544a1558 100644 --- a/jdk/src/share/classes/java/sql/DriverManager.java +++ b/jdk/src/share/classes/java/sql/DriverManager.java @@ -510,7 +510,7 @@ public class DriverManager { public Void run() { ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class); - Iterator driversIterator = loadedDrivers.iterator(); + Iterator driversIterator = loadedDrivers.iterator(); /* Load these drivers, so that they can be instantiated. * It may be the case that the driver class may not be there diff --git a/jdk/src/share/classes/sun/security/ec/ECKeyFactory.java b/jdk/src/share/classes/sun/security/ec/ECKeyFactory.java index cd35c91d14b..16ee6778169 100644 --- a/jdk/src/share/classes/sun/security/ec/ECKeyFactory.java +++ b/jdk/src/share/classes/sun/security/ec/ECKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, 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 @@ -51,33 +51,21 @@ import java.security.spec.*; */ public final class ECKeyFactory extends KeyFactorySpi { - // Used by translateKey() and the SunPKCS11 provider - public final static KeyFactory INSTANCE; + // Used by translateKey() + private static KeyFactory instance; - // Internal provider object we can obtain the KeyFactory and - // AlgorithmParameters from. Used by ECParameters and AlgorithmId. - // This can go away once we have EC always available in the SUN provider. - // Used by ECParameters and AlgorithmId. - public final static Provider ecInternalProvider; - - static { - final Provider p = new Provider("SunEC-Internal", 1.0d, null) { - private static final long serialVersionUID = 970685700309471261L; - }; - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - p.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory"); - p.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters"); - p.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC"); - return null; + private static KeyFactory getInstance() { + if (instance == null) { + try { + instance = KeyFactory.getInstance("EC", "SunEC"); + } catch (NoSuchProviderException e) { + throw new RuntimeException(e); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); } - }); - try { - INSTANCE = KeyFactory.getInstance("EC", p); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); } - ecInternalProvider = p; + + return instance; } public ECKeyFactory() { @@ -102,7 +90,12 @@ public final class ECKeyFactory extends KeyFactorySpi { checkKey(ecKey); return ecKey; } else { - return (ECKey)INSTANCE.translateKey(key); + /* + * We don't call the engineTranslateKey method directly + * because KeyFactory.translateKey adds code to loop through + * all key factories. + */ + return (ECKey)getInstance().translateKey(key); } } diff --git a/jdk/src/share/classes/sun/security/ec/ECParameters.java b/jdk/src/share/classes/sun/security/ec/ECParameters.java index 614ba3f4675..56037ada939 100644 --- a/jdk/src/share/classes/sun/security/ec/ECParameters.java +++ b/jdk/src/share/classes/sun/security/ec/ECParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, 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 @@ -276,8 +276,8 @@ public final class ECParameters extends AlgorithmParametersSpi { static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec) throws InvalidKeyException { try { - AlgorithmParameters params = AlgorithmParameters.getInstance - ("EC", ECKeyFactory.ecInternalProvider); + AlgorithmParameters params = + AlgorithmParameters.getInstance("EC", "SunEC"); params.init(spec); return params; } catch (GeneralSecurityException e) { diff --git a/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java b/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java index aae485c1241..0dcf4b030a9 100644 --- a/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java +++ b/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java @@ -96,8 +96,13 @@ public final class ECPublicKeyImpl extends X509Key implements ECPublicKey { */ @SuppressWarnings("deprecation") protected void parseKeyBits() throws InvalidKeyException { + AlgorithmParameters algParams = this.algid.getParameters(); + if (algParams == null) { + throw new InvalidKeyException("EC domain parameters must be " + + "encoded in the algorithm identifier"); + } + try { - AlgorithmParameters algParams = this.algid.getParameters(); params = algParams.getParameterSpec(ECParameterSpec.class); w = ECParameters.decodePoint(key, params.getCurve()); } catch (IOException e) { diff --git a/jdk/src/share/classes/sun/security/ec/SunECEntries.java b/jdk/src/share/classes/sun/security/ec/SunECEntries.java index 6d2cb65a77a..fe810ee8abf 100644 --- a/jdk/src/share/classes/sun/security/ec/SunECEntries.java +++ b/jdk/src/share/classes/sun/security/ec/SunECEntries.java @@ -54,6 +54,7 @@ final class SunECEntries { */ map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters"); map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC"); + map.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC"); map.put("AlgorithmParameters.EC KeySize", "256"); @@ -133,6 +134,9 @@ final class SunECEntries { "sun.security.ec.ECDSASignature$Raw"); map.put("Signature.SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1"); + map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.1", "SHA1withECDSA"); + map.put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA"); + map.put("Signature.SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224"); map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA"); diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index 61a3c7c129f..596fa80a0f2 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -115,7 +115,12 @@ public class Config { private static boolean isMacosLionOrBetter() { // split the "10.x.y" version number - String osVersion = System.getProperty("os.version"); + String osname = getProperty("os.name"); + if (!osname.contains("OS X")) { + return false; + } + + String osVersion = getProperty("os.version"); String[] fragments = osVersion.split("\\."); // sanity check the "10." part of the version @@ -140,20 +145,14 @@ public class Config { /* * If either one system property is specified, we throw exception. */ - String tmp = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction - ("java.security.krb5.kdc")); + String tmp = getProperty("java.security.krb5.kdc"); if (tmp != null) { // The user can specify a list of kdc hosts separated by ":" defaultKDC = tmp.replace(':', ' '); } else { defaultKDC = null; } - defaultRealm = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction - ("java.security.krb5.realm")); + defaultRealm = getProperty("java.security.krb5.realm"); if ((defaultKDC == null && defaultRealm != null) || (defaultRealm == null && defaultKDC != null)) { throw new KrbException @@ -165,11 +164,34 @@ public class Config { // Always read the Kerberos configuration file try { Vector configFile; - configFile = loadConfigFile(); - if (configFile == null && isMacosLionOrBetter()) { - stanzaTable = SCDynamicStoreConfig.getConfig(); - } else { + String fileName = getJavaFileName(); + if (fileName != null) { + configFile = loadConfigFile(fileName); stanzaTable = parseStanzaTable(configFile); + if (DEBUG) { + System.out.println("Loaded from Java config"); + } + } else { + boolean found = false; + if (isMacosLionOrBetter()) { + try { + stanzaTable = SCDynamicStoreConfig.getConfig(); + if (DEBUG) { + System.out.println("Loaded from SCDynamicStoreConfig"); + } + found = true; + } catch (IOException ioe) { + // OK. Will go on with file + } + } + if (!found) { + fileName = getNativeFileName(); + configFile = loadConfigFile(fileName); + stanzaTable = parseStanzaTable(configFile); + if (DEBUG) { + System.out.println("Loaded from native config"); + } + } } } catch (IOException ioe) { // No krb5.conf, no problem. We'll use DNS or system property etc. @@ -546,10 +568,13 @@ public class Config { * [domain_realm] * blue.sample.com = TEST.SAMPLE.COM * .backup.com = EXAMPLE.COM + * + * @params fileName the conf file, cannot be null + * @return the content, null if fileName is empty + * @throws IOException if there is an I/O or format error */ - private Vector loadConfigFile() throws IOException { + private Vector loadConfigFile(final String fileName) throws IOException { try { - final String fileName = getFileName(); if (!fileName.equals("")) { BufferedReader br = new BufferedReader(new InputStreamReader( java.security.AccessController.doPrivileged( @@ -668,97 +693,106 @@ public class Config { } /** - * Gets the default configuration file name. This method will never - * return null. + * Gets the default Java configuration file name. * * If the system property "java.security.krb5.conf" is defined, we'll - * use its value, no matter if the file exists or not. Otherwise, - * the file will be searched in a list of possible loations in the - * following order: + * use its value, no matter if the file exists or not. Otherwise, we + * will look at $JAVA_HOME/lib/security directory with "krb5.conf" name, + * and return it if the file exists. * - * 1. at Java home lib\security directory with "krb5.conf" name, - * 2. at windows directory with the name of "krb5.ini" for Windows, - * /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf otherwise. + * The method returns null if it cannot find a Java config file. + */ + private String getJavaFileName() { + String name = getProperty("java.security.krb5.conf"); + if (name == null) { + name = getProperty("java.home") + File.separator + + "lib" + File.separator + "security" + + File.separator + "krb5.conf"; + if (!fileExists(name)) { + name = null; + } + } + if (DEBUG) { + System.out.println("Java config name: " + name); + } + return name; + } + + /** + * Gets the default native configuration file name. + * + * Depending on the OS type, the method returns the default native + * kerberos config file name, which is at windows directory with + * the name of "krb5.ini" for Windows, /etc/krb5/krb5.conf for Solaris, + * /etc/krb5.conf otherwise. Mac OSX X has a different file name. * * Note: When the Terminal Service is started in Windows (from 2003), * there are two kinds of Windows directories: A system one (say, * C:\Windows), and a user-private one (say, C:\Users\Me\Windows). * We will first look for krb5.ini in the user-private one. If not * found, try the system one instead. + * + * This method will always return a non-null non-empty file name, + * even if that file does not exist. */ - private String getFileName() { - String name = - java.security.AccessController.doPrivileged( - new sun.security.action. - GetPropertyAction("java.security.krb5.conf")); - if (name == null) { - name = java.security.AccessController.doPrivileged( - new sun.security.action. - GetPropertyAction("java.home")) + File.separator + - "lib" + File.separator + "security" + - File.separator + "krb5.conf"; - if (!fileExists(name)) { - name = null; - String osname = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("os.name")); - if (osname.startsWith("Windows")) { - try { - Credentials.ensureLoaded(); - } catch (Exception e) { - // ignore exceptions + private String getNativeFileName() { + String name = null; + String osname = getProperty("os.name"); + if (osname.startsWith("Windows")) { + try { + Credentials.ensureLoaded(); + } catch (Exception e) { + // ignore exceptions + } + if (Credentials.alreadyLoaded) { + String path = getWindowsDirectory(false); + if (path != null) { + if (path.endsWith("\\")) { + path = path + "krb5.ini"; + } else { + path = path + "\\krb5.ini"; } - if (Credentials.alreadyLoaded) { - String path = getWindowsDirectory(false); - if (path != null) { - if (path.endsWith("\\")) { - path = path + "krb5.ini"; - } else { - path = path + "\\krb5.ini"; - } - if (fileExists(path)) { - name = path; - } - } - if (name == null) { - path = getWindowsDirectory(true); - if (path != null) { - if (path.endsWith("\\")) { - path = path + "krb5.ini"; - } else { - path = path + "\\krb5.ini"; - } - name = path; - } + if (fileExists(path)) { + name = path; + } + } + if (name == null) { + path = getWindowsDirectory(true); + if (path != null) { + if (path.endsWith("\\")) { + path = path + "krb5.ini"; + } else { + path = path + "\\krb5.ini"; } + name = path; } - if (name == null) { - name = "c:\\winnt\\krb5.ini"; - } - } else if (osname.startsWith("SunOS")) { - name = "/etc/krb5/krb5.conf"; - } else if (osname.contains("OS X")) { - if (isMacosLionOrBetter()) return ""; - name = findMacosConfigFile(); - } else { - name = "/etc/krb5.conf"; } } + if (name == null) { + name = "c:\\winnt\\krb5.ini"; + } + } else if (osname.startsWith("SunOS")) { + name = "/etc/krb5/krb5.conf"; + } else if (osname.contains("OS X")) { + name = findMacosConfigFile(); + } else { + name = "/etc/krb5.conf"; } if (DEBUG) { - System.out.println("Config name: " + name); + System.out.println("Native config name: " + name); } return name; } - private String getProperty(String property) { - return java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction(property)); + private static String getProperty(String property) { + return java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction(property)); } private String findMacosConfigFile() { String userHome = getProperty("user.home"); final String PREF_FILE = "/Library/Preferences/edu.mit.Kerberos"; - String userPrefs=userHome + PREF_FILE; + String userPrefs = userHome + PREF_FILE; if (fileExists(userPrefs)) { return userPrefs; @@ -768,11 +802,7 @@ public class Config { return PREF_FILE; } - if (fileExists("/etc/krb5.conf")) { - return "/etc/krb5.conf"; - } - - return ""; + return "/etc/krb5.conf"; } private static String trimmed(String s) { @@ -1344,32 +1374,52 @@ public class Config { } } + // Shows the content of the Config object for debug purpose. + // + // { + // libdefaults = { + // default_realm = R + // } + // realms = { + // R = { + // kdc = [k1,k2] + // } + // } + // } + @Override public String toString() { StringBuffer sb = new StringBuffer(); - toStringIndented("", stanzaTable, sb); + toStringInternal("", stanzaTable, sb); return sb.toString(); } - private static void toStringIndented(String prefix, Object obj, + private static void toStringInternal(String prefix, Object obj, StringBuffer sb) { if (obj instanceof String) { - sb.append(prefix); - sb.append(obj); - sb.append('\n'); + // A string value, just print it + sb.append(obj).append('\n'); } else if (obj instanceof Hashtable) { + // A table, start a new sub-section... Hashtable tab = (Hashtable)obj; + sb.append("{\n"); for (Object o: tab.keySet()) { - sb.append(prefix); - sb.append(o); - sb.append(" = {\n"); - toStringIndented(prefix + " ", tab.get(o), sb); - sb.append(prefix + "}\n"); + // ...indent, print "key = ", and + sb.append(prefix).append(" ").append(o).append(" = "); + // ...go recursively into value + toStringInternal(prefix + " ", tab.get(o), sb); } + sb.append(prefix).append("}\n"); } else if (obj instanceof Vector) { + // A vector of strings, print them inside [ and ] Vector v = (Vector)obj; + sb.append("["); + boolean first = true; for (Object o: v.toArray()) { - toStringIndented(prefix + " ", o, sb); + if (!first) sb.append(","); + sb.append(o); + first = false; } + sb.append("]\n"); } } } diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java index 8179dc01682..c7d62ff6b46 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java @@ -164,6 +164,10 @@ final class P11Cipher extends CipherSpi { // if we do the padding private int bytesBuffered; + // length of key size in bytes; currently only used by AES given its oid + // specification mandates a fixed size of the key + private int fixedKeySize = -1; + P11Cipher(Token token, String algorithm, long mechanism) throws PKCS11Exception, NoSuchAlgorithmException { super(); @@ -172,19 +176,26 @@ final class P11Cipher extends CipherSpi { this.mechanism = mechanism; String algoParts[] = algorithm.split("/"); - keyAlgorithm = algoParts[0]; - if (keyAlgorithm.equals("AES")) { + if (algoParts[0].startsWith("AES")) { blockSize = 16; - } else if (keyAlgorithm.equals("RC4") || - keyAlgorithm.equals("ARCFOUR")) { - blockSize = 0; - } else { // DES, DESede, Blowfish - blockSize = 8; - } - this.blockMode = + int index = algoParts[0].indexOf('_'); + if (index != -1) { + // should be well-formed since we specify what we support + fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8; + } + keyAlgorithm = "AES"; + } else { + keyAlgorithm = algoParts[0]; + if (keyAlgorithm.equals("RC4") || + keyAlgorithm.equals("ARCFOUR")) { + blockSize = 0; + } else { // DES, DESede, Blowfish + blockSize = 8; + } + this.blockMode = (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB); - + } String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding"); String paddingStr = (algoParts.length > 2 ? algoParts[2] : defPadding); @@ -333,6 +344,9 @@ final class P11Cipher extends CipherSpi { SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { cancelOperation(); + if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) { + throw new InvalidKeyException("Key size is invalid"); + } switch (opmode) { case Cipher.ENCRYPT_MODE: encrypt = true; diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java b/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java index ef6cf3a1ef5..a4c48e76d44 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, 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 @@ -304,7 +304,7 @@ final class P11ECKeyFactory extends P11KeyFactory { } KeyFactory implGetSoftwareFactory() throws GeneralSecurityException { - return sun.security.ec.ECKeyFactory.INSTANCE; + return KeyFactory.getInstance("EC", "SunEC"); } } diff --git a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java index bac38137f16..d138d675a48 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -399,12 +399,8 @@ public final class SunPKCS11 extends AuthProvider { return System.identityHashCode(this); } - private static String[] s(String s1) { - return new String[] {s1}; - } - - private static String[] s(String s1, String s2) { - return new String[] {s1, s2}; + private static String[] s(String ...aliases) { + return aliases; } private static final class Descriptor { @@ -521,7 +517,8 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_MD2)); d(MD, "MD5", P11Digest, m(CKM_MD5)); - d(MD, "SHA1", P11Digest, s("SHA", "SHA-1"), + d(MD, "SHA1", P11Digest, + s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"), m(CKM_SHA_1)); d(MD, "SHA-224", P11Digest, @@ -540,6 +537,7 @@ public final class SunPKCS11 extends AuthProvider { d(MAC, "HmacMD5", P11MAC, m(CKM_MD5_HMAC)); d(MAC, "HmacSHA1", P11MAC, + s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"), m(CKM_SHA_1_HMAC)); d(MAC, "HmacSHA224", P11MAC, s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"), @@ -561,6 +559,7 @@ public final class SunPKCS11 extends AuthProvider { d(KPG, "RSA", P11KeyPairGenerator, m(CKM_RSA_PKCS_KEY_PAIR_GEN)); d(KPG, "DSA", P11KeyPairGenerator, + s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"), m(CKM_DSA_KEY_PAIR_GEN)); d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"), m(CKM_DH_PKCS_KEY_PAIR_GEN)); @@ -583,6 +582,7 @@ public final class SunPKCS11 extends AuthProvider { d(KF, "RSA", P11RSAKeyFactory, m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509)); d(KF, "DSA", P11DSAKeyFactory, + s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"), m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1)); d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"), m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE)); @@ -609,6 +609,7 @@ public final class SunPKCS11 extends AuthProvider { d(SKF, "DESede", P11SecretKeyFactory, m(CKM_DES3_CBC)); d(SKF, "AES", P11SecretKeyFactory, + s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"), m(CKM_AES_CBC)); d(SKF, "Blowfish", P11SecretKeyFactory, m(CKM_BLOWFISH_CBC)); @@ -635,10 +636,28 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_DES3_ECB)); d(CIP, "AES/CBC/NoPadding", P11Cipher, m(CKM_AES_CBC)); + d(CIP, "AES_128/CBC/NoPadding", P11Cipher, + s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"), + m(CKM_AES_CBC)); + d(CIP, "AES_192/CBC/NoPadding", P11Cipher, + s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"), + m(CKM_AES_CBC)); + d(CIP, "AES_256/CBC/NoPadding", P11Cipher, + s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"), + m(CKM_AES_CBC)); d(CIP, "AES/CBC/PKCS5Padding", P11Cipher, m(CKM_AES_CBC_PAD, CKM_AES_CBC)); d(CIP, "AES/ECB/NoPadding", P11Cipher, m(CKM_AES_ECB)); + d(CIP, "AES_128/ECB/NoPadding", P11Cipher, + s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"), + m(CKM_AES_ECB)); + d(CIP, "AES_192/ECB/NoPadding", P11Cipher, + s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"), + m(CKM_AES_ECB)); + d(CIP, "AES_256/ECB/NoPadding", P11Cipher, + s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"), + m(CKM_AES_ECB)); d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"), m(CKM_AES_ECB)); d(CIP, "AES/CTR/NoPadding", P11Cipher, @@ -654,13 +673,16 @@ public final class SunPKCS11 extends AuthProvider { d(CIP, "RSA/ECB/NoPadding", P11RSACipher, m(CKM_RSA_X_509)); - d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"), + d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"), m(CKM_DSA)); - d(SIG, "DSA", P11Signature, s("SHA1withDSA"), + d(SIG, "DSA", P11Signature, + s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27", + "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"), m(CKM_DSA_SHA1, CKM_DSA)); d(SIG, "NONEwithECDSA", P11Signature, m(CKM_ECDSA)); - d(SIG, "SHA1withECDSA", P11Signature, s("ECDSA"), + d(SIG, "SHA1withECDSA", P11Signature, + s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"), m(CKM_ECDSA_SHA1, CKM_ECDSA)); d(SIG, "SHA224withECDSA", P11Signature, s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"), @@ -675,10 +697,14 @@ public final class SunPKCS11 extends AuthProvider { s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"), m(CKM_ECDSA)); d(SIG, "MD2withRSA", P11Signature, + s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"), m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); d(SIG, "MD5withRSA", P11Signature, + s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"), m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); d(SIG, "SHA1withRSA", P11Signature, + s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5", + "1.3.14.3.2.29"), m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); d(SIG, "SHA224withRSA", P11Signature, s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"), diff --git a/jdk/src/share/classes/sun/security/provider/DSA.java b/jdk/src/share/classes/sun/security/provider/DSA.java index a59679ccc6f..411563f42e4 100644 --- a/jdk/src/share/classes/sun/security/provider/DSA.java +++ b/jdk/src/share/classes/sun/security/provider/DSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,14 +45,15 @@ import sun.security.jca.JCAUtil; /** * The Digital Signature Standard (using the Digital Signature - * Algorithm), as described in fips186 of the National Instute of - * Standards and Technology (NIST), using fips180-1 (SHA-1). + * Algorithm), as described in fips186-3 of the National Instute of + * Standards and Technology (NIST), using SHA digest algorithms + * from FIPS180-3. * * This file contains both the signature implementation for the - * commonly used SHA1withDSA (DSS) as well as RawDSA, used by TLS - * among others. RawDSA expects the 20 byte SHA-1 digest as input - * via update rather than the original data like other signature - * implementations. + * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA, + * as well as RawDSA, used by TLS among others. RawDSA expects + * the 20 byte SHA-1 digest as input via update rather than the + * original data like other signature implementations. * * @author Benjamin Renaud * @@ -78,129 +79,19 @@ abstract class DSA extends SignatureSpi { /* The private key, if any */ private BigInteger presetX; - /* The random seed used to generate k */ - private int[] Kseed; - - /* The random seed used to generate k (specified by application) */ - private byte[] KseedAsByteArray; - - /* - * The random seed used to generate k - * (prevent the same Kseed from being used twice in a row - */ - private int[] previousKseed; - /* The RNG used to output a seed for generating k */ private SecureRandom signingRandom; + /* The message digest object used */ + private final MessageDigest md; + /** * Construct a blank DSA object. It must be * initialized before being usable for signing or verifying. */ - DSA() { + DSA(MessageDigest md) { super(); - } - - /** - * Return the 20 byte hash value and reset the digest. - */ - abstract byte[] getDigest() throws SignatureException; - - /** - * Reset the digest. - */ - abstract void resetDigest(); - - /** - * Standard SHA1withDSA implementation. - */ - public static final class SHA1withDSA extends DSA { - - /* The SHA hash for the data */ - private final MessageDigest dataSHA; - - public SHA1withDSA() throws NoSuchAlgorithmException { - dataSHA = MessageDigest.getInstance("SHA-1"); - } - - /** - * Update a byte to be signed or verified. - */ - protected void engineUpdate(byte b) { - dataSHA.update(b); - } - - /** - * Update an array of bytes to be signed or verified. - */ - protected void engineUpdate(byte[] data, int off, int len) { - dataSHA.update(data, off, len); - } - - protected void engineUpdate(ByteBuffer b) { - dataSHA.update(b); - } - - byte[] getDigest() { - return dataSHA.digest(); - } - - void resetDigest() { - dataSHA.reset(); - } - } - - /** - * RawDSA implementation. - * - * RawDSA requires the data to be exactly 20 bytes long. If it is - * not, a SignatureException is thrown when sign()/verify() is called - * per JCA spec. - */ - public static final class RawDSA extends DSA { - - // length of the SHA-1 digest (20 bytes) - private final static int SHA1_LEN = 20; - - // 20 byte digest buffer - private final byte[] digestBuffer; - - // offset into the buffer - private int ofs; - - public RawDSA() { - digestBuffer = new byte[SHA1_LEN]; - } - - protected void engineUpdate(byte b) { - if (ofs == SHA1_LEN) { - ofs = SHA1_LEN + 1; - return; - } - digestBuffer[ofs++] = b; - } - - protected void engineUpdate(byte[] data, int off, int len) { - if (ofs + len > SHA1_LEN) { - ofs = SHA1_LEN + 1; - return; - } - System.arraycopy(data, off, digestBuffer, ofs, len); - ofs += len; - } - - byte[] getDigest() throws SignatureException { - if (ofs != SHA1_LEN) { - throw new SignatureException - ("Data for RawDSA must be exactly 20 bytes long"); - } - ofs = 0; - return digestBuffer; - } - - void resetDigest() { - ofs = 0; - } + this.md = md; } /** @@ -217,13 +108,25 @@ abstract class DSA extends SignatureSpi { throw new InvalidKeyException("not a DSA private key: " + privateKey); } + java.security.interfaces.DSAPrivateKey priv = (java.security.interfaces.DSAPrivateKey)privateKey; + + // check for algorithm specific constraints before doing initialization + DSAParams params = priv.getParams(); + if (params == null) { + throw new InvalidKeyException("DSA private key lacks parameters"); + } + checkKey(params); + + this.params = params; this.presetX = priv.getX(); this.presetY = null; - initialize(priv.getParams()); + this.presetP = params.getP(); + this.presetQ = params.getQ(); + this.presetG = params.getG(); + this.md.reset(); } - /** * Initialize the DSA object with a DSA public key. * @@ -240,16 +143,42 @@ abstract class DSA extends SignatureSpi { } java.security.interfaces.DSAPublicKey pub = (java.security.interfaces.DSAPublicKey)publicKey; + + // check for algorithm specific constraints before doing initialization + DSAParams params = pub.getParams(); + if (params == null) { + throw new InvalidKeyException("DSA public key lacks parameters"); + } + checkKey(params); + + this.params = params; this.presetY = pub.getY(); this.presetX = null; - initialize(pub.getParams()); + this.presetP = params.getP(); + this.presetQ = params.getQ(); + this.presetG = params.getG(); + this.md.reset(); } - private void initialize(DSAParams params) throws InvalidKeyException { - resetDigest(); - setParams(params); + /** + * Update a byte to be signed or verified. + */ + protected void engineUpdate(byte b) { + md.update(b); } + /** + * Update an array of bytes to be signed or verified. + */ + protected void engineUpdate(byte[] data, int off, int len) { + md.update(data, off, len); + } + + protected void engineUpdate(ByteBuffer b) { + md.update(b); + } + + /** * Sign all the data thus far updated. The signature is formatted * according to the Canonical Encoding Rules, returned as a DER @@ -352,23 +281,51 @@ abstract class DSA extends SignatureSpi { } } + @Deprecated + protected void engineSetParameter(String key, Object param) { + throw new InvalidParameterException("No parameter accepted"); + } + + @Deprecated + protected Object engineGetParameter(String key) { + return null; + } + + protected void checkKey(DSAParams params) throws InvalidKeyException { + // FIPS186-3 states in sec4.2 that a hash function which provides + // a lower security strength than the (L, N) pair ordinarily should + // not be used. + int valueN = params.getQ().bitLength(); + if (valueN > md.getDigestLength()*8) { + throw new InvalidKeyException("Key is too strong for this signature algorithm"); + } + } + private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g, BigInteger k) { BigInteger temp = g.modPow(k, p); - return temp.remainder(q); - } + return temp.mod(q); + } private BigInteger generateS(BigInteger x, BigInteger q, BigInteger r, BigInteger k) throws SignatureException { - byte[] s2 = getDigest(); - BigInteger temp = new BigInteger(1, s2); + byte[] s2; + try { + s2 = md.digest(); + } catch (RuntimeException re) { + // Only for RawDSA due to its 20-byte length restriction + throw new SignatureException(re.getMessage()); + } + // get the leftmost min(N, outLen) bits of the digest value + int nBytes = q.bitLength()/8; + if (nBytes < s2.length) { + s2 = Arrays.copyOfRange(s2, 0, nBytes); + } + BigInteger z = new BigInteger(1, s2); BigInteger k1 = k.modInverse(q); - BigInteger s = x.multiply(r); - s = temp.add(s); - s = k1.multiply(s); - return s.remainder(q); + return x.multiply(r).add(z).multiply(k1).mod(q); } private BigInteger generateW(BigInteger p, BigInteger q, @@ -380,54 +337,41 @@ abstract class DSA extends SignatureSpi { BigInteger q, BigInteger g, BigInteger w, BigInteger r) throws SignatureException { - byte[] s2 = getDigest(); - BigInteger temp = new BigInteger(1, s2); + byte[] s2; + try { + s2 = md.digest(); + } catch (RuntimeException re) { + // Only for RawDSA due to its 20-byte length restriction + throw new SignatureException(re.getMessage()); + } + // get the leftmost min(N, outLen) bits of the digest value + int nBytes = q.bitLength()/8; + if (nBytes < s2.length) { + s2 = Arrays.copyOfRange(s2, 0, nBytes); + } + BigInteger z = new BigInteger(1, s2); - temp = temp.multiply(w); - BigInteger u1 = temp.remainder(q); - - BigInteger u2 = (r.multiply(w)).remainder(q); + BigInteger u1 = z.multiply(w).mod(q); + BigInteger u2 = (r.multiply(w)).mod(q); BigInteger t1 = g.modPow(u1,p); BigInteger t2 = y.modPow(u2,p); BigInteger t3 = t1.multiply(t2); - BigInteger t5 = t3.remainder(p); - return t5.remainder(q); + BigInteger t5 = t3.mod(p); + return t5.mod(q); } - /* - * Please read bug report 4044247 for an alternative, faster, - * NON-FIPS approved method to generate K - */ - private BigInteger generateK(BigInteger q) { - - BigInteger k = null; - - // The application specified a Kseed for us to use. - // Note that we do not allow usage of the same Kseed twice in a row - if (Kseed != null && !Arrays.equals(Kseed, previousKseed)) { - k = generateK(Kseed, q); - if (k.signum() > 0 && k.compareTo(q) < 0) { - previousKseed = new int [Kseed.length]; - System.arraycopy(Kseed, 0, previousKseed, 0, Kseed.length); - return k; - } - } - - // The application did not specify a Kseed for us to use. - // We'll generate a new Kseed by getting random bytes from - // a SecureRandom object. + // NOTE: This following impl is defined in FIPS 186-3 AppendixB.2.2. + // Original DSS algos such as SHA1withDSA and RawDSA uses a different + // algorithm defined in FIPS 186-1 Sec3.2, and thus need to override this. + protected BigInteger generateK(BigInteger q) { SecureRandom random = getSigningRandom(); + byte[] kValue = new byte[q.bitLength()/8]; while (true) { - int[] seed = new int[5]; - - for (int i = 0; i < 5; i++) - seed[i] = random.nextInt(); - k = generateK(seed, q); + random.nextBytes(kValue); + BigInteger k = new BigInteger(1, kValue).mod(q); if (k.signum() > 0 && k.compareTo(q) < 0) { - previousKseed = new int [seed.length]; - System.arraycopy(seed, 0, previousKseed, 0, seed.length); return k; } } @@ -435,7 +379,7 @@ abstract class DSA extends SignatureSpi { // Use the application-specified SecureRandom Object if provided. // Otherwise, use our default SecureRandom Object. - private SecureRandom getSigningRandom() { + protected SecureRandom getSigningRandom() { if (signingRandom == null) { if (appRandom != null) { signingRandom = appRandom; @@ -446,171 +390,6 @@ abstract class DSA extends SignatureSpi { return signingRandom; } - /** - * Compute k for a DSA signature. - * - * @param seed the seed for generating k. This seed should be - * secure. This is what is refered to as the KSEED in the DSA - * specification. - * - * @param g the g parameter from the DSA key pair. - */ - private BigInteger generateK(int[] seed, BigInteger q) { - - // check out t in the spec. - int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476, - 0xC3D2E1F0, 0x67452301 }; - // - int[] tmp = DSA.SHA_7(seed, t); - byte[] tmpBytes = new byte[tmp.length * 4]; - for (int i = 0; i < tmp.length; i++) { - int k = tmp[i]; - for (int j = 0; j < 4; j++) { - tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8))); - } - } - BigInteger k = new BigInteger(1, tmpBytes).mod(q); - return k; - } - - // Constants for each round - private static final int round1_kt = 0x5a827999; - private static final int round2_kt = 0x6ed9eba1; - private static final int round3_kt = 0x8f1bbcdc; - private static final int round4_kt = 0xca62c1d6; - - /** - * Computes set 1 thru 7 of SHA-1 on m1. */ - static int[] SHA_7(int[] m1, int[] h) { - - int[] W = new int[80]; - System.arraycopy(m1,0,W,0,m1.length); - int temp = 0; - - for (int t = 16; t <= 79; t++){ - temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; - W[t] = ((temp << 1) | (temp >>>(32 - 1))); - } - - int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4]; - for (int i = 0; i < 20; i++) { - temp = ((a<<5) | (a>>>(32-5))) + - ((b&c)|((~b)&d))+ e + W[i] + round1_kt; - e = d; - d = c; - c = ((b<<30) | (b>>>(32-30))); - b = a; - a = temp; - } - - // Round 2 - for (int i = 20; i < 40; i++) { - temp = ((a<<5) | (a>>>(32-5))) + - (b ^ c ^ d) + e + W[i] + round2_kt; - e = d; - d = c; - c = ((b<<30) | (b>>>(32-30))); - b = a; - a = temp; - } - - // Round 3 - for (int i = 40; i < 60; i++) { - temp = ((a<<5) | (a>>>(32-5))) + - ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt; - e = d; - d = c; - c = ((b<<30) | (b>>>(32-30))); - b = a; - a = temp; - } - - // Round 4 - for (int i = 60; i < 80; i++) { - temp = ((a<<5) | (a>>>(32-5))) + - (b ^ c ^ d) + e + W[i] + round4_kt; - e = d; - d = c; - c = ((b<<30) | (b>>>(32-30))); - b = a; - a = temp; - } - int[] md = new int[5]; - md[0] = h[0] + a; - md[1] = h[1] + b; - md[2] = h[2] + c; - md[3] = h[3] + d; - md[4] = h[4] + e; - return md; - } - - - /** - * This implementation recognizes the following parameter:

- * - *
Kseed - * - *
a byte array. - * - *
- * - * @deprecated - */ - @Deprecated - protected void engineSetParameter(String key, Object param) { - if (key.equals("KSEED")) { - if (param instanceof byte[]) { - Kseed = byteArray2IntArray((byte[])param); - KseedAsByteArray = (byte[])param; - } else { - debug("unrecognized param: " + key); - throw new InvalidParameterException("Kseed not a byte array"); - } - } else { - throw new InvalidParameterException("invalid parameter"); - } - } - - /** - * Return the value of the requested parameter. Recognized - * parameters are: - * - *
- * - *
Kseed - * - *
a byte array. - * - *
- * - * @return the value of the requested parameter. - * - * @see java.security.SignatureEngine - * - * @deprecated - */ - @Deprecated - protected Object engineGetParameter(String key) { - if (key.equals("KSEED")) { - return KseedAsByteArray; - } else { - return null; - } - } - - /** - * Set the algorithm object. - */ - private void setParams(DSAParams params) throws InvalidKeyException { - if (params == null) { - throw new InvalidKeyException("DSA public key lacks parameters"); - } - this.params = params; - this.presetP = params.getP(); - this.presetQ = params.getQ(); - this.presetG = params.getG(); - } - /** * Return a human readable rendition of the engine. */ @@ -632,38 +411,6 @@ abstract class DSA extends SignatureSpi { return printable; } - /* - * Utility routine for converting a byte array into an int array - */ - private int[] byteArray2IntArray(byte[] byteArray) { - - int j = 0; - byte[] newBA; - int mod = byteArray.length % 4; - - // guarantee that the incoming byteArray is a multiple of 4 - // (pad with 0's) - switch (mod) { - case 3: newBA = new byte[byteArray.length + 1]; break; - case 2: newBA = new byte[byteArray.length + 2]; break; - case 1: newBA = new byte[byteArray.length + 3]; break; - default: newBA = new byte[byteArray.length + 0]; break; - } - System.arraycopy(byteArray, 0, newBA, 0, byteArray.length); - - // copy each set of 4 bytes in the byte array into an integer - int[] newSeed = new int[newBA.length / 4]; - for (int i = 0; i < newBA.length; i += 4) { - newSeed[j] = newBA[i + 3] & 0xFF; - newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00; - newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000; - newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000; - j++; - } - - return newSeed; - } - private static void debug(Exception e) { if (debug) { e.printStackTrace(); @@ -675,4 +422,325 @@ abstract class DSA extends SignatureSpi { System.err.println(s); } } + + /** + * Standard SHA224withDSA implementation as defined in FIPS186-3. + */ + public static final class SHA224withDSA extends DSA { + public SHA224withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-224")); + } + } + + /** + * Standard SHA256withDSA implementation as defined in FIPS186-3. + */ + public static final class SHA256withDSA extends DSA { + public SHA256withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-256")); + } + } + + static class LegacyDSA extends DSA { + /* The random seed used to generate k */ + private int[] kSeed; + /* The random seed used to generate k (specified by application) */ + private byte[] kSeedAsByteArray; + /* + * The random seed used to generate k + * (prevent the same Kseed from being used twice in a row + */ + private int[] kSeedLast; + + public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException { + super(md); + } + + @Deprecated + protected void engineSetParameter(String key, Object param) { + if (key.equals("KSEED")) { + if (param instanceof byte[]) { + kSeed = byteArray2IntArray((byte[])param); + kSeedAsByteArray = (byte[])param; + } else { + debug("unrecognized param: " + key); + throw new InvalidParameterException("kSeed not a byte array"); + } + } else { + throw new InvalidParameterException("Unsupported parameter"); + } + } + + @Deprecated + protected Object engineGetParameter(String key) { + if (key.equals("KSEED")) { + return kSeedAsByteArray; + } else { + return null; + } + } + + @Override + protected void checkKey(DSAParams params) throws InvalidKeyException { + int valueL = params.getP().bitLength(); + if (valueL > 1024) { + throw new InvalidKeyException("Key is too long for this algorithm"); + } + } + + /* + * Please read bug report 4044247 for an alternative, faster, + * NON-FIPS approved method to generate K + */ + @Override + protected BigInteger generateK(BigInteger q) { + BigInteger k = null; + + // The application specified a kSeed for us to use. + // Note: we dis-allow usage of the same Kseed twice in a row + if (kSeed != null && !Arrays.equals(kSeed, kSeedLast)) { + k = generateKUsingKSeed(kSeed, q); + if (k.signum() > 0 && k.compareTo(q) < 0) { + kSeedLast = kSeed.clone(); + return k; + } + } + + // The application did not specify a Kseed for us to use. + // We'll generate a new Kseed by getting random bytes from + // a SecureRandom object. + SecureRandom random = getSigningRandom(); + + while (true) { + int[] seed = new int[5]; + + for (int i = 0; i < 5; i++) seed[i] = random.nextInt(); + + k = generateKUsingKSeed(seed, q); + if (k.signum() > 0 && k.compareTo(q) < 0) { + kSeedLast = seed; + return k; + } + } + } + + /** + * Compute k for the DSA signature as defined in the original DSS, + * i.e. FIPS186. + * + * @param seed the seed for generating k. This seed should be + * secure. This is what is refered to as the KSEED in the DSA + * specification. + * + * @param g the g parameter from the DSA key pair. + */ + private BigInteger generateKUsingKSeed(int[] seed, BigInteger q) { + + // check out t in the spec. + int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476, + 0xC3D2E1F0, 0x67452301 }; + // + int[] tmp = SHA_7(seed, t); + byte[] tmpBytes = new byte[tmp.length * 4]; + for (int i = 0; i < tmp.length; i++) { + int k = tmp[i]; + for (int j = 0; j < 4; j++) { + tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8))); + } + } + BigInteger k = new BigInteger(1, tmpBytes).mod(q); + return k; + } + + // Constants for each round + private static final int round1_kt = 0x5a827999; + private static final int round2_kt = 0x6ed9eba1; + private static final int round3_kt = 0x8f1bbcdc; + private static final int round4_kt = 0xca62c1d6; + + /** + * Computes set 1 thru 7 of SHA-1 on m1. */ + static int[] SHA_7(int[] m1, int[] h) { + + int[] W = new int[80]; + System.arraycopy(m1,0,W,0,m1.length); + int temp = 0; + + for (int t = 16; t <= 79; t++){ + temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = ((temp << 1) | (temp >>>(32 - 1))); + } + + int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4]; + for (int i = 0; i < 20; i++) { + temp = ((a<<5) | (a>>>(32-5))) + + ((b&c)|((~b)&d))+ e + W[i] + round1_kt; + e = d; + d = c; + c = ((b<<30) | (b>>>(32-30))); + b = a; + a = temp; + } + + // Round 2 + for (int i = 20; i < 40; i++) { + temp = ((a<<5) | (a>>>(32-5))) + + (b ^ c ^ d) + e + W[i] + round2_kt; + e = d; + d = c; + c = ((b<<30) | (b>>>(32-30))); + b = a; + a = temp; + } + + // Round 3 + for (int i = 40; i < 60; i++) { + temp = ((a<<5) | (a>>>(32-5))) + + ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt; + e = d; + d = c; + c = ((b<<30) | (b>>>(32-30))); + b = a; + a = temp; + } + + // Round 4 + for (int i = 60; i < 80; i++) { + temp = ((a<<5) | (a>>>(32-5))) + + (b ^ c ^ d) + e + W[i] + round4_kt; + e = d; + d = c; + c = ((b<<30) | (b>>>(32-30))); + b = a; + a = temp; + } + int[] md = new int[5]; + md[0] = h[0] + a; + md[1] = h[1] + b; + md[2] = h[2] + c; + md[3] = h[3] + d; + md[4] = h[4] + e; + return md; + } + + /* + * Utility routine for converting a byte array into an int array + */ + private int[] byteArray2IntArray(byte[] byteArray) { + + int j = 0; + byte[] newBA; + int mod = byteArray.length % 4; + + // guarantee that the incoming byteArray is a multiple of 4 + // (pad with 0's) + switch (mod) { + case 3: newBA = new byte[byteArray.length + 1]; break; + case 2: newBA = new byte[byteArray.length + 2]; break; + case 1: newBA = new byte[byteArray.length + 3]; break; + default: newBA = new byte[byteArray.length + 0]; break; + } + System.arraycopy(byteArray, 0, newBA, 0, byteArray.length); + + // copy each set of 4 bytes in the byte array into an integer + int[] newSeed = new int[newBA.length / 4]; + for (int i = 0; i < newBA.length; i += 4) { + newSeed[j] = newBA[i + 3] & 0xFF; + newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00; + newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000; + newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000; + j++; + } + + return newSeed; + } + } + + public static final class SHA1withDSA extends LegacyDSA { + public SHA1withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-1")); + } + } + + /** + * RawDSA implementation. + * + * RawDSA requires the data to be exactly 20 bytes long. If it is + * not, a SignatureException is thrown when sign()/verify() is called + * per JCA spec. + */ + public static final class RawDSA extends LegacyDSA { + // Internal special-purpose MessageDigest impl for RawDSA + // Only override whatever methods used + // NOTE: no clone support + public static final class NullDigest20 extends MessageDigest { + // 20 byte digest buffer + private final byte[] digestBuffer = new byte[20]; + + // offset into the buffer; use Integer.MAX_VALUE to indicate + // out-of-bound condition + private int ofs = 0; + + protected NullDigest20() { + super("NullDigest20"); + } + protected void engineUpdate(byte input) { + if (ofs == digestBuffer.length) { + ofs = Integer.MAX_VALUE; + } else { + digestBuffer[ofs++] = input; + } + } + protected void engineUpdate(byte[] input, int offset, int len) { + if (ofs + len > digestBuffer.length) { + ofs = Integer.MAX_VALUE; + } else { + System.arraycopy(input, offset, digestBuffer, ofs, len); + ofs += len; + } + } + protected final void engineUpdate(ByteBuffer input) { + int inputLen = input.remaining(); + if (ofs + inputLen > digestBuffer.length) { + ofs = Integer.MAX_VALUE; + } else { + input.get(digestBuffer, ofs, inputLen); + ofs += inputLen; + } + } + protected byte[] engineDigest() throws RuntimeException { + if (ofs != digestBuffer.length) { + throw new RuntimeException + ("Data for RawDSA must be exactly 20 bytes long"); + } + reset(); + return digestBuffer; + } + protected int engineDigest(byte[] buf, int offset, int len) + throws DigestException { + if (ofs != digestBuffer.length) { + throw new DigestException + ("Data for RawDSA must be exactly 20 bytes long"); + } + if (len < digestBuffer.length) { + throw new DigestException + ("Output buffer too small; must be at least 20 bytes"); + } + System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length); + reset(); + return digestBuffer.length; + } + + protected void engineReset() { + ofs = 0; + } + protected final int engineGetDigestLength() { + return digestBuffer.length; + } + } + + public RawDSA() throws NoSuchAlgorithmException { + super(new NullDigest20()); + } + } } diff --git a/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java b/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java index 9adab7b6b6e..579d60e0fea 100644 --- a/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java +++ b/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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 @@ -48,8 +48,9 @@ import sun.security.jca.JCAUtil; public class DSAKeyPairGenerator extends KeyPairGenerator implements java.security.interfaces.DSAKeyPairGenerator { - /* The modulus length */ - private int modlen; + /* Length for prime P and subPrime Q in bits */ + private int plen; + private int qlen; /* whether to force new parameters to be generated for each KeyPair */ private boolean forceNewParameters; @@ -65,20 +66,23 @@ implements java.security.interfaces.DSAKeyPairGenerator { initialize(1024, null); } - private static void checkStrength(int strength) { - if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) { + private static void checkStrength(int sizeP, int sizeQ) { + if ((sizeP >= 512) && (sizeP <= 1024) && (sizeP % 64 == 0) + && sizeQ == 160) { + // traditional - allow for backward compatibility + // L=multiples of 64 and between 512 and 1024 (inclusive) + // N=160 + } else if (sizeP == 2048 && (sizeQ == 224 || sizeQ == 256)) { + // L=2048, N=224 or 256 + } else { throw new InvalidParameterException - ("Modulus size must range from 512 to 1024 " - + "and be a multiple of 64"); + ("Unsupported prime and subprime size combination: " + + sizeP + ", " + sizeQ); } } public void initialize(int modlen, SecureRandom random) { - checkStrength(modlen); - this.random = random; - this.modlen = modlen; - this.params = null; - this.forceNewParameters = false; + initialize(modlen, false, random); } /** @@ -86,18 +90,27 @@ implements java.security.interfaces.DSAKeyPairGenerator { * is false, a set of pre-computed parameters is used. */ public void initialize(int modlen, boolean genParams, SecureRandom random) { - checkStrength(modlen); + int subPrimeLen = -1; + if (modlen <= 1024) { + subPrimeLen = 160; + } else if (modlen == 2048) { + subPrimeLen = 224; + } + checkStrength(modlen, subPrimeLen); if (genParams) { params = null; } else { - params = ParameterCache.getCachedDSAParameterSpec(modlen); + params = ParameterCache.getCachedDSAParameterSpec(modlen, + subPrimeLen); if (params == null) { throw new InvalidParameterException ("No precomputed parameters for requested modulus size " + "available"); } + } - this.modlen = modlen; + this.plen = modlen; + this.qlen = subPrimeLen; this.random = random; this.forceNewParameters = genParams; } @@ -136,9 +149,11 @@ implements java.security.interfaces.DSAKeyPairGenerator { } private void initialize0(DSAParameterSpec params, SecureRandom random) { - int modlen = params.getP().bitLength(); - checkStrength(modlen); - this.modlen = modlen; + int sizeP = params.getP().bitLength(); + int sizeQ = params.getQ().bitLength(); + checkStrength(sizeP, sizeQ); + this.plen = sizeP; + this.qlen = sizeQ; this.params = params; this.random = random; this.forceNewParameters = false; @@ -156,11 +171,11 @@ implements java.security.interfaces.DSAKeyPairGenerator { try { if (forceNewParameters) { // generate new parameters each time - spec = ParameterCache.getNewDSAParameterSpec(modlen, random); + spec = ParameterCache.getNewDSAParameterSpec(plen, qlen, random); } else { if (params == null) { params = - ParameterCache.getDSAParameterSpec(modlen, random); + ParameterCache.getDSAParameterSpec(plen, qlen, random); } spec = params; } @@ -203,43 +218,14 @@ implements java.security.interfaces.DSAKeyPairGenerator { */ private BigInteger generateX(SecureRandom random, BigInteger q) { BigInteger x = null; + byte[] temp = new byte[qlen]; while (true) { - int[] seed = new int[5]; - for (int i = 0; i < 5; i++) { - seed[i] = random.nextInt(); - } - x = generateX(seed, q); + random.nextBytes(temp); + x = new BigInteger(1, temp).mod(q); if (x.signum() > 0 && (x.compareTo(q) < 0)) { - break; + return x; } } - return x; - } - - /** - * Given a seed, generate the private key component of the key - * pair. In the terminology used in the DSA specification - * (FIPS-186) seed is the XSEED quantity. - * - * @param seed the seed to use to generate the private key. - */ - BigInteger generateX(int[] seed, BigInteger q) { - - // check out t in the spec. - int[] t = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, - 0x10325476, 0xC3D2E1F0 }; - // - - int[] tmp = DSA.SHA_7(seed, t); - byte[] tmpBytes = new byte[tmp.length * 4]; - for (int i = 0; i < tmp.length; i++) { - int k = tmp[i]; - for (int j = 0; j < 4; j++) { - tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8))); - } - } - BigInteger x = new BigInteger(1, tmpBytes).mod(q); - return x; } /** diff --git a/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java b/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java index 953d7151166..9c6be21d580 100644 --- a/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java +++ b/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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,10 +32,12 @@ import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.InvalidParameterException; +import java.security.MessageDigest; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.spec.DSAParameterSpec; +import java.security.spec.DSAGenParameterSpec; /** * This class generates parameters for the DSA algorithm. It uses a default @@ -54,8 +56,14 @@ import java.security.spec.DSAParameterSpec; public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { - // the modulus length - private int modLen = 1024; // default + // the default parameters + private static final DSAGenParameterSpec DEFAULTS = + new DSAGenParameterSpec(1024, 160, 160); + + // the length of prime P, subPrime Q, and seed in bits + private int valueL = -1; + private int valueN = -1; + private int seedLen = -1; // the source of randomness private SecureRandom random; @@ -65,11 +73,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); - // Make a SHA-1 hash function - private SHA sha; - public DSAParameterGenerator() { - this.sha = new SHA(); } /** @@ -80,19 +84,18 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { * @param random the source of randomness */ protected void engineInit(int strength, SecureRandom random) { - /* - * Bruce Schneier, "Applied Cryptography", 2nd Edition, - * Description of DSA: - * [...] The algorithm uses the following parameter: - * p=a prime number L bits long, when L ranges from 512 to 1024 and is - * a multiple of 64. [...] - */ - if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) { + if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) { + this.valueN = 160; + } else if (strength == 2048) { + this.valueN = 224; +// } else if (strength == 3072) { +// this.valueN = 256; + } else { throw new InvalidParameterException - ("Prime size must range from 512 to 1024 " - + "and be a multiple of 64"); + ("Prime size should be 512 - 1024, or 2048"); } - this.modLen = strength; + this.valueL = strength; + this.seedLen = valueN; this.random = random; } @@ -100,7 +103,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { * Initializes this parameter generator with a set of * algorithm-specific parameter generation values. * - * @param params the set of algorithm-specific parameter generation values + * @param genParamSpec the set of algorithm-specific parameter generation values * @param random the source of randomness * * @exception InvalidAlgorithmParameterException if the given parameter @@ -109,7 +112,19 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { protected void engineInit(AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { + if (!(genParamSpec instanceof DSAGenParameterSpec)) { throw new InvalidAlgorithmParameterException("Invalid parameter"); + } + DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec) genParamSpec; + if (dsaGenParams.getPrimePLength() > 2048) { + throw new InvalidParameterException + ("Prime size should be 512 - 1024, or 2048"); + } + // directly initialize using the already validated values + this.valueL = dsaGenParams.getPrimePLength(); + this.valueN = dsaGenParams.getSubprimeQLength(); + this.seedLen = dsaGenParams.getSeedLength(); + this.random = random; } /** @@ -123,15 +138,21 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { if (this.random == null) { this.random = new SecureRandom(); } - - BigInteger[] pAndQ = generatePandQ(this.random, this.modLen); + if (valueL == -1) { + try { + engineInit(DEFAULTS, this.random); + } catch (InvalidAlgorithmParameterException iape) { + // should never happen + } + } + BigInteger[] pAndQ = generatePandQ(this.random, valueL, + valueN, seedLen); BigInteger paramP = pAndQ[0]; BigInteger paramQ = pAndQ[1]; BigInteger paramG = generateG(paramP, paramQ); - DSAParameterSpec dsaParamSpec = new DSAParameterSpec(paramP, - paramQ, - paramG); + DSAParameterSpec dsaParamSpec = + new DSAParameterSpec(paramP, paramQ, paramG); algParams = AlgorithmParameters.getInstance("DSA", "SUN"); algParams.init(dsaParamSpec); } catch (InvalidParameterSpecException e) { @@ -156,102 +177,98 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { * * @param random the source of randomness to generate the * seed - * @param L the size of p, in bits. + * @param valueL the size of p, in bits. + * @param valueN the size of q, in bits. + * @param seedLen the length of seed, in bits. * * @return an array of BigInteger, with p at index 0 and - * q at index 1. - */ - BigInteger[] generatePandQ(SecureRandom random, int L) { - BigInteger[] result = null; - byte[] seed = new byte[20]; - - while(result == null) { - for (int i = 0; i < 20; i++) { - seed[i] = (byte)random.nextInt(); - } - result = generatePandQ(seed, L); - } - return result; - } - - /* - * Generates the prime and subprime parameters for DSA. - * - *

The seed parameter corresponds to the SEED parameter - * referenced in the FIPS specification of the DSA algorithm, - * and L is the size of p, in bits. - * - * @param seed the seed to generate the parameters - * @param L the size of p, in bits. - * - * @return an array of BigInteger, with p at index 0, * q at index 1, the seed at index 2, and the counter value - * at index 3, or null if the seed does not yield suitable numbers. + * at index 3. */ - BigInteger[] generatePandQ(byte[] seed, int L) { + private static BigInteger[] generatePandQ(SecureRandom random, int valueL, + int valueN, int seedLen) { + String hashAlg = null; + if (valueN == 160) { + hashAlg = "SHA"; + } else if (valueN == 224) { + hashAlg = "SHA-224"; + } else if (valueN == 256) { + hashAlg = "SHA-256"; + } + MessageDigest hashObj = null; + try { + hashObj = MessageDigest.getInstance(hashAlg); + } catch (NoSuchAlgorithmException nsae) { + // should never happen + nsae.printStackTrace(); + } - /* Useful variables */ - int g = seed.length * 8; - int n = (L - 1) / 160; - int b = (L - 1) % 160; + /* Step 3, 4: Useful variables */ + int outLen = hashObj.getDigestLength()*8; + int n = (valueL - 1) / outLen; + int b = (valueL - 1) % outLen; + byte[] seedBytes = new byte[seedLen/8]; + BigInteger twoSl = TWO.pow(seedLen); + int primeCertainty = 80; // for 1024-bit prime P + if (valueL == 2048) { + primeCertainty = 112; + //} else if (valueL == 3072) { + // primeCertainty = 128; + } - BigInteger SEED = new BigInteger(1, seed); - BigInteger TWOG = TWO.pow(2 * g); + BigInteger resultP, resultQ, seed = null; + int counter; + while (true) { + do { + /* Step 5 */ + random.nextBytes(seedBytes); + seed = new BigInteger(1, seedBytes); - /* Step 2 (Step 1 is getting seed). */ - byte[] U1 = SHA(seed); - byte[] U2 = SHA(toByteArray((SEED.add(ONE)).mod(TWOG))); + /* Step 6 */ + BigInteger U = new BigInteger(1, hashObj.digest(seedBytes)). + mod(TWO.pow(valueN - 1)); - xor(U1, U2); - byte[] U = U1; + /* Step 7 */ + resultQ = TWO.pow(valueN - 1).add(U).add(ONE). subtract(U.mod(TWO)); + } while (!resultQ.isProbablePrime(primeCertainty)); - /* Step 3: For q by setting the msb and lsb to 1 */ - U[0] |= 0x80; - U[19] |= 1; - BigInteger q = new BigInteger(1, U); - - /* Step 5 */ - if (!q.isProbablePrime(80)) { - return null; - - } else { - BigInteger V[] = new BigInteger[n + 1]; - BigInteger offset = TWO; - - /* Step 6 */ - for (int counter = 0; counter < 4096; counter++) { - - /* Step 7 */ - for (int k = 0; k <= n; k++) { - BigInteger K = BigInteger.valueOf(k); - BigInteger tmp = (SEED.add(offset).add(K)).mod(TWOG); - V[k] = new BigInteger(1, SHA(toByteArray(tmp))); - } - - /* Step 8 */ - BigInteger W = V[0]; - for (int i = 1; i < n; i++) { - W = W.add(V[i].multiply(TWO.pow(i * 160))); - } - W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * 160))); - - BigInteger TWOLm1 = TWO.pow(L - 1); - BigInteger X = W.add(TWOLm1); - - /* Step 9 */ - BigInteger c = X.mod(q.multiply(TWO)); - BigInteger p = X.subtract(c.subtract(ONE)); - - /* Step 10 - 13 */ - if (p.compareTo(TWOLm1) > -1 && p.isProbablePrime(80)) { - BigInteger[] result = {p, q, SEED, - BigInteger.valueOf(counter)}; - return result; - } - offset = offset.add(BigInteger.valueOf(n)).add(ONE); + /* Step 10 */ + BigInteger offset = ONE; + /* Step 11 */ + for (counter = 0; counter < 4*valueL; counter++) { + BigInteger V[] = new BigInteger[n + 1]; + /* Step 11.1 */ + for (int j = 0; j <= n; j++) { + BigInteger J = BigInteger.valueOf(j); + BigInteger tmp = (seed.add(offset).add(J)).mod(twoSl); + byte[] vjBytes = hashObj.digest(toByteArray(tmp)); + V[j] = new BigInteger(1, vjBytes); + } + /* Step 11.2 */ + BigInteger W = V[0]; + for (int i = 1; i < n; i++) { + W = W.add(V[i].multiply(TWO.pow(i * outLen))); + } + W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * outLen))); + /* Step 11.3 */ + BigInteger twoLm1 = TWO.pow(valueL - 1); + BigInteger X = W.add(twoLm1); + /* Step 11.4, 11.5 */ + BigInteger c = X.mod(resultQ.multiply(TWO)); + resultP = X.subtract(c.subtract(ONE)); + /* Step 11.6, 11.7 */ + if (resultP.compareTo(twoLm1) > -1 + && resultP.isProbablePrime(primeCertainty)) { + /* Step 11.8 */ + BigInteger[] result = {resultP, resultQ, seed, + BigInteger.valueOf(counter)}; + return result; + } + /* Step 11.9 */ + offset = offset.add(BigInteger.valueOf(n)).add(ONE); } - return null; - } + } + } /* @@ -262,31 +279,24 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { * * @param the g */ - BigInteger generateG(BigInteger p, BigInteger q) { + private static BigInteger generateG(BigInteger p, BigInteger q) { BigInteger h = ONE; + /* Step 1 */ BigInteger pMinusOneOverQ = (p.subtract(ONE)).divide(q); - BigInteger g = ONE; - while (g.compareTo(TWO) < 0) { - g = h.modPow(pMinusOneOverQ, p); + BigInteger resultG = ONE; + while (resultG.compareTo(TWO) < 0) { + /* Step 3 */ + resultG = h.modPow(pMinusOneOverQ, p); h = h.add(ONE); } - return g; - } - - /* - * Returns the SHA-1 digest of some data - */ - private byte[] SHA(byte[] array) { - sha.engineReset(); - sha.engineUpdate(array, 0, array.length); - return sha.engineDigest(); + return resultG; } /* * Converts the result of a BigInteger.toByteArray call to an exact * signed magnitude representation for any positive number. */ - private byte[] toByteArray(BigInteger bigInt) { + private static byte[] toByteArray(BigInteger bigInt) { byte[] result = bigInt.toByteArray(); if (result[0] == 0) { byte[] tmp = new byte[result.length - 1]; @@ -295,13 +305,4 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { } return result; } - - /* - * XORs U2 into U1 - */ - private void xor(byte[] U1, byte[] U2) { - for (int i = 0; i < U1.length; i++) { - U1[i] ^= U2[i]; - } - } } diff --git a/jdk/src/share/classes/sun/security/provider/ParameterCache.java b/jdk/src/share/classes/sun/security/provider/ParameterCache.java index f263fb7ea26..419bbd68522 100644 --- a/jdk/src/share/classes/sun/security/provider/ParameterCache.java +++ b/jdk/src/share/classes/sun/security/provider/ParameterCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package sun.security.provider; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.math.BigInteger; import java.security.*; @@ -55,11 +56,17 @@ public final class ParameterCache { private final static Map dhCache; /** - * Return cached DSA parameters for the given keylength, or null if none - * are available in the cache. + * Return cached DSA parameters for the given length combination of + * prime and subprime, or null if none are available in the cache. */ - public static DSAParameterSpec getCachedDSAParameterSpec(int keyLength) { - return dsaCache.get(Integer.valueOf(keyLength)); + public static DSAParameterSpec getCachedDSAParameterSpec(int primeLen, + int subprimeLen) { + // ensure the sum is unique in all cases, i.e. + // case#1: (512 <= p <= 1024) AND q=160 + // case#2: p=2048 AND q=224 + // case#3: p=2048 AND q=256 + // (NOT-YET-SUPPORTED)case#4: p=3072 AND q=256 + return dsaCache.get(Integer.valueOf(primeLen+subprimeLen)); } /** @@ -71,18 +78,39 @@ public final class ParameterCache { } /** - * Return DSA parameters for the given keylength. Uses cache if possible, - * generates new parameters and adds them to the cache otherwise. + * Return DSA parameters for the given primeLen. Uses cache if + * possible, generates new parameters and adds them to the cache + * otherwise. */ - public static DSAParameterSpec getDSAParameterSpec(int keyLength, + public static DSAParameterSpec getDSAParameterSpec(int primeLen, SecureRandom random) - throws NoSuchAlgorithmException, InvalidParameterSpecException { - DSAParameterSpec spec = getCachedDSAParameterSpec(keyLength); + throws NoSuchAlgorithmException, InvalidParameterSpecException, + InvalidAlgorithmParameterException { + if (primeLen <= 1024) { + return getDSAParameterSpec(primeLen, 160, random); + } else if (primeLen == 2048) { + return getDSAParameterSpec(primeLen, 224, random); + } else { + return null; + } + } + + /** + * Return DSA parameters for the given primeLen and subprimeLen. + * Uses cache if possible, generates new parameters and adds them to the + * cache otherwise. + */ + public static DSAParameterSpec getDSAParameterSpec(int primeLen, + int subprimeLen, SecureRandom random) + throws NoSuchAlgorithmException, InvalidParameterSpecException, + InvalidAlgorithmParameterException { + DSAParameterSpec spec = + getCachedDSAParameterSpec(primeLen, subprimeLen); if (spec != null) { return spec; } - spec = getNewDSAParameterSpec(keyLength, random); - dsaCache.put(Integer.valueOf(keyLength), spec); + spec = getNewDSAParameterSpec(primeLen, subprimeLen, random); + dsaCache.put(Integer.valueOf(primeLen + subprimeLen), spec); return spec; } @@ -107,28 +135,28 @@ public final class ParameterCache { } /** - * Return new DSA parameters for the given keylength. Do not lookup in - * cache and do not cache the newly generated parameters. This method - * really only exists for the legacy method + * Return new DSA parameters for the given length combination of prime and + * sub prime. Do not lookup in cache and do not cache the newly generated + * parameters. This method really only exists for the legacy method * DSAKeyPairGenerator.initialize(int, boolean, SecureRandom). */ - public static DSAParameterSpec getNewDSAParameterSpec(int keyLength, - SecureRandom random) - throws NoSuchAlgorithmException, InvalidParameterSpecException { + public static DSAParameterSpec getNewDSAParameterSpec(int primeLen, + int subprimeLen, SecureRandom random) + throws NoSuchAlgorithmException, InvalidParameterSpecException, + InvalidAlgorithmParameterException { AlgorithmParameterGenerator gen = AlgorithmParameterGenerator.getInstance("DSA"); - gen.init(keyLength, random); + DSAGenParameterSpec genParams = + new DSAGenParameterSpec(primeLen, subprimeLen); + gen.init(genParams, random); AlgorithmParameters params = gen.generateParameters(); DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class); return spec; } static { - // XXX change to ConcurrentHashMap once available - dhCache = Collections.synchronizedMap - (new HashMap()); - dsaCache = Collections.synchronizedMap - (new HashMap()); + dhCache = new ConcurrentHashMap(); + dsaCache = new ConcurrentHashMap(); /* * We support precomputed parameter for 512, 768 and 1024 bit @@ -210,17 +238,99 @@ public final class ParameterCache { "83dfe15ae59f06928b665e807b552564014c3bfecf" + "492a", 16); - dsaCache.put(Integer.valueOf(512), + dsaCache.put(Integer.valueOf(512+160), new DSAParameterSpec(p512, q512, g512)); - dsaCache.put(Integer.valueOf(768), + dsaCache.put(Integer.valueOf(768+160), new DSAParameterSpec(p768, q768, g768)); - dsaCache.put(Integer.valueOf(1024), + dsaCache.put(Integer.valueOf(1024+160), new DSAParameterSpec(p1024, q1024, g1024)); + /* + * L = 2048, N = 224 + * SEED = 584236080cfa43c09b02354135f4cc5198a19efada08bd866d601ba4 + * counter = 2666 + */ + BigInteger p2048_224 = + new BigInteger("8f7935d9b9aae9bfabed887acf4951b6f32ec59e3b" + + "af3718e8eac4961f3efd3606e74351a9c4183339b8" + + "09e7c2ae1c539ba7475b85d011adb8b47987754984" + + "695cac0e8f14b3360828a22ffa27110a3d62a99345" + + "3409a0fe696c4658f84bdd20819c3709a01057b195" + + "adcd00233dba5484b6291f9d648ef883448677979c" + + "ec04b434a6ac2e75e9985de23db0292fc1118c9ffa" + + "9d8181e7338db792b730d7b9e349592f6809987215" + + "3915ea3d6b8b4653c633458f803b32a4c2e0f27290" + + "256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea1" + + "43de4b66ff04903ed5cf1623e158d487c608e97f21" + + "1cd81dca23cb6e380765f822e342be484c05763939" + + "601cd667", 16); + + BigInteger q2048_224 = + new BigInteger("baf696a68578f7dfdee7fa67c977c785ef32b233ba" + + "e580c0bcd5695d", 16); + + BigInteger g2048_224 = + new BigInteger("16a65c58204850704e7502a39757040d34da3a3478" + + "c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f" + + "37eeb1e09f3182d23c9043cb642f88004160edf9ca" + + "09b32076a79c32a627f2473e91879ba2c4e744bd20" + + "81544cb55b802c368d1fa83ed489e94e0fa0688e32" + + "428a5c78c478c68d0527b71c9a3abb0b0be12c4468" + + "9639e7d3ce74db101a65aa2b87f64c6826db3ec72f" + + "4b5599834bb4edb02f7c90e9a496d3a55d535bebfc" + + "45d4f619f63f3dedbb873925c2f224e07731296da8" + + "87ec1e4748f87efb5fdeb75484316b2232dee553dd" + + "af02112b0d1f02da30973224fe27aeda8b9d4b2922" + + "d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1" + + "ef17dbde", 16); + dsaCache.put(Integer.valueOf(2048+224), + new DSAParameterSpec(p2048_224, q2048_224, g2048_224)); + + /* + * L = 2048, N = 256 + * SEED = b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536 + * counter = 497 + */ + BigInteger p2048_256 = + new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c721" + + "0313bb45fb4d5bb2e5fe1cbd678cd4bbdd84c9836b" + + "e1f31c0777725aeb6c2fc38b85f48076fa76bcd814" + + "6cc89a6fb2f706dd719898c2083dc8d896f84062e2" + + "c9c94d137b054a8d8096adb8d51952398eeca852a0" + + "af12df83e475aa65d4ec0c38a9560d5661186ff98b" + + "9fc9eb60eee8b030376b236bc73be3acdbd74fd61c" + + "1d2475fa3077b8f080467881ff7e1ca56fee066d79" + + "506ade51edbb5443a563927dbc4ba520086746175c" + + "8885925ebc64c6147906773496990cb714ec667304" + + "e261faee33b3cbdf008e0c3fa90650d97d3909c927" + + "5bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" + + "a406cb0b", 16); + + BigInteger q2048_256 = + new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43" + + "ca0ec572e37e09939a9773", 16); + + BigInteger g2048_256 = + new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b" + + "889a74aaf53174aa0fbe7e3c5b8fcd7a53bef563b0" + + "e98560328960a9517f4014d3325fc7962bf1e04937" + + "0d76d1314a76137e792f3f0db859d095e4a5b93202" + + "4f079ecf2ef09c797452b0770e1350782ed57ddf79" + + "4979dcef23cb96f183061965c4ebc93c9c71c56b92" + + "5955a75f94cccf1449ac43d586d0beee43251b0b22" + + "87349d68de0d144403f13e802f4146d882e057af19" + + "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f" + + "695e347d8d1cf9ac819a26ca9b04cb0eb9b7b03598" + + "8d15bbac65212a55239cfc7e58fae38d7250ab9991" + + "ffbc97134025fe8ce04c4399ad96569be91a546f49" + + "78693c7a", 16); + dsaCache.put(Integer.valueOf(2048+256), + new DSAParameterSpec(p2048_256, q2048_256, g2048_256)); // use DSA parameters for DH as well dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512)); dhCache.put(Integer.valueOf(768), new DHParameterSpec(p768, g768)); dhCache.put(Integer.valueOf(1024), new DHParameterSpec(p1024, g1024)); + dhCache.put(Integer.valueOf(2048), new DHParameterSpec(p2048_224, g2048_224)); } } diff --git a/jdk/src/share/classes/sun/security/provider/SunEntries.java b/jdk/src/share/classes/sun/security/provider/SunEntries.java index 3f0ef1084ce..3876acbf3be 100644 --- a/jdk/src/share/classes/sun/security/provider/SunEntries.java +++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java @@ -47,6 +47,10 @@ import java.security.*; * SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384, * and SHA-512. * + * - SHA-224withDSA/SHA-256withDSA are the signature schemes + * described in FIPS 186-3. The associated object identifiers are + * "OID.2.16.840.1.101.3.4.3.1", and "OID.2.16.840.1.101.3.4.3.2". + * - DSA is the key generation scheme as described in FIPS 186. * Aliases for DSA include the OID strings "OID.1.3.14.3.2.12" * and "OID.1.2.840.10040.4.1". @@ -106,11 +110,15 @@ final class SunEntries { map.put("Signature.SHA1withDSA", "sun.security.provider.DSA$SHA1withDSA"); map.put("Signature.NONEwithDSA", "sun.security.provider.DSA$RawDSA"); map.put("Alg.Alias.Signature.RawDSA", "NONEwithDSA"); + map.put("Signature.SHA224withDSA", "sun.security.provider.DSA$SHA224withDSA"); + map.put("Signature.SHA256withDSA", "sun.security.provider.DSA$SHA256withDSA"); String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" + "|java.security.interfaces.DSAPrivateKey"; map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses); map.put("Signature.NONEwithDSA SupportedKeyClasses", dsaKeyClasses); + map.put("Signature.SHA224withDSA SupportedKeyClasses", dsaKeyClasses); + map.put("Signature.SHA256withDSA SupportedKeyClasses", dsaKeyClasses); map.put("Alg.Alias.Signature.DSA", "SHA1withDSA"); map.put("Alg.Alias.Signature.DSS", "SHA1withDSA"); @@ -124,6 +132,10 @@ final class SunEntries { map.put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA"); map.put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA"); map.put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA"); + map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.1", "SHA224withDSA"); + map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.1", "SHA224withDSA"); + map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.2", "SHA256withDSA"); + map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.2", "SHA256withDSA"); /* * Key Pair Generator engines @@ -143,6 +155,8 @@ final class SunEntries { map.put("Alg.Alias.MessageDigest.SHA-1", "SHA"); map.put("Alg.Alias.MessageDigest.SHA1", "SHA"); + map.put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA"); + map.put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA"); map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224"); map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224"); @@ -169,15 +183,17 @@ final class SunEntries { */ map.put("AlgorithmParameters.DSA", "sun.security.provider.DSAParameters"); - map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA"); + map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.1", "DSA"); map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA"); + map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA"); /* * Key factories */ map.put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory"); - map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); + map.put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA"); map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); + map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); /* * Certificates @@ -234,9 +250,13 @@ final class SunEntries { /* * KeySize */ + map.put("Signature.NONEwithDSA KeySize", "1024"); map.put("Signature.SHA1withDSA KeySize", "1024"); - map.put("KeyPairGenerator.DSA KeySize", "1024"); - map.put("AlgorithmParameterGenerator.DSA KeySize", "1024"); + map.put("Signature.SHA224withDSA KeySize", "2048"); + map.put("Signature.SHA256withDSA KeySize", "2048"); + + map.put("KeyPairGenerator.DSA KeySize", "2048"); + map.put("AlgorithmParameterGenerator.DSA KeySize", "2048"); /* * Implementation type: software or hardware diff --git a/jdk/src/share/classes/sun/security/x509/AlgorithmId.java b/jdk/src/share/classes/sun/security/x509/AlgorithmId.java index d4ca7959970..e2d6c60c111 100644 --- a/jdk/src/share/classes/sun/security/x509/AlgorithmId.java +++ b/jdk/src/share/classes/sun/security/x509/AlgorithmId.java @@ -120,21 +120,14 @@ public class AlgorithmId implements Serializable, DerEncoder { try { algParams = AlgorithmParameters.getInstance(algidString); } catch (NoSuchAlgorithmException e) { - try { - // Try the internal EC code so that we can fully parse EC - // keys even if the provider is not registered. - // This code can go away once we have EC in the SUN provider. - algParams = AlgorithmParameters.getInstance(algidString, - sun.security.ec.ECKeyFactory.ecInternalProvider); - } catch (NoSuchAlgorithmException ee) { - /* - * This algorithm parameter type is not supported, so we cannot - * parse the parameters. - */ - algParams = null; - return; - } + /* + * This algorithm parameter type is not supported, so we cannot + * parse the parameters. + */ + algParams = null; + return; } + // Decode (parse) the parameters algParams.init(params.toByteArray()); } @@ -505,6 +498,9 @@ public class AlgorithmId implements Serializable, DerEncoder { if (name.equalsIgnoreCase("EC")) { return EC_oid; } + if (name.equalsIgnoreCase("ECDH")) { + return AlgorithmId.ECDH_oid; + } // Common signature types if (name.equalsIgnoreCase("MD5withRSA") @@ -524,6 +520,12 @@ public class AlgorithmId implements Serializable, DerEncoder { || name.equalsIgnoreCase("SHA-1/DSA")) { return AlgorithmId.sha1WithDSA_oid; } + if (name.equalsIgnoreCase("SHA224WithDSA")) { + return AlgorithmId.sha224WithDSA_oid; + } + if (name.equalsIgnoreCase("SHA256WithDSA")) { + return AlgorithmId.sha256WithDSA_oid; + } if (name.equalsIgnoreCase("SHA1WithRSA") || name.equalsIgnoreCase("SHA1/RSA")) { return AlgorithmId.sha1WithRSAEncryption_oid; @@ -654,6 +656,7 @@ public class AlgorithmId implements Serializable, DerEncoder { public static final ObjectIdentifier DSA_oid; public static final ObjectIdentifier DSA_OIW_oid; public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1); + public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12); public static final ObjectIdentifier RSA_oid; public static final ObjectIdentifier RSAEncryption_oid; @@ -694,6 +697,10 @@ public class AlgorithmId implements Serializable, DerEncoder { public static final ObjectIdentifier shaWithDSA_OIW_oid; public static final ObjectIdentifier sha1WithDSA_OIW_oid; public static final ObjectIdentifier sha1WithDSA_oid; + public static final ObjectIdentifier sha224WithDSA_oid = + oid(2, 16, 840, 1, 101, 3, 4, 3, 1); + public static final ObjectIdentifier sha256WithDSA_oid = + oid(2, 16, 840, 1, 101, 3, 4, 3, 2); public static final ObjectIdentifier sha1WithECDSA_oid = oid(1, 2, 840, 10045, 4, 1); @@ -725,7 +732,6 @@ public class AlgorithmId implements Serializable, DerEncoder { public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid = ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6}); - static { /* * Note the preferred OIDs are named simply with no "OIW" or @@ -885,6 +891,8 @@ public class AlgorithmId implements Serializable, DerEncoder { nameTable.put(DSA_oid, "DSA"); nameTable.put(DSA_OIW_oid, "DSA"); nameTable.put(EC_oid, "EC"); + nameTable.put(ECDH_oid, "ECDH"); + nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA"); nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA"); nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA"); @@ -895,6 +903,8 @@ public class AlgorithmId implements Serializable, DerEncoder { nameTable.put(sha1WithDSA_oid, "SHA1withDSA"); nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA"); nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA"); + nameTable.put(sha224WithDSA_oid, "SHA224withDSA"); + nameTable.put(sha256WithDSA_oid, "SHA256withDSA"); nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA"); nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA"); nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA"); diff --git a/jdk/src/share/demo/jvmti/hprof/debug_malloc.h b/jdk/src/share/demo/jvmti/hprof/debug_malloc.h index 6b6b4c6b733..d74ff608b2a 100644 --- a/jdk/src/share/demo/jvmti/hprof/debug_malloc.h +++ b/jdk/src/share/demo/jvmti/hprof/debug_malloc.h @@ -59,6 +59,11 @@ #include #include +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + /* The real functions behind the macro curtains. */ void *debug_malloc(size_t, const char *, int); @@ -71,10 +76,10 @@ void debug_free(void *, const char *, int); void debug_malloc_verify(const char*, int); #undef malloc_verify -#define malloc_verify() debug_malloc_verify(__FILE__, __LINE__) +#define malloc_verify() debug_malloc_verify(THIS_FILE, __LINE__) void debug_malloc_police(const char*, int); #undef malloc_police -#define malloc_police() debug_malloc_police(__FILE__, __LINE__) +#define malloc_police() debug_malloc_police(THIS_FILE, __LINE__) #endif diff --git a/jdk/src/share/demo/jvmti/hprof/hprof_error.h b/jdk/src/share/demo/jvmti/hprof/hprof_error.h index c0d6aed0fea..b82d4ee6b90 100644 --- a/jdk/src/share/demo/jvmti/hprof/hprof_error.h +++ b/jdk/src/share/demo/jvmti/hprof/hprof_error.h @@ -41,20 +41,25 @@ #ifndef HPROF_ERROR_H #define HPROF_ERROR_H +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + /* Macros over assert and error functions so we can capture the source loc. */ #define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE)) #define HPROF_ERROR(fatal,msg) \ - error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, __FILE__, __LINE__) + error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, THIS_FILE, __LINE__) #define HPROF_JVMTI_ERROR(error,msg) \ error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \ - error, msg, __FILE__, __LINE__) + error, msg, THIS_FILE, __LINE__) #if defined(DEBUG) || !defined(NDEBUG) #define HPROF_ASSERT(cond) \ - (((int)(cond))?(void)0:error_assert(#cond, __FILE__, __LINE__)) + (((int)(cond))?(void)0:error_assert(#cond, THIS_FILE, __LINE__)) #else #define HPROF_ASSERT(cond) #endif @@ -77,11 +82,11 @@ #define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n" #define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \ - str1, __FILE__, __LINE__ )) + str1, THIS_FILE, __LINE__ )) #define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \ - str1, str2, __FILE__, __LINE__ )) + str1, str2, THIS_FILE, __LINE__ )) #define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \ - str1, str2, num, __FILE__, __LINE__ )) + str1, str2, num, THIS_FILE, __LINE__ )) #define LOG(str) LOG1(str) diff --git a/jdk/src/share/demo/jvmti/hprof/hprof_util.h b/jdk/src/share/demo/jvmti/hprof/hprof_util.h index c052394f2b6..588570ce64b 100644 --- a/jdk/src/share/demo/jvmti/hprof/hprof_util.h +++ b/jdk/src/share/demo/jvmti/hprof/hprof_util.h @@ -41,6 +41,11 @@ #ifndef HPROF_UTIL_H #define HPROF_UTIL_H +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + /* Macros that protect code from accidently using a local ref improperly */ #define WITH_LOCAL_REFS(env, number) \ { \ @@ -184,8 +189,8 @@ void hprof_free(void *ptr); #ifdef DEBUG void * hprof_debug_malloc(int size, char *file, int line); void hprof_debug_free(void *ptr, char *file, int line); - #define HPROF_MALLOC(size) hprof_debug_malloc(size, __FILE__, __LINE__) - #define HPROF_FREE(ptr) hprof_debug_free(ptr, __FILE__, __LINE__) + #define HPROF_MALLOC(size) hprof_debug_malloc(size, THIS_FILE, __LINE__) + #define HPROF_FREE(ptr) hprof_debug_free(ptr, THIS_FILE, __LINE__) #else #define HPROF_MALLOC(size) hprof_malloc(size) #define HPROF_FREE(ptr) hprof_free(ptr) diff --git a/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c b/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c index 1da0e55d322..772548de165 100644 --- a/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c +++ b/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c @@ -70,12 +70,20 @@ /* Macros over error functions to capture line numbers */ -#define CRW_FATAL(ci, message) fatal_error(ci, message, __FILE__, __LINE__) +/* Fatal error used in all builds. */ + +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE "java_crw.demo.c" /* Never use __FILE__ */ +#endif + +#define CRW_FATAL(ci, message) fatal_error(ci, message, THIS_FILE, __LINE__) #if defined(DEBUG) || !defined(NDEBUG) + /* This assert macro is only used in the debug builds. */ #define CRW_ASSERT(ci, cond) \ - ((cond)?(void)0:assert_error(ci, #cond, __FILE__, __LINE__)) + ((cond)?(void)0:assert_error(ci, #cond, THIS_FILE, __LINE__)) #else diff --git a/jdk/src/share/instrument/JPLISAssert.h b/jdk/src/share/instrument/JPLISAssert.h index c2ef7eef124..a0446447e59 100644 --- a/jdk/src/share/instrument/JPLISAssert.h +++ b/jdk/src/share/instrument/JPLISAssert.h @@ -49,10 +49,14 @@ extern "C" { #define JPLISASSERT_ENABLEASSERTIONS (0) #endif +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif #if JPLISASSERT_ENABLEASSERTIONS -#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, __FILE__, __LINE__) -#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, __FILE__, __LINE__) +#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, THIS_FILE, __LINE__) +#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, THIS_FILE, __LINE__) #else #define jplis_assert(x) #define jplis_assert_msg(x, msg) diff --git a/jdk/src/share/native/sun/awt/debug/debug_assert.h b/jdk/src/share/native/sun/awt/debug/debug_assert.h index 22d804733e0..920f232ee50 100644 --- a/jdk/src/share/native/sun/awt/debug/debug_assert.h +++ b/jdk/src/share/native/sun/awt/debug/debug_assert.h @@ -32,17 +32,22 @@ extern "C" { #include "debug_util.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #if defined(DEBUG) #define DASSERT(_expr) \ if ( !(_expr) ) { \ - DAssert_Impl( #_expr, __FILE__, __LINE__); \ + DAssert_Impl( #_expr, THIS_FILE, __LINE__); \ } else { \ } #define DASSERTMSG(_expr, _msg) \ if ( !(_expr) ) { \ - DAssert_Impl( (_msg), __FILE__, __LINE__); \ + DAssert_Impl( (_msg), THIS_FILE, __LINE__); \ } else { \ } diff --git a/jdk/src/share/native/sun/awt/debug/debug_mem.c b/jdk/src/share/native/sun/awt/debug/debug_mem.c index 5a4690be8f1..bf91768e6d3 100644 --- a/jdk/src/share/native/sun/awt/debug/debug_mem.c +++ b/jdk/src/share/native/sun/awt/debug/debug_mem.c @@ -27,6 +27,11 @@ #include "debug_util.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #define DMEM_MIN(a,b) (a) < (b) ? (a) : (b) #define DMEM_MAX(a,b) (a) > (b) ? (a) : (b) @@ -291,7 +296,7 @@ void DMem_ReportLeaks() { DMutex_Enter(DMemMutex); /* Force memory leaks to be output regardless of trace settings */ - DTrace_EnableFile(__FILE__, TRUE); + DTrace_EnableFile(THIS_FILE, TRUE); DTRACE_PRINTLN("--------------------------"); DTRACE_PRINTLN("Debug Memory Manager Leaks"); DTRACE_PRINTLN("--------------------------"); diff --git a/jdk/src/share/native/sun/awt/debug/debug_trace.h b/jdk/src/share/native/sun/awt/debug/debug_trace.h index e91c556ac07..aad4677d111 100644 --- a/jdk/src/share/native/sun/awt/debug/debug_trace.h +++ b/jdk/src/share/native/sun/awt/debug/debug_trace.h @@ -34,6 +34,11 @@ extern "C" { #include "debug_util.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + typedef int dtrace_id; enum { UNDEFINED_TRACE_ID = -1 /* indicates trace point has not been registered yet */ @@ -69,7 +74,7 @@ static dtrace_id _Dt_FileTraceId = UNDEFINED_TRACE_ID; #define _DTrace_Template(_func, _ac, _f, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) \ { \ static dtrace_id _dt_lineid_ = UNDEFINED_TRACE_ID; \ - DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, __FILE__, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \ + DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, THIS_FILE, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \ } /* printf style trace macros */ diff --git a/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h b/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h index 81e79b9acd3..01aeb6fcaea 100644 --- a/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h +++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h @@ -452,7 +452,12 @@ extern CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs; void *p11malloc(size_t c, char *file, int line); void p11free(void *p, char *file, int line); -#define malloc(c) (p11malloc((c), __FILE__, __LINE__)) -#define free(c) (p11free((c), __FILE__, __LINE__)) +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + +#define malloc(c) (p11malloc((c), THIS_FILE, __LINE__)) +#define free(c) (p11free((c), THIS_FILE, __LINE__)) #endif diff --git a/jdk/src/share/npt/utf.h b/jdk/src/share/npt/utf.h index 8fbda735fa1..4345b606df1 100644 --- a/jdk/src/share/npt/utf.h +++ b/jdk/src/share/npt/utf.h @@ -33,8 +33,13 @@ #include "jni.h" #include "utf_md.h" +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + /* Error and assert macros */ -#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m) +#define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m) #define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 ) void utfError(char *file, int line, char *message); diff --git a/jdk/src/share/transport/shmem/shmemBase.h b/jdk/src/share/transport/shmem/shmemBase.h index 661d9f076b8..0d5cec1f7b4 100644 --- a/jdk/src/share/transport/shmem/shmemBase.h +++ b/jdk/src/share/transport/shmem/shmemBase.h @@ -49,11 +49,16 @@ jint shmemBase_receivePacket(SharedMemoryConnection *, jdwpPacket *packet); jint shmemBase_name(SharedMemoryTransport *, char **name); jint shmemBase_getlasterror(char *msg, jint size); +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #ifdef DEBUG #define SHMEM_ASSERT(expression) \ do { \ if (!(expression)) { \ - exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \ + exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \ } \ } while (0) #else @@ -63,7 +68,7 @@ do { \ #define SHMEM_GUARANTEE(expression) \ do { \ if (!(expression)) { \ - exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \ + exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \ } \ } while (0) diff --git a/jdk/src/solaris/bin/jexec.c b/jdk/src/solaris/bin/jexec.c index b2efc99c48d..2e478d8f1a7 100644 --- a/jdk/src/solaris/bin/jexec.c +++ b/jdk/src/solaris/bin/jexec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,6 +80,7 @@ # include # include # include +# include "jni.h" # include "manifest_info.h" #endif diff --git a/jdk/src/solaris/instrument/EncodingSupport_md.c b/jdk/src/solaris/instrument/EncodingSupport_md.c index 35ba4502891..456916e2882 100644 --- a/jdk/src/solaris/instrument/EncodingSupport_md.c +++ b/jdk/src/solaris/instrument/EncodingSupport_md.c @@ -33,8 +33,13 @@ /* Routines to convert back and forth between Platform Encoding and UTF-8 */ +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + /* Error and assert macros */ -#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m) +#define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m) #define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 ) #define UTF_DEBUG(x) diff --git a/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c b/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c index b5248992ea4..62e5615c80a 100644 --- a/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c +++ b/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c @@ -100,18 +100,20 @@ JNIEXPORT jlong JNICALL Java_com_sun_management_OperatingSystem_getTotalSwapSpaceSize (JNIEnv *env, jobject mbean) { - MEMORYSTATUS ms; - GlobalMemoryStatus(&ms); - return (jlong)ms.dwTotalPageFile; + MEMORYSTATUSEX ms; + ms.dwLength = sizeof(ms); + GlobalMemoryStatusEx(&ms); + return (jlong) ms.ullTotalPageFile; } JNIEXPORT jlong JNICALL Java_com_sun_management_OperatingSystem_getFreeSwapSpaceSize (JNIEnv *env, jobject mbean) { - MEMORYSTATUS ms; - GlobalMemoryStatus(&ms); - return (jlong)ms.dwAvailPageFile; + MEMORYSTATUSEX ms; + ms.dwLength = sizeof(ms); + GlobalMemoryStatusEx(&ms); + return (jlong) ms.ullAvailPageFile; } JNIEXPORT jlong JNICALL @@ -137,21 +139,20 @@ JNIEXPORT jlong JNICALL Java_com_sun_management_OperatingSystem_getFreePhysicalMemorySize (JNIEnv *env, jobject mbean) { - MEMORYSTATUS ms; - GlobalMemoryStatus(&ms); - return (jlong) ms.dwAvailPhys; + MEMORYSTATUSEX ms; + ms.dwLength = sizeof(ms); + GlobalMemoryStatusEx(&ms); + return (jlong) ms.ullAvailPhys; } JNIEXPORT jlong JNICALL Java_com_sun_management_OperatingSystem_getTotalPhysicalMemorySize (JNIEnv *env, jobject mbean) { - MEMORYSTATUS ms; - // also returns dwAvailPhys (free physical memory bytes), - // dwTotalVirtual, dwAvailVirtual, - // dwMemoryLoad (% of memory in use) - GlobalMemoryStatus(&ms); - return ms.dwTotalPhys; + MEMORYSTATUSEX ms; + ms.dwLength = sizeof(ms); + GlobalMemoryStatusEx(&ms); + return (jlong) ms.ullTotalPhys; } // Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer. diff --git a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp index 996e70fbb26..1435f6d10c0 100644 --- a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp +++ b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp @@ -35,9 +35,15 @@ extern "C" { #ifdef USE_ERROR #include + +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #define MIDIIN_CHECK_ERROR { \ if (err != MMSYSERR_NOERROR) \ - ERROR3("MIDI IN Error in %s:%d : %s\n", __FILE__, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \ + ERROR3("MIDI IN Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \ } #else #define MIDIIN_CHECK_ERROR diff --git a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c index e4e68b76754..f3e573e892d 100644 --- a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c +++ b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c @@ -33,9 +33,15 @@ #ifdef USE_ERROR #include + +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #define MIDIOUT_CHECK_ERROR { \ if (err != MMSYSERR_NOERROR) \ - ERROR3("MIDI OUT Error in %s:%d : %s\n", __FILE__, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \ + ERROR3("MIDI OUT Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \ } #else #define MIDIOUT_CHECK_ERROR diff --git a/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h b/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h index bcaf4d70198..7eda48f8d62 100644 --- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h +++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h @@ -28,6 +28,11 @@ #define D3D_DEBUG_INFO #endif // DEBUG +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE THIS_FILE +#endif + #ifdef D3D_PPL_DLL @@ -104,7 +109,7 @@ do { \ #define ACT_IF_NULL(ACTION, value) \ if ((value) == NULL) { \ J2dTraceLn3(J2D_TRACE_ERROR, \ - "%s is null in %s:%d", #value, __FILE__, __LINE__); \ + "%s is null in %s:%d", #value, THIS_FILE, __LINE__); \ ACTION; \ } else do { } while (0) #define RETURN_IF_NULL(value) ACT_IF_NULL(return, value) @@ -114,12 +119,12 @@ do { \ #define RETURN_STATUS_IF_EXP_FAILED(EXPR) \ if (FAILED(res = (EXPR))) { \ - DebugPrintD3DError(res, " " ## #EXPR ## " failed in " ## __FILE__); \ + DebugPrintD3DError(res, " " ## #EXPR ## " failed in " ## THIS_FILE); \ return res; \ } else do { } while (0) #define RETURN_STATUS_IF_FAILED(status) \ if (FAILED((status))) { \ - DebugPrintD3DError((status), " failed in " ## __FILE__ ## ", return;");\ + DebugPrintD3DError((status), " failed in " ## THIS_FILE ## ", return;");\ return (status); \ } else do { } while (0) diff --git a/jdk/src/windows/native/sun/windows/alloc.h b/jdk/src/windows/native/sun/windows/alloc.h index fdd0cd6eb72..527da4227c8 100644 --- a/jdk/src/windows/native/sun/windows/alloc.h +++ b/jdk/src/windows/native/sun/windows/alloc.h @@ -26,6 +26,11 @@ #ifndef _ALLOC_H_ #define _ALLOC_H_ +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #include "stdhdrs.h" // By defining std::bad_alloc in a local header file instead of including @@ -127,12 +132,12 @@ void handle_bad_alloc(void); throw (std::bad_alloc); #define safe_Malloc(size) \ - safe_Malloc_outofmem(size, __FILE__, __LINE__) + safe_Malloc_outofmem(size, THIS_FILE, __LINE__) #define safe_Calloc(num, size) \ - safe_Calloc_outofmem(num, size, __FILE__, __LINE__) + safe_Calloc_outofmem(num, size, THIS_FILE, __LINE__) #define safe_Realloc(memblock, size) \ - safe_Realloc_outofmem(memblock, size, __FILE__, __LINE__) - #define new new(__FILE__, __LINE__) + safe_Realloc_outofmem(memblock, size, THIS_FILE, __LINE__) + #define new new(THIS_FILE, __LINE__) #endif /* OUTOFMEM_TEST */ #define TRY \ diff --git a/jdk/src/windows/native/sun/windows/awt_Debug.h b/jdk/src/windows/native/sun/windows/awt_Debug.h index 9f7c0c08a8b..468b99135f7 100644 --- a/jdk/src/windows/native/sun/windows/awt_Debug.h +++ b/jdk/src/windows/native/sun/windows/awt_Debug.h @@ -65,7 +65,12 @@ #define AWT_DUMP_CLIP_RECTANGLE(_msg, _hwnd) \ _DTrace_Template(DumpClipRectangle, 2, "", (_msg), (_hwnd), 0, 0, 0, 0, 0, 0) - #define new new(__FILE__, __LINE__) + /* Use THIS_FILE when it is available. */ + #ifndef THIS_FILE + #define THIS_FILE __FILE__ + #endif + + #define new new(THIS_FILE, __LINE__) #define VERIFY(exp) DASSERT(exp) #define UNIMPLEMENTED() DASSERT(FALSE) diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.h b/jdk/src/windows/native/sun/windows/awt_Toolkit.h index f3e7e74138b..e640d805002 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h @@ -132,24 +132,30 @@ class CriticalSection { // Macros for using CriticalSection objects that help trace // lock/unlock actions + +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + #define CRITICAL_SECTION_ENTER(cs) { \ J2dTraceLn4(J2D_TRACE_VERBOSE2, \ "CS.Wait: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \ - GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \ + GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \ (cs).Enter(); \ J2dTraceLn4(J2D_TRACE_VERBOSE2, \ "CS.Enter: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \ - GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \ + GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \ } #define CRITICAL_SECTION_LEAVE(cs) { \ J2dTraceLn4(J2D_TRACE_VERBOSE2, \ "CS.Leave: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \ - GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \ + GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \ (cs).Leave(); \ J2dTraceLn4(J2D_TRACE_VERBOSE2, \ "CS.Left: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \ - GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \ + GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \ } /************************************************************************ diff --git a/jdk/src/windows/transport/shmem/shmem_md.c b/jdk/src/windows/transport/shmem/shmem_md.c index fe659b03b43..83e9349574b 100644 --- a/jdk/src/windows/transport/shmem/shmem_md.c +++ b/jdk/src/windows/transport/shmem/shmem_md.c @@ -30,6 +30,11 @@ #include "sysShmem.h" #include "shmemBase.h" /* for exitTransportWithError */ +/* Use THIS_FILE when it is available. */ +#ifndef THIS_FILE + #define THIS_FILE __FILE__ +#endif + /* * These functions are not completely universal. For now, they are used * exclusively for Jbug's shared memory transport mechanism. They have @@ -44,7 +49,7 @@ static HANDLE memHandle = NULL; if (!(expression)) { \ exitTransportWithError \ ("\"%s\", line %d: assertion failure\n", \ - __FILE__, __DATE__, __LINE__); \ + THIS_FILE, __DATE__, __LINE__); \ } \ } #else diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 50969cdb5cf..b84b9879dd3 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -261,6 +261,18 @@ java/nio/channels/AsyncCloseAndInterrupt.java solaris-all # 7146541 java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all +# 7187882 +java/rmi/activation/checkusage/CheckUsage.java generic-all + +# 7190106 +java/rmi/reliability/benchmark/runRmiBench.sh generic-all + +# 7191877 +java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java generic-all + +# 7195095 +sun/rmi/transport/proxy/EagerHttpFallback.java linux-all + ############################################################################ # jdk_security diff --git a/jdk/test/com/sun/corba/cachedSocket/7056731.sh b/jdk/test/com/sun/corba/cachedSocket/7056731.sh index c6f53109d04..afb2278d328 100644 --- a/jdk/test/com/sun/corba/cachedSocket/7056731.sh +++ b/jdk/test/com/sun/corba/cachedSocket/7056731.sh @@ -115,5 +115,8 @@ else exitCode=0 fi +#jtreg complaining about not being able to clean up; let's sleep +sleep 2 rm -rf out.$$ client.$$ +sleep 2 exit ${exitCode} diff --git a/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java b/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java index 78316efb7ee..6226fe9191d 100644 --- a/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java +++ b/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 6330287 6331386 + * @bug 6330287 6331386 7044060 * @summary verify that DHKeyPairGenerator returns keys of the expected size * (modulus and exponent) * -and- @@ -57,7 +57,8 @@ public class TestExponentSize { * Sizes and values for various lengths. */ private enum Sizes { - two56(256), three84(384), five12(512), seven68(768), ten24(1024); + two56(256), three84(384), five12(512), seven68(768), ten24(1024), + twenty48(2048); private final int intSize; private final BigInteger bigIntValue; @@ -82,7 +83,8 @@ public class TestExponentSize { KeyPair kp; KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE"); - // Sun's default uses a default psize of 1024/lsize of 512 + // Sun's default uses a default psize of 1024 and + // lsize of (pSize / 2) but at least 384 bits kp = kpg.generateKeyPair(); checkKeyPair(kp, Sizes.ten24, Sizes.five12); @@ -114,6 +116,20 @@ public class TestExponentSize { kp = kpg.generateKeyPair(); checkKeyPair(kp, Sizes.seven68, Sizes.three84); + // test w/ only pSize + kpg.initialize(Sizes.twenty48.getIntSize()); + kp = kpg.generateKeyPair(); + checkKeyPair(kp, Sizes.twenty48, Sizes.ten24); + + publicKey = (DHPublicKey)kp.getPublic(); + p = publicKey.getParams().getP(); + g = publicKey.getParams().getG(); + + // test w/ all values specified + kpg.initialize(new DHParameterSpec(p, g, Sizes.five12.getIntSize())); + kp = kpg.generateKeyPair(); + checkKeyPair(kp, Sizes.twenty48, Sizes.five12); + System.out.println("OK"); } diff --git a/jdk/test/com/sun/management/OperatingSystemMXBean/MemoryStatusOverflow.java b/jdk/test/com/sun/management/OperatingSystemMXBean/MemoryStatusOverflow.java new file mode 100644 index 00000000000..0925710c081 --- /dev/null +++ b/jdk/test/com/sun/management/OperatingSystemMXBean/MemoryStatusOverflow.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, 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 6853676 + * @summary On computers with more than 4 GB of memory, + * the GlobalMemoryStatus function can return incorrect information, + * reporting a value of -1 to indicate an overflow. + * + * @run main MemoryStatusOverflow + */ + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.lang.management.ManagementFactory; +import com.sun.management.OperatingSystemMXBean; + +public class MemoryStatusOverflow { + static final long MEMORYSTATUS_OVERFLOW = (1L << 32) - 1; // (DWORD) -1 + + public static void main(String... args) throws Exception { + OperatingSystemMXBean bean = (OperatingSystemMXBean) + ManagementFactory.getOperatingSystemMXBean(); + List failedGetterNames = new ArrayList(); + List testedGetterNames = Arrays.asList( + "getTotalSwapSpaceSize", "getFreeSwapSpaceSize", + "getTotalPhysicalMemorySize", "getFreePhysicalMemorySize"); + for (String getterName : testedGetterNames) { + Method getter = OperatingSystemMXBean.class.getMethod(getterName); + long value = (Long) getter.invoke(bean); + if (value == MEMORYSTATUS_OVERFLOW) { + failedGetterNames.add(getterName); + } + } + if (!failedGetterNames.isEmpty()) { + throw new AssertionError(failedGetterNames); + } + System.out.println("Test passed."); + } +} diff --git a/jdk/test/java/nio/file/Files/CopyAndMove.java b/jdk/test/java/nio/file/Files/CopyAndMove.java index 9ac27af0669..0becc686719 100644 --- a/jdk/test/java/nio/file/Files/CopyAndMove.java +++ b/jdk/test/java/nio/file/Files/CopyAndMove.java @@ -86,10 +86,12 @@ public class CopyAndMove { assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink()); assertTrue(attrs1.isOther() == attrs2.isOther()); - // check last modified time - long time1 = attrs1.lastModifiedTime().toMillis(); - long time2 = attrs2.lastModifiedTime().toMillis(); - assertTrue(time1 == time2); + // check last modified time if not a symbolic link + if (!attrs1.isSymbolicLink()) { + long time1 = attrs1.lastModifiedTime().toMillis(); + long time2 = attrs2.lastModifiedTime().toMillis(); + assertTrue(time1 == time2); + } // check size if (attrs1.isRegularFile()) diff --git a/jdk/test/sun/security/ec/TestEC.java b/jdk/test/sun/security/ec/TestEC.java index c23980d14ff..41d0f0361da 100644 --- a/jdk/test/sun/security/ec/TestEC.java +++ b/jdk/test/sun/security/ec/TestEC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, 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 @@ * @run main TestEC */ +import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; @@ -62,7 +63,12 @@ public class TestEC { } public static void main0(String[] args) throws Exception { - Provider p = new sun.security.ec.SunEC(); + Provider p = Security.getProvider("SunEC"); + + if (p == null) { + throw new NoSuchProviderException("Can't get SunEC provider"); + } + System.out.println("Running tests with " + p.getName() + " provider...\n"); long start = System.currentTimeMillis(); diff --git a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java index 2aa38a9f505..eba81c6d3ea 100644 --- a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java +++ b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java @@ -63,6 +63,10 @@ public class ReadCertificates extends PKCS11Test { System.out.println("Provider does not support ECDSA, skipping..."); return; } + + /* + * PKCS11Test.main will remove this provider if needed + */ Providers.setAt(p, 1); random = new SecureRandom(); @@ -132,7 +136,6 @@ public class ReadCertificates extends PKCS11Test { } } - Security.removeProvider(p.getName()); System.out.println("OK"); } diff --git a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java index 979783eace7..6acc667aaf3 100644 --- a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java +++ b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java @@ -53,6 +53,10 @@ public class ReadPKCS12 extends PKCS11Test { System.out.println("Provider does not support ECDSA, skipping..."); return; } + + /* + * PKCS11Test.main will remove this provider if needed + */ Providers.setAt(p, 1); CertificateFactory factory = CertificateFactory.getInstance("X.509"); @@ -147,7 +151,6 @@ public class ReadPKCS12 extends PKCS11Test { out.close(); } - Security.removeProvider(p.getName()); System.out.println("OK"); } diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDH.java b/jdk/test/sun/security/pkcs11/ec/TestECDH.java index 3182cff27d9..aa26d5c6d43 100644 --- a/jdk/test/sun/security/pkcs11/ec/TestECDH.java +++ b/jdk/test/sun/security/pkcs11/ec/TestECDH.java @@ -60,6 +60,10 @@ public class TestECDH extends PKCS11Test { System.out.println("Provider does not support ECDH, skipping"); return; } + + /* + * PKCS11Test.main will remove this provider if needed + */ Providers.setAt(p, 1); if (false) { @@ -77,7 +81,6 @@ public class TestECDH extends PKCS11Test { test(p, pub192a, priv192a, pub192b, priv192b, secret192); test(p, pub163a, priv163a, pub163b, priv163b, secret163); - Security.removeProvider(p.getName()); System.out.println("OK"); } diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDH2.java b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java new file mode 100644 index 00000000000..21d1490600e --- /dev/null +++ b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, 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 6405536 + * @summary basic test of ECDSA signatures for P-256 and P-384 from the + * example data in "Suite B Implementer's Guide to FIPS 186-3". + * @library .. + * @library ../../../../java/security/testlibrary + * @compile -XDignore.symbol.file TestECDH2.java + * @run main TestECDH2 + */ + +import java.io.*; +import java.util.*; +import java.math.BigInteger; + +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; +import javax.crypto.*; + +import sun.security.ec.NamedCurve; + +public class TestECDH2 extends PKCS11Test { + + // values of the keys we use for the tests + + // keypair using NIST P-256 + private final static String privD256 = "70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a"; + private final static String pubX256 = "8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8"; + private final static String pubY256 = "d8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9"; + + // keypair using NIST P-384 + private final static String privD384 = "c838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24"; + private final static String pubX384 = "1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0"; + private final static String pubY384 = "eb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9"; + + private KeyFactory kf = null; + private KeyPairGenerator kpg = null; + + private static void testKeyAgreement(KeyPair kpA, KeyPair kpB, Provider p) + throws Exception { + KeyAgreement ka1 = KeyAgreement.getInstance("ECDH", p); + ka1.init(kpA.getPrivate()); + ka1.doPhase(kpB.getPublic(), true); + byte[] s1 = ka1.generateSecret(); + + KeyAgreement ka2 = KeyAgreement.getInstance("ECDH", p); + ka2.init(kpB.getPrivate()); + ka2.doPhase(kpA.getPublic(), true); + byte[] s2 = ka2.generateSecret(); + if (Arrays.equals(s1, s2) == false) { + System.out.println("expected: " + toString(s1)); + System.out.println("actual: " + toString(s2)); + throw new Exception("Generated secrets do not match"); + } + } + + private KeyPair genECKeyPair(String curvName, String privD, String pubX, + String pubY) throws Exception { + ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName); + ECPrivateKeySpec privKeySpec = + new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams); + ECPublicKeySpec pubKeySpec = + new ECPublicKeySpec(new ECPoint(new BigInteger(pubX, 16), + new BigInteger(pubY, 16)), + ecParams); + PrivateKey privKey = kf.generatePrivate(privKeySpec); + PublicKey pubKey = kf.generatePublic(pubKeySpec); + return new KeyPair(pubKey, privKey); + } + private KeyPair genECKeyPair(String curvName) throws Exception { + ECGenParameterSpec genParams = new ECGenParameterSpec(curvName); + kpg.initialize(genParams, null); + return kpg.generateKeyPair(); + } + public static void main(String[] args) throws Exception { + main(new TestECDH2()); + } + + public void main(Provider provider) throws Exception { + if (provider.getService("KeyAgreement", "ECDH") == null) { + System.out.println("ECDH not supported, skipping"); + return; + } + + kf = KeyFactory.getInstance("EC", provider); + kpg = KeyPairGenerator.getInstance("EC", provider); + + System.out.println("Testing against NIST P-256"); + + long start = System.currentTimeMillis(); + KeyPair kp256A = genECKeyPair("secp256r1", privD256, pubX256, pubY256); + KeyPair kp256B = genECKeyPair("secp256r1"); + testKeyAgreement(kp256A, kp256B, provider); + + System.out.println("Testing against NIST P-384"); + KeyPair kp384A = genECKeyPair("secp384r1", privD384, pubX384, pubY384); + KeyPair kp384B = genECKeyPair("secp384r1"); + testKeyAgreement(kp384A, kp384B, provider); + + long stop = System.currentTimeMillis(); + System.out.println("All tests passed (" + (stop - start) + " ms)."); + } +} diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java index 0514d1d575e..6f5325aae9e 100644 --- a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java +++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java @@ -116,6 +116,10 @@ public class TestECDSA extends PKCS11Test { System.out.println("ECDSA not supported, skipping"); return; } + + /* + * PKCS11Test.main will remove this provider if needed + */ Providers.setAt(provider, 1); if (false) { @@ -137,7 +141,6 @@ public class TestECDSA extends PKCS11Test { test(provider, pub521, priv521, sig521); test(provider, pub571, priv571, sig571); - Security.removeProvider(provider.getName()); long stop = System.currentTimeMillis(); System.out.println("All tests passed (" + (stop - start) + " ms)."); } diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java new file mode 100644 index 00000000000..98c7f031930 --- /dev/null +++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 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 6405536 + * @summary basic test of ECDSA signatures for P-256 and P-384 from the + * example data in "Suite B Implementer's Guide to FIPS 186-3". + * @library .. + * @library ../../../../java/security/testlibrary + * @compile -XDignore.symbol.file TestECDSA2.java + * @run main TestECDSA2 + */ + +import java.io.*; +import java.util.*; +import java.math.BigInteger; + +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; + +import sun.security.ec.NamedCurve; + +public class TestECDSA2 extends PKCS11Test { + + // values of the keys we use for the tests + + // keypair using NIST P-256 + private final static String privD256 = "70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a"; + private final static String pubX256 = "8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8"; + private final static String pubY256 = "d8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9"; + + // keypair using NIST P-384 + private final static String privD384 = "c838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24"; + private final static String pubX384 = "1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0"; + private final static String pubY384 = "eb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9"; + + // data to be signed + private final static byte[] data = "This is only a test message. It is 48 bytes long".getBytes(); + + private KeyFactory kf = null; + + private static void testSignAndVerify(String alg, KeyPair kp, Provider p) throws Exception { + Signature s = Signature.getInstance(alg, p); + s.initSign(kp.getPrivate()); + s.update(data); + byte[] result = s.sign(); + + s.initVerify(kp.getPublic()); + s.update(data); + if (!s.verify(result)) { + throw new Exception("Error: Signature verification failed"); + } + System.out.println(p.getName() + ": " + alg + " Passed"); + } + + private KeyPair genECKeyPair(String curvName, String privD, String pubX, String pubY) throws Exception { + ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName); + ECPrivateKeySpec privKeySpec = + new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams); + ECPublicKeySpec pubKeySpec = + new ECPublicKeySpec(new ECPoint(new BigInteger(pubX, 16), new BigInteger(pubY, 16)), + ecParams); + PrivateKey privKey = kf.generatePrivate(privKeySpec); + PublicKey pubKey = kf.generatePublic(pubKeySpec); + return new KeyPair(pubKey, privKey); + } + + public static void main(String[] args) throws Exception { + main(new TestECDSA2()); + } + + public void main(Provider provider) throws Exception { + boolean testP256 = + (provider.getService("Signature", "SHA256withECDSA") != null); + + boolean testP384 = + (provider.getService("Signature", "SHA384withECDSA") != null); + + if (!testP256 && !testP384) { + System.out.println("ECDSA not supported, skipping"); + return; + } + + kf = KeyFactory.getInstance("EC", provider); + + long start = System.currentTimeMillis(); + if (testP256) { + // can use secp256r1, NIST P-256, X9.62 prime256v1, or 1.2.840.10045.3.1.7 + KeyPair kp = genECKeyPair("secp256r1", privD256, pubX256, pubY256); + testSignAndVerify("SHA256withECDSA", kp, provider); + } + if (testP384) { + // can use secp384r1, NIST P-384, 1.3.132.0.34 + KeyPair kp = genECKeyPair("secp384r1", privD384, pubX384, pubY384); + testSignAndVerify("SHA384withECDSA", kp, provider); + } + long stop = System.currentTimeMillis(); + System.out.println("All tests passed (" + (stop - start) + " ms)."); + } +} diff --git a/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java b/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java new file mode 100644 index 00000000000..c416c1d8423 --- /dev/null +++ b/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012, 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 7044060 + * @summary verify that DSA parameter generation works + * @run main/othervm/timeout=300 TestAlgParameterGenerator + */ +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; + +public class TestAlgParameterGenerator { + + private static void checkParamStrength(AlgorithmParameters param, + int strength) throws Exception { + String algo = param.getAlgorithm(); + if (!algo.equalsIgnoreCase("DSA")) { + throw new Exception("Unexpected type of parameters: " + algo); + } + DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class); + int valueL = spec.getP().bitLength(); + if (strength != valueL) { + System.out.println("Expected " + strength + " but actual " + valueL); + throw new Exception("Wrong P strength"); + } + } + private static void checkParamStrength(AlgorithmParameters param, + DSAGenParameterSpec genParam) + throws Exception { + String algo = param.getAlgorithm(); + if (!algo.equalsIgnoreCase("DSA")) { + throw new Exception("Unexpected type of parameters: " + algo); + } + DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class); + int valueL = spec.getP().bitLength(); + int strength = genParam.getPrimePLength(); + if (strength != valueL) { + System.out.println("P: Expected " + strength + " but actual " + valueL); + throw new Exception("Wrong P strength"); + } + int valueN = spec.getQ().bitLength(); + strength = genParam.getSubprimeQLength(); + if (strength != valueN) { + System.out.println("Q: Expected " + strength + " but actual " + valueN); + throw new Exception("Wrong Q strength"); + } + } + + public static void main(String[] args) throws Exception { + AlgorithmParameterGenerator apg = + AlgorithmParameterGenerator.getInstance("DSA", "SUN"); + + long start, stop; + // make sure no-init still works + start = System.currentTimeMillis(); + AlgorithmParameters param = apg.generateParameters(); + stop = System.currentTimeMillis(); + System.out.println("Time: " + (stop - start) + " ms."); + checkParamStrength(param, 1024); + + // make sure the old model works + int[] strengths = { 512, 768, 1024 }; + for (int i = 0; i < strengths.length; i++) { + int sizeP = strengths[i]; + System.out.println("Generating " + sizeP + "-bit DSA Parameters"); + start = System.currentTimeMillis(); + apg.init(sizeP); + param = apg.generateParameters(); + stop = System.currentTimeMillis(); + System.out.println("Time: " + (stop - start) + " ms."); + checkParamStrength(param, sizeP); + } + + // now the newer model + DSAGenParameterSpec spec1 = new DSAGenParameterSpec(1024, 160); + DSAGenParameterSpec spec2 = new DSAGenParameterSpec(2048, 224); + DSAGenParameterSpec spec3 = new DSAGenParameterSpec(2048, 256); + //DSAGenParameterSpec spec4 = new DSAGenParameterSpec(3072, 256); + DSAGenParameterSpec[] specSet = { + spec1, spec2, spec3//, spec4 + }; + for (int i = 0; i < specSet.length; i++) { + DSAGenParameterSpec genParam = specSet[i]; + System.out.println("Generating (" + genParam.getPrimePLength() + + ", " + genParam.getSubprimeQLength() + + ") DSA Parameters"); + start = System.currentTimeMillis(); + apg.init(genParam, null); + param = apg.generateParameters(); + stop = System.currentTimeMillis(); + System.out.println("Time: " + (stop - start) + " ms."); + checkParamStrength(param, genParam); + } + } +} diff --git a/jdk/test/sun/security/provider/DSA/TestDSA2.java b/jdk/test/sun/security/provider/DSA/TestDSA2.java new file mode 100644 index 00000000000..a478b8bc0a3 --- /dev/null +++ b/jdk/test/sun/security/provider/DSA/TestDSA2.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012, 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 7044060 + * @run main/othervm/timeout=250 TestDSA2 + * @summary verify that DSA signature works using SHA and SHA-224 and SHA-256 digests. + */ + + +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; + +public class TestDSA2 { + + // NOTE: need to explictly specify provider since the more + // preferred provider SunPKCS11 provider only supports up + // 1024 bits. + private static final String PROV = "SUN"; + + private static final String[] SIG_ALGOS = { + "SHA1withDSA", "SHA224withDSA", "SHA256withDSA" + }; + + private static final int[] KEYSIZES = { + 1024, 2048 + }; + + public static void main(String[] args) throws Exception { + boolean[] expectedToPass = { true, true, true }; + test(1024, expectedToPass); + boolean[] expectedToPass2 = { false, true, true }; + test(2048, expectedToPass2); + } + + private static void test(int keySize, boolean[] testStatus) + throws Exception { + byte[] data = "1234567890".getBytes(); + System.out.println("Test against key size: " + keySize); + + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", PROV); + keyGen.initialize(keySize, new SecureRandom()); + KeyPair pair = keyGen.generateKeyPair(); + + if (testStatus.length != SIG_ALGOS.length) { + throw new RuntimeException("TestError: incorrect status array!"); + } + for (int i = 0; i < SIG_ALGOS.length; i++) { + Signature dsa = Signature.getInstance(SIG_ALGOS[i], PROV); + try { + dsa.initSign(pair.getPrivate()); + dsa.update(data); + byte[] sig = dsa.sign(); + dsa.initVerify(pair.getPublic()); + dsa.update(data); + boolean verifies = dsa.verify(sig); + if (verifies == testStatus[i]) { + System.out.println(SIG_ALGOS[i] + ": Passed"); + } else { + System.out.println(SIG_ALGOS[i] + ": should " + + (testStatus[i]? "pass":"fail")); + throw new RuntimeException(SIG_ALGOS[i] + ": Unexpected Test result!"); + + } + } catch (Exception ex) { + if (testStatus[i]) { + ex.printStackTrace(); + throw new RuntimeException(SIG_ALGOS[i] + ": Unexpected exception " + ex); + } else { + System.out.println(SIG_ALGOS[i] + ": Passed, expected " + ex); + } + } + } + } +} diff --git a/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java b/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java index 70f9dae9577..f0c0fc37828 100644 --- a/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java +++ b/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java @@ -24,7 +24,7 @@ /* * @test * @bug 4800108 - * @summary verify that precomputed DSA parameters are always used (512, 768, 1024 bit) + * @summary verify that precomputed DSA parameters are always used (512, 768, 1024, 2048 bit) * @run main/othervm/timeout=15 TestKeyPairGenerator */ @@ -78,6 +78,10 @@ public class TestKeyPairGenerator { kp = kpg.generateKeyPair(); checkKeyLength(kp, 512); + kpg.initialize(2048); + kp = kpg.generateKeyPair(); + checkKeyLength(kp, 2048); + long stop = System.currentTimeMillis(); System.out.println("Time: " + (stop - start) + " ms."); } diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java index 37b6341d387..85ac5cb5a73 100644 --- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, 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 @@ -27,10 +27,9 @@ * @library ../../../httpstest/ * @build HttpCallback HttpServer ClosedChannelList HttpTransaction TunnelProxy * @summary Redirect problem with HttpsURLConnection using a proxy - * @run main/othervm B6216082 - * * SunJSSE does not support dynamic system properties, no way to re-use * system properties in samevm/agentvm mode. + * @run main/othervm B6216082 */ import java.io.*; @@ -54,7 +53,9 @@ public class B6216082 { try { // XXX workaround for CNFE Class.forName("java.nio.channels.ClosedByInterruptException"); - setupEnv(); + if (!setupEnv()) { + return; + } startHttpServer(); @@ -69,6 +70,12 @@ public class B6216082 { throw new RuntimeException("Test failed : bad http request"); } } finally { + if (proxy != null) { + proxy.terminate(); + } + if (server != null) { + server.terminate(); + } HttpsURLConnection.setDefaultHostnameVerifier(reservedHV); } } @@ -80,18 +87,13 @@ public class B6216082 { static String keyStoreFile = "keystore"; static String trustStoreFile = "truststore"; static String passwd = "passphrase"; - public static void setupEnv() { - try { - firstNonLoAddress = getNonLoAddress(); - - if (firstNonLoAddress == null) { - System.out.println("The test needs at least one non-loopback address to run. Quit now."); - System.exit(0); - } - System.out.println(firstNonLoAddress.getHostAddress()); - } catch (Exception e) { - e.printStackTrace(); + public static boolean setupEnv() throws Exception { + firstNonLoAddress = getNonLoAddress(); + if (firstNonLoAddress == null) { + System.err.println("The test needs at least one non-loopback address to run. Quit now."); + return false; } + System.out.println(firstNonLoAddress.getHostAddress()); // will use proxy System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress()); @@ -106,6 +108,7 @@ public class B6216082 { System.setProperty("javax.net.ssl.trustStore", trustFilename); System.setProperty("javax.net.ssl.trustStorePassword", passwd); HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier()); + return true; } public static InetAddress getNonLoAddress() throws Exception { @@ -126,33 +129,22 @@ public class B6216082 { return null; } - public static void startHttpServer() { - try { - // Both the https server and the proxy let the - // system pick up an ephemeral port. - httpTrans = new SimpleHttpTransaction(); - server = new HttpServer(httpTrans, 1, 10, 0); - proxy = new TunnelProxy(1, 10, 0); - } catch (IOException e) { - e.printStackTrace(); - } + public static void startHttpServer() throws IOException { + // Both the https server and the proxy let the + // system pick up an ephemeral port. + httpTrans = new SimpleHttpTransaction(); + server = new HttpServer(httpTrans, 1, 10, 0); + proxy = new TunnelProxy(1, 10, 0); } - public static void makeHttpCall() { - try { - System.out.println("https server listen on: " + server.getLocalPort()); - System.out.println("https proxy listen on: " + proxy.getLocalPort()); - URL url = new URL("https" , firstNonLoAddress.getHostAddress(), - server.getLocalPort(), "/"); - HttpURLConnection uc = (HttpURLConnection)url.openConnection(); - System.out.println(uc.getResponseCode()); - uc.disconnect(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - proxy.terminate(); - server.terminate(); - } + public static void makeHttpCall() throws Exception { + System.out.println("https server listen on: " + server.getLocalPort()); + System.out.println("https proxy listen on: " + proxy.getLocalPort()); + URL url = new URL("https" , firstNonLoAddress.getHostAddress(), + server.getLocalPort(), "/"); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + System.out.println(uc.getResponseCode()); + uc.disconnect(); } static class NameVerifier implements HostnameVerifier { @@ -189,7 +181,7 @@ class SimpleHttpTransaction implements HttpCallback { } } } catch (Exception e) { - e.printStackTrace(); + throw new RuntimeException(e); } } } diff --git a/jdk/test/sun/tools/jstatd/jpsOutput1.awk b/jdk/test/sun/tools/jstatd/jpsOutput1.awk index 289d3407eeb..4c25392b08c 100644 --- a/jdk/test/sun/tools/jstatd/jpsOutput1.awk +++ b/jdk/test/sun/tools/jstatd/jpsOutput1.awk @@ -7,7 +7,7 @@ BEGIN { matched++; } -/^[0-9]+ -- process information unavailable$/ { +/^[0-9]+ -- .*$/ { matched++; } diff --git a/jdk/test/tools/launcher/BigJar.java b/jdk/test/tools/launcher/BigJar.java new file mode 100644 index 00000000000..5c183f44e7e --- /dev/null +++ b/jdk/test/tools/launcher/BigJar.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2012, 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 7194005 + * @summary launcher handling of zip64 archives (Scenario A and B) + * @compile -XDignore.symbol.file BigJar.java + * @run main/timeout=600 BigJar + */ +/* + * This test consists of two scenarios: + * + * Scenario A: create a jar with entries exceeding 64K, add a main class and + * see if the launcher can handle it. + * + * Scenario A1: create a jar as in A, but add a zipfile comment as well. + * + * Scenario B: create a jar with a large enough file exceeding 4GB, and + * similarly test the launcher. This test can be run optionally by using the + * following jtreg option: + * "-javaoptions:-DBigJar_testScenarioB=true" + * or set + * "BigJar_testScenarioB" environment variable. + * + * Note this test will only run iff all the disk requirements are met at runtime. + */ +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class BigJar extends TestHelper { + + private static final long GIGA = 1024 * 1024 * 1024; + private static final int BUFFER_LEN = Short.MAX_VALUE * 2; + + long getCount(long minlength) { + return (minlength / BUFFER_LEN) + 1; + } + + long computeCRC(long minlength) { + CRC32 crc = new CRC32(); + byte[] buffer = new byte[BUFFER_LEN]; + long count = getCount(minlength); + for (long i = 0; i < count; i++) { + crc.update(buffer); + } + return crc.getValue(); + } + + long computeCRC(File inFile) throws IOException { + byte[] buffer = new byte[8192]; + CRC32 crc = new CRC32(); + try (FileInputStream fis = new FileInputStream(inFile); + BufferedInputStream bis = new BufferedInputStream(fis)) { + int n = bis.read(buffer); + while (n > 0) { + crc.update(buffer, 0, n); + n = bis.read(buffer); + } + } + return crc.getValue(); + } + + void createLargeFile(OutputStream os, long minlength) throws IOException { + byte[] buffer = new byte[BUFFER_LEN]; + long count = getCount(minlength); + for (long i = 0; i < count; i++) { + os.write(buffer); + } + os.flush(); + } + + Manifest createMainClass(File javaFile) throws IOException { + javaFile.delete(); + List content = new ArrayList<>(); + content.add("public class " + baseName(javaFile) + "{"); + content.add("public static void main(String... args) {"); + content.add("System.out.println(\"Hello World\\n\");"); + content.add("System.exit(0);"); + content.add("}"); + content.add("}"); + createFile(javaFile, content); + compile(javaFile.getName()); + Manifest manifest = new Manifest(); + manifest.clear(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, baseName(javaFile)); + System.out.println(manifest.getMainAttributes().keySet()); + System.out.println(manifest.getMainAttributes().values()); + return manifest; + } + + void createJarWithLargeFile(File jarFile, long minlength) throws IOException { + File javaFile = new File("Foo.java"); + Manifest manifest = createMainClass(javaFile); + File classFile = getClassFile(javaFile); + try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile), manifest); + BufferedOutputStream bos = new BufferedOutputStream(jos); + FileInputStream fis = new FileInputStream(classFile);) { + jos.setLevel(ZipOutputStream.STORED); + jos.setMethod(0); + + JarEntry je = new JarEntry("large.data"); + je.setCompressedSize(getCount(minlength) * BUFFER_LEN); + je.setSize(getCount(minlength) * BUFFER_LEN); + je.setCrc(computeCRC(minlength)); + je.setMethod(ZipEntry.STORED); + jos.putNextEntry(je); + createLargeFile(bos, minlength); + + je = new JarEntry(classFile.getName()); + je.setCompressedSize(classFile.length()); + je.setSize(classFile.length()); + je.setCrc(computeCRC(classFile)); + je.setMethod(ZipEntry.STORED); + jos.putNextEntry(je); + copyStream(fis, bos); + bos.flush(); + jos.closeEntry(); + } + } + + void createLargeJar(File jarFile, String comment) throws IOException { + final int MAX = Short.MAX_VALUE * 2 + 10; + JarEntry je = null; + File javaFile = new File("Foo.java"); + File classFile = getClassFile(javaFile); + Manifest manifest = createMainClass(javaFile); + try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile), manifest); + FileInputStream fis = new FileInputStream(classFile)) { + jos.setLevel(JarOutputStream.STORED); + jos.setMethod(JarOutputStream.STORED); + for (int i = 0; i < MAX; i++) { + je = new JarEntry("X" + i + ".txt"); + je.setSize(0); + je.setCompressedSize(0); + je.setCrc(0); + jos.putNextEntry(je); + } + + // add a class file + je = new JarEntry(classFile.getName()); + je.setCompressedSize(classFile.length()); + je.setSize(classFile.length()); + je.setCrc(computeCRC(classFile)); + jos.putNextEntry(je); + copyStream(fis, jos); + jos.closeEntry(); + if (comment != null) { + jos.setComment(comment); + } + } + } + + void testTheJar(File theJar) throws Exception { + try { + TestResult tr = doExec(javaCmd, "-jar", theJar.getName()); + tr.checkPositive(); + if (!tr.testStatus) { + System.out.println(tr); + throw new Exception("Failed"); + } + } finally { + theJar.delete(); + } + } + + // a jar with entries exceeding 64k + a class file for the existential test + @Test + void testScenarioA() throws Exception { + File largeJar = new File("large.jar"); + createLargeJar(largeJar, null); + testTheJar(largeJar); + } + + // a jar with entries exceeding 64k and zip comment + @Test + void testScenarioA1() throws Exception { + File largeJar = new File("largewithcomment.jar"); + createLargeJar(largeJar, "A really large jar with a comment"); + testTheJar(largeJar); + } + + // a jar with an enormous file + a class file for the existential test + @Test + void testScenarioB() throws Exception { + final String testString = "BigJar_testScenarioB"; + if (Boolean.getBoolean(testString) == false && + System.getenv(testString) == null) { + System.out.println("Warning: testScenarioB passes vacuously"); + return; + } + final File largeJar = new File("huge.jar"); + + final Path path = largeJar.getAbsoluteFile().getParentFile().toPath(); + final long available = Files.getFileStore(path).getUsableSpace(); + final long MAX_VALUE = 0xFFFF_FFFFL; + + final long absolute = MAX_VALUE + 1L; + final long required = (long) (absolute * 1.1); // pad for sundries + System.out.println("\tavailable: " + available / GIGA + " GB"); + System.out.println("\trequired: " + required / GIGA + " GB"); + + if (available > required) { + createJarWithLargeFile(largeJar, absolute); + testTheJar(largeJar); + } else { + System.out.println("Warning: testScenarioB passes vacuously," + + " requirements exceeds available space"); + } + } + + public static void main(String... args) throws Exception { + BigJar bj = new BigJar(); + bj.run(args); + if (testExitValue > 0) { + System.out.println("Total of " + testExitValue + " failed"); + System.exit(1); + } else { + System.out.println("All tests pass"); + } + } +} diff --git a/jdk/test/tools/launcher/TestHelper.java b/jdk/test/tools/launcher/TestHelper.java index 893b90f2f06..6738eba5e19 100644 --- a/jdk/test/tools/launcher/TestHelper.java +++ b/jdk/test/tools/launcher/TestHelper.java @@ -21,6 +21,8 @@ * questions. */ +import java.io.OutputStream; +import java.io.InputStream; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -243,6 +245,21 @@ public class TestHelper { return null; } + static File getClassFile(File javaFile) { + String s = javaFile.getAbsolutePath().replace(JAVA_FILE_EXT, CLASS_FILE_EXT); + return new File(s); + } + + static File getJavaFile(File classFile) { + String s = classFile.getAbsolutePath().replace(CLASS_FILE_EXT, JAVA_FILE_EXT); + return new File(s); + } + + static String baseName(File f) { + String s = f.getName(); + return s.substring(0, s.indexOf(".")); + } + /* * A convenience method to create a jar with jar file name and defs */ @@ -324,6 +341,15 @@ public class TestHelper { } } + static void copyStream(InputStream in, OutputStream out) throws IOException { + byte[] buf = new byte[8192]; + int n = in.read(buf); + while (n > 0) { + out.write(buf, 0, n); + n = in.read(buf); + } + } + static void copyFile(File src, File dst) throws IOException { Path parent = dst.toPath().getParent(); if (parent != null) { diff --git a/langtools/.hgtags b/langtools/.hgtags index 737fc671631..653073cff9c 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -176,3 +176,4 @@ c4cd4cab2220817c88c8c139c9bfc91c36b48826 jdk8-b51 1d2db0e5eabc2eaf865986f7b7ffbf7b14b00232 jdk8-b52 d3d0b9cd76e04bf9e381b402630ac3cfe464bb38 jdk8-b53 9cf72631baf5cb1ebd8736c5efeab7746977ea68 jdk8-b54 +e48e7e1f026b82d921433150180799898c088890 jdk8-b55 diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java new file mode 100644 index 00000000000..486e9b6a4a4 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2012, 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.tools.javac.code; + +import java.util.Map; +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.comp.Annotate; +import com.sun.tools.javac.comp.AttrContext; +import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Pair; + +import static com.sun.tools.javac.code.Kinds.PCK; +import com.sun.tools.javac.util.*; + +/** + * Container for all annotations (attributes in javac) on a Symbol. + * + * This class is explicitly mutable. Its contents will change when attributes + * are annotated onto the Symbol. However this class depends on the facts that + * List (in javac) is immutable. + * + * An instance of this class can be in one of three states: + * + * NOT_STARTED indicates that the Symbol this instance belongs to have not been + * annotated (yet). Specifically if the declaration is not annotated this + * instance will never move past NOT_STARTED. You can never go back to + * NOT_STARTED. + * + * IN_PROGRESS annotations have been found on the declaration. Will be processed + * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list + * of attributes (and this moves out of the IN_PROGRESS state). + * + * "unnamed" this Annotations contains some attributes, possibly the final set. + * While in this state you can only prepend or append to the attributes not set + * it directly. You can also move back to the IN_PROGRESS sate using reset(). + * + *

This is NOT part of any supported API. If you write code that depends + * on this, you do so at your own risk. This code and its internal interfaces + * are subject to change or deletion without notice. + */ +public class Annotations { + + private static final List NOT_STARTED = List.of(null); + private static final List IN_PROGRESS = List.of(null); + /* + * This field should never be null + */ + private List attributes = NOT_STARTED; + /* + * The Symbol this Annotatios belong to + */ + private final Symbol s; + + public Annotations(Symbol s) { + this.s = s; + } + + public List getAttributes() { + return filterSentinels(attributes); + } + + public void setAttributes(List a) { + Assert.check(pendingCompletion() || !isStarted()); + if (a == null) { + throw new NullPointerException(); + } + attributes = a; + } + + public void setAttributes(Annotations other) { + if (other == null) { + throw new NullPointerException(); + } + setAttributes(other.getAttributes()); + } + + public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) { + Assert.check(pendingCompletion() || (!isStarted() && s.kind == PCK)); + + Map> annotated = ctx.annotated; + boolean atLeastOneRepeated = false; + List buf = List.nil(); + for (ListBuffer lb : annotated.values()) { + if (lb.size() == 1) { + buf = buf.prepend(lb.first()); + } else { // repeated + buf = buf.prepend(new Placeholder(lb.toList(), s)); + atLeastOneRepeated = true; + } + } + + // Add non-repeating attributes + setAttributes(buf.reverse()); + + if (atLeastOneRepeated) { + // The Symbol s is now annotated with a combination of + // finished non-repeating annotations and placeholders for + // repeating annotations. + // + // We need to do this in two passes because when creating + // a container for a repeating annotation we must + // guarantee that the @ContainedBy on the + // contained annotation is fully annotated + // + // The way we force this order is to do all repeating + // annotations in a pass after all non-repeating are + // finished. This will work because @ContainedBy + // is non-repeating and therefore will be annotated in the + // fist pass. + + // Queue a pass that will replace Attribute.Placeholders + // with Attribute.Compound (made from synthesized containers). + ctx.annotateRepeated(new Annotate.Annotator() { + + @Override + public String toString() { + return "repeated annotation pass of: " + s + " in: " + s.owner; + } + + @Override + public void enterAnnotation() { + complete(ctx); + } + }); + } + } + + public Annotations reset() { + attributes = IN_PROGRESS; + return this; + } + + public boolean isEmpty() { + return !isStarted() + || pendingCompletion() + || attributes.isEmpty(); + } + + public boolean pendingCompletion() { + return attributes == IN_PROGRESS; + } + + public Annotations append(List l) { + attributes = filterSentinels(attributes); + + if (l.isEmpty()) { + ; // no-op + } else if (attributes.isEmpty()) { + attributes = l; + } else { + attributes = attributes.appendList(l); + } + return this; + } + + public Annotations prepend(List l) { + attributes = filterSentinels(attributes); + + if (l.isEmpty()) { + ; // no-op + } else if (attributes.isEmpty()) { + attributes = l; + } else { + attributes = attributes.prependList(l); + } + return this; + } + + private List filterSentinels(List a) { + return (a == IN_PROGRESS || a == NOT_STARTED) + ? List.nil() + : a; + } + + private boolean isStarted() { + return attributes != NOT_STARTED; + } + + private List getPlaceholders() { + List res = List.nil(); + for (Attribute.Compound a : filterSentinels(attributes)) { + if (a instanceof Placeholder) { + res = res.prepend(a); + } + } + return res.reverse(); + } + + /* + * Replace Placeholders for repeating annotations with their containers + */ + private void complete(Annotate.AnnotateRepeatedContext ctx) { + Assert.check(!pendingCompletion()); + Log log = ctx.log; + Env env = ctx.env; + JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); + try { + + if (isEmpty()) { + return; + } + + List result = List.nil(); + for (Attribute.Compound a : getAttributes()) { + if (a instanceof Placeholder) { + Attribute.Compound replacement = replaceOne((Placeholder) a, ctx); + + if (null != replacement) { + result = result.prepend(replacement); + } + } else { + result = result.prepend(a); + } + } + + attributes = result.reverse(); + + Assert.check(Annotations.this.getPlaceholders().isEmpty()); + } finally { + log.useSource(oldSource); + } + } + + private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) { + Log log = ctx.log; + + // Process repeated annotations + Attribute.Compound validRepeated = + ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor()); + + if (validRepeated != null) { + // Check that the container isn't manually + // present along with repeated instances of + // its contained annotation. + ListBuffer manualContainer = ctx.annotated.get(validRepeated.type.tsym); + if (manualContainer != null) { + log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present", + manualContainer.first().type.tsym); + } + } + + // A null return will delete the Placeholder + return validRepeated; + + } + + private static class Placeholder extends Attribute.Compound { + + private List placeholderFor; + private Symbol on; + + public Placeholder(List placeholderFor, Symbol on) { + super(Type.noType, List.>nil()); + this.placeholderFor = placeholderFor; + this.on = on; + } + + @Override + public String toString() { + return ""; + } + + public List getPlaceholderFor() { + return placeholderFor; + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java index 37bb6eebe72..0460ac9aa1e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -103,11 +103,11 @@ public abstract class Attribute implements AnnotationValue { * represented as a ClassSymbol. */ public static class Class extends Attribute { - public final Type type; + public final Type classType; public void accept(Visitor v) { v.visitClass(this); } public Class(Types types, Type type) { super(makeClassType(types, type)); - this.type = type; + this.classType = type; } static Type makeClassType(Types types, Type type) { Type arg = type.isPrimitive() @@ -118,13 +118,13 @@ public abstract class Attribute implements AnnotationValue { types.syms.classType.tsym); } public String toString() { - return type + ".class"; + return classType + ".class"; } public Type getValue() { - return type; + return classType; } public R accept(AnnotationValueVisitor v, P p) { - return v.visitType(type, p); + return v.visitType(classType, p); } } @@ -212,6 +212,12 @@ public abstract class Attribute implements AnnotationValue { super(type); this.values = values; } + + public Array(Type type, List values) { + super(type); + this.values = values.toArray(new Attribute[values.size()]); + } + public void accept(Visitor v) { v.visitArray(this); } public String toString() { StringBuilder buf = new StringBuilder(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java index 46f7bddb4be..e3ed0f35983 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, 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 @@ -70,16 +70,16 @@ public class Lint * Returns the result of combining the values in this object with * the given annotations. */ - public Lint augment(List attrs) { - return augmentor.augment(this, attrs); + public Lint augment(Annotations annots) { + return augmentor.augment(this, annots.getAttributes()); } /** * Returns the result of combining the values in this object with * the given annotations and flags. */ - public Lint augment(List attrs, long flags) { - Lint l = augmentor.augment(this, attrs); + public Lint augment(Annotations annots, long flags) { + Lint l = augmentor.augment(this, annots.getAttributes()); if ((flags & DEPRECATED) != 0) { if (l == this) l = new Lint(this); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java index 9fcbba44709..e17d1a1fa81 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java @@ -203,6 +203,9 @@ public enum Source { public boolean allowEffectivelyFinalInInnerClasses() { return compareTo(JDK1_8) >= 0; } + public boolean allowRepeatedAnnotations() { + return compareTo(JDK1_8) >= 0; + } public static SourceVersion toSourceVersion(Source source) { switch(source) { case JDK1_2: diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 238b25d09b2..fc651b4a1f3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -72,22 +72,24 @@ public abstract class Symbol implements Element { */ public long flags() { return flags_field; } - /** The attributes of this symbol. + /** The attributes of this symbol are contained in this + * Annotations. The Annotations instance is NOT immutable. */ - public List attributes_field; + public final Annotations annotations = new Annotations(this); /** An accessor method for the attributes of this symbol. * Attributes of class symbols should be accessed through the accessor * method to make sure that the class symbol is loaded. */ public List getAnnotationMirrors() { - return Assert.checkNonNull(attributes_field); + return Assert.checkNonNull(annotations.getAttributes()); } /** Fetch a particular annotation from a symbol. */ public Attribute.Compound attribute(Symbol anno) { - for (Attribute.Compound a : getAnnotationMirrors()) + for (Attribute.Compound a : getAnnotationMirrors()) { if (a.type.tsym == anno) return a; + } return null; } @@ -120,7 +122,6 @@ public abstract class Symbol implements Element { this.owner = owner; this.completer = null; this.erasure_field = null; - this.attributes_field = List.nil(); this.name = name; } @@ -657,10 +658,11 @@ public abstract class Symbol implements Element { if (completer != null) complete(); if (package_info != null && package_info.completer != null) { package_info.complete(); - if (attributes_field.isEmpty()) - attributes_field = package_info.attributes_field; + if (annotations.isEmpty()) { + annotations.setAttributes(package_info.annotations); } - return Assert.checkNonNull(attributes_field); + } + return Assert.checkNonNull(annotations.getAttributes()); } /** A package "exists" if a type or package that exists has @@ -762,7 +764,7 @@ public abstract class Symbol implements Element { public List getAnnotationMirrors() { if (completer != null) complete(); - return Assert.checkNonNull(attributes_field); + return Assert.checkNonNull(annotations.getAttributes()); } public Type erasure(Types types) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 31cb45e9622..7b35ad53784 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -156,6 +156,10 @@ public class Symtab { public final Type systemType; public final Type autoCloseableType; public final Type trustMeType; + public final Type containedByType; + public final Type containerForType; + public final Type documentedType; + public final Type elementTypeType; /** The symbol representing the length field of an array. */ @@ -468,6 +472,10 @@ public class Symtab { deprecatedType = enterClass("java.lang.Deprecated"); suppressWarningsType = enterClass("java.lang.SuppressWarnings"); inheritedType = enterClass("java.lang.annotation.Inherited"); + containedByType = enterClass("java.lang.annotation.ContainedBy"); + containerForType = enterClass("java.lang.annotation.ContainerFor"); + documentedType = enterClass("java.lang.annotation.Documented"); + elementTypeType = enterClass("java.lang.annotation.ElementType"); systemType = enterClass("java.lang.System"); autoCloseableType = enterClass("java.lang.AutoCloseable"); autoCloseableClose = new MethodSymbol(PUBLIC, diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 98f081a6686..4fdfd4d1ef8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -1358,6 +1358,20 @@ public class Types { } return result; } + + /** + * Returns an ArrayType with the component type t + * + * @param t The component type of the ArrayType + * @return the ArrayType for the given component + */ + public ArrayType makeArrayType(Type t) { + if (t.tag == VOID || + t.tag >= PACKAGE) { + Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString()); + } + return new ArrayType(t, syms.arrayClass); + } // // @@ -3811,8 +3825,12 @@ public class Types { // public RetentionPolicy getRetention(Attribute.Compound a) { + return getRetention(a.type.tsym); + } + + public RetentionPolicy getRetention(Symbol sym) { RetentionPolicy vis = RetentionPolicy.CLASS; // the default - Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym); + Attribute.Compound c = sym.attribute(syms.retentionType.tsym); if (c != null) { Attribute value = c.member(names.value); if (value != null && value instanceof Attribute.Enum) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index 724481e54ae..eae5e943c23 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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,7 +25,11 @@ package com.sun.tools.javac.comp; +import java.util.Map; +import java.util.Objects; + import com.sun.tools.javac.util.*; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.*; @@ -83,8 +87,9 @@ public class Annotate { private int enterCount = 0; ListBuffer q = new ListBuffer(); + ListBuffer repeatedQ = new ListBuffer(); - public void later(Annotator a) { + public void normal(Annotator a) { q.append(a); } @@ -92,6 +97,10 @@ public class Annotate { q.prepend(a); } + public void repeated(Annotator a) { + repeatedQ.append(a); + } + /** Called when the Enter phase starts. */ public void enterStart() { enterCount++; @@ -109,6 +118,10 @@ public class Annotate { try { while (q.nonEmpty()) q.next().enterAnnotation(); + + while (repeatedQ.nonEmpty()) { + repeatedQ.next().enterAnnotation(); + } } finally { enterCount--; } @@ -124,6 +137,53 @@ public class Annotate { String toString(); } + /** + * This context contains all the information needed to synthesize new + * annotations trees by the completer for repeating annotations. + */ + public class AnnotateRepeatedContext { + public final Env env; + public final Map> annotated; + public final Map pos; + public final Log log; + + public AnnotateRepeatedContext(Env env, + Map> annotated, + Map pos, + Log log) { + Objects.requireNonNull(env); + Objects.requireNonNull(annotated); + Objects.requireNonNull(pos); + Objects.requireNonNull(log); + + this.env = env; + this.annotated = annotated; + this.pos = pos; + this.log = log; + } + + /** + * Process a list of repeating annotations returning a new + * Attribute.Compound that is the attribute for the synthesized tree + * for the container. + * + * @param repeatingAnnotations a List of repeating annotations + * @return a new Attribute.Compound that is the container for the repeatingAnnotations + */ + public Attribute.Compound processRepeatedAnnotations(List repeatingAnnotations) { + return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this); + } + + /** + * Queue the Annotator a on the repeating annotations queue of the + * Annotate instance this context belongs to. + * + * @param a the Annotator to enqueue for repeating annotation annotating + */ + public void annotateRepeated(Annotator a) { + Annotate.this.repeated(a); + } + } /* ******************************************************************** * Compute an attribute from its annotation. @@ -268,4 +328,219 @@ public class Annotate { log.error(tree.pos(), "annotation.value.not.allowable.type"); return new Attribute.Error(attr.attribExpr(tree, env, expected)); } + + /* ********************************* + * Support for repeating annotations + ***********************************/ + + /* Process repeated annotations. This method returns the + * synthesized container annotation or null IFF all repeating + * annotation are invalid. This method reports errors/warnings. + */ + private Attribute.Compound processRepeatedAnnotations(List annotations, + AnnotateRepeatedContext ctx) { + Attribute.Compound firstOccurrence = annotations.head; + List repeated = List.nil(); + Type origAnnoType; + Type arrayOfOrigAnnoType = null; + Type targetContainerType = null; + MethodSymbol containerValueSymbol = null; + + Assert.check(!annotations.isEmpty() && + !annotations.tail.isEmpty()); // i.e. size() > 1 + + for (List al = annotations; + !al.isEmpty(); + al = al.tail) + { + Attribute.Compound currentAnno = al.head; + + origAnnoType = currentAnno.type; + if (arrayOfOrigAnnoType == null) { + arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); +} + + Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno)); + if (currentContainerType == null) { + continue; + } + // Assert that the target Container is == for all repeated + // annos of the same annotation type, the types should + // come from the same Symbol, i.e. be '==' + Assert.check(targetContainerType == null || currentContainerType == targetContainerType); + targetContainerType = currentContainerType; + + containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno)); + + if (containerValueSymbol == null) { // Check of CA type failed + // errors are already reported + continue; + } + + repeated = repeated.prepend(currentAnno); + } + + if (!repeated.isEmpty()) { + repeated = repeated.reverse(); + JCAnnotation annoTree; + TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); + Pair p = + new Pair(containerValueSymbol, + new Attribute.Array(arrayOfOrigAnnoType, repeated)); + annoTree = m.Annotation(new Attribute.Compound(targetContainerType, + List.of(p))); + Attribute.Compound c = enterAnnotation(annoTree, + targetContainerType, + ctx.env); + return c; + } else { + return null; // errors should have been reported elsewhere + } + } + + /** Fetches the actual Type that should be the containing annotation. */ + private Type getContainingType(Attribute.Compound currentAnno, + DiagnosticPosition pos) + { + Type origAnnoType = currentAnno.type; + TypeSymbol origAnnoDecl = origAnnoType.tsym; + + // Fetch the ContainedBy annotation from the current + // annotation's declaration, or null if it has none + Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym); + if (ca == null) { // has no ContainedBy annotation + log.error(pos, "duplicate.annotation.missing.container", origAnnoType); + return null; + } + + return filterSame(extractContainingType(ca, pos, origAnnoDecl), + origAnnoType); + } + + // returns null if t is same as 's', returns 't' otherwise + private Type filterSame(Type t, Type s) { + if (t == null || s == null) { + return t; + } + + return types.isSameType(t, s) ? null : t; + } + + /** Extract the actual Type to be used for a containing annotation. */ + private Type extractContainingType(Attribute.Compound ca, + DiagnosticPosition pos, + TypeSymbol annoDecl) + { + // The next three checks check that the ContainedBy annotation + // on the declaration of the annotation type that is repeating is + // valid. + + // ContainedBy must have at least one element + if (ca.values.isEmpty()) { + log.error(pos, "invalid.containedby.annotation", annoDecl); + return null; + } + Pair p = ca.values.head; + Name name = p.fst.name; + if (name != names.value) { // should contain only one element, named "value" + log.error(pos, "invalid.containedby.annotation", annoDecl); + return null; + } + if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class + log.error(pos, "invalid.containedby.annotation", annoDecl); + return null; + } + + return ((Attribute.Class)p.snd).getValue(); + } + + /* Validate that the suggested targetContainerType Type is a valid + * container type for repeated instances of originalAnnoType + * annotations. Return null and report errors if this is not the + * case, return the MethodSymbol of the value element in + * targetContainerType if it is suitable (this is needed to + * synthesize the container). */ + private MethodSymbol validateContainer(Type targetContainerType, + Type originalAnnoType, + DiagnosticPosition pos) { + MethodSymbol containerValueSymbol = null; + boolean fatalError = false; + + // Validate that there is a (and only 1) value method + Scope scope = targetContainerType.tsym.members(); + int nr_value_elems = 0; + boolean error = false; + for(Symbol elm : scope.getElementsByName(names.value)) { + nr_value_elems++; + + if (nr_value_elems == 1 && + elm.kind == Kinds.MTH) { + containerValueSymbol = (MethodSymbol)elm; + } else { + error = true; + } + } + if (error) { + log.error(pos, + "invalid.containedby.annotation.multiple.values", + targetContainerType, + nr_value_elems); + return null; + } else if (nr_value_elems == 0) { + log.error(pos, + "invalid.containedby.annotation.no.value", + targetContainerType); + return null; + } + + // validate that the 'value' element is a method + // probably "impossible" to fail this + if (containerValueSymbol.kind != Kinds.MTH) { + log.error(pos, + "invalid.containedby.annotation.invalid.value", + targetContainerType); + fatalError = true; + } + + // validate that the 'value' element has the correct return type + // i.e. array of original anno + Type valueRetType = containerValueSymbol.type.getReturnType(); + Type expectedType = types.makeArrayType(originalAnnoType); + if (!(types.isArray(valueRetType) && + types.isSameType(expectedType, valueRetType))) { + log.error(pos, + "invalid.containedby.annotation.value.return", + targetContainerType, + valueRetType, + expectedType); + fatalError = true; + } + + // validate that all other elements of containing type has defaults + scope = targetContainerType.tsym.members(); + error = false; + for(Symbol elm : scope.getElements()) { + if (elm.name != names.value && + elm.kind == Kinds.MTH && + ((MethodSymbol)elm).defaultValue == null) { + log.error(pos, + "invalid.containedby.annotation.elem.nondefault", + targetContainerType, + elm); + containerValueSymbol = null; + error = true; + } + } + if (error) { + fatalError = true; + } + + // Explicitly no check for/validity of @ContainerFor. That is + // done on declaration of the container, and at reflect time. + + // The rest of the conditions for a valid containing annotation are made + // in Check.validateRepeatedAnnotaton(); + + return fatalError ? null : containerValueSymbol; + } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 180966dffaf..b9613fa31c1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -662,10 +662,12 @@ public class Attr extends JCTree.Visitor { // env.info.enclVar.attributes_field might not yet have been evaluated, and so might be // null. In that case, calling augment will throw an NPE. To avoid this, for now we // revert to the jdk 6 behavior and ignore the (unevaluated) attributes. - if (env.info.enclVar.attributes_field == null) + if (env.info.enclVar.annotations.pendingCompletion()) { env.info.lint = lintEnv.info.lint; - else - env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags()); + } else { + env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.annotations, + env.info.enclVar.flags()); + } Lint prevLint = chk.setLint(env.info.lint); JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); @@ -776,7 +778,7 @@ public class Attr extends JCTree.Visitor { public void visitMethodDef(JCMethodDecl tree) { MethodSymbol m = tree.sym; - Lint lint = env.info.lint.augment(m.attributes_field, m.flags()); + Lint lint = env.info.lint.augment(m.annotations, m.flags()); Lint prevLint = chk.setLint(lint); MethodSymbol prevMethod = chk.setMethod(m); try { @@ -921,7 +923,7 @@ public class Attr extends JCTree.Visitor { } VarSymbol v = tree.sym; - Lint lint = env.info.lint.augment(v.attributes_field, v.flags()); + Lint lint = env.info.lint.augment(v.annotations, v.flags()); Lint prevLint = chk.setLint(lint); // Check that the variable's declared type is well-formed. @@ -3069,7 +3071,7 @@ public class Attr extends JCTree.Visitor { lintEnv = lintEnv.next; // Having found the enclosing lint value, we can initialize the lint value for this class - env.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags()); + env.info.lint = lintEnv.info.lint.augment(c.annotations, c.flags()); Lint prevLint = chk.setLint(env.info.lint); JavaFileObject prev = log.useSource(c.sourcefile); @@ -3133,6 +3135,26 @@ public class Attr extends JCTree.Visitor { if (tree.typarams.nonEmpty()) log.error(tree.typarams.head.pos(), "intf.annotation.cant.have.type.params"); + + // If this annotation has a @ContainedBy, validate + Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym); + if (containedBy != null) { + // get diagnositc position for error reporting + DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type); + Assert.checkNonNull(cbPos); + + chk.validateContainedBy(c, containedBy, cbPos); + } + + // If this annotation has a @ContainerFor, validate + Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym); + if (containerFor != null) { + // get diagnositc position for error reporting + DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type); + Assert.checkNonNull(cfPos); + + chk.validateContainerFor(c, containerFor, cfPos); + } } else { // Check that all extended classes and interfaces // are compatible (i.e. no two define methods with same arguments @@ -3194,6 +3216,16 @@ public class Attr extends JCTree.Visitor { } } // where + /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ + private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) { + for(List al = tree.mods.annotations; !al.isEmpty(); al = al.tail) { + if (types.isSameType(al.head.annotationType.type, t)) + return al.head.pos(); + } + + return null; + } + /** check if a class is a subtype of Serializable, if that is available. */ private boolean isSerializable(ClassSymbol c) { try { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index ac18d9f0b42..627258727c1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -69,7 +69,6 @@ public class Check { private final Infer infer; private final Types types; private final JCDiagnostic.Factory diags; - private final boolean skipAnnotations; private boolean warnOnSyntheticConflicts; private boolean suppressAbortOnBadClassFile; private boolean enableSunApiLintControl; @@ -113,7 +112,6 @@ public class Check { allowCovariantReturns = source.allowCovariantReturns(); allowSimplifiedVarargs = source.allowSimplifiedVarargs(); complexInference = options.isSet("complexinference"); - skipAnnotations = options.isSet("skipAnnotations"); warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); enableSunApiLintControl = options.isSet("enableSunApiLintControl"); @@ -2422,14 +2420,13 @@ public class Check { /** Check the annotations of a symbol. */ public void validateAnnotations(List annotations, Symbol s) { - if (skipAnnotations) return; for (JCAnnotation a : annotations) validateAnnotation(a, s); } /** Check an annotation of a symbol. */ - public void validateAnnotation(JCAnnotation a, Symbol s) { + private void validateAnnotation(JCAnnotation a, Symbol s) { validateAnnotationTree(a); if (!annotationApplicable(a, s)) @@ -2441,6 +2438,215 @@ public class Check { } } + /** + * Validate the proposed container 'containedBy' on the + * annotation type symbol 's'. Report errors at position + * 'pos'. + * + * @param s The (annotation)type declaration annotated with a @ContainedBy + * @param containerAnno the @ContainedBy on 's' + * @param pos where to report errors + */ + public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) { + Assert.check(types.isSameType(containedBy.type, syms.containedByType)); + + Type t = null; + List> l = containedBy.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containedby", s, containedBy); + return; + } + + validateHasContainerFor(t.tsym, s, pos); + validateRetention(t.tsym, s, pos); + validateDocumented(t.tsym, s, pos); + validateInherited(t.tsym, s, pos); + validateTarget(t.tsym, s, pos); + } + + /** + * Validate the proposed container 'containerFor' on the + * annotation type symbol 's'. Report errors at position + * 'pos'. + * + * @param s The (annotation)type declaration annotated with a @ContainerFor + * @param containerFor the @ContainedFor on 's' + * @param pos where to report errors + */ + public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) { + Assert.check(types.isSameType(containerFor.type, syms.containerForType)); + + Type t = null; + List> l = containerFor.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containerfor", s, containerFor); + return; + } + + validateHasContainedBy(t.tsym, s, pos); + } + + private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { + Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym); + + if (containedBy == null) { + log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym); + return; + } + + Type t = null; + List> l = containedBy.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containedby", container, contained); + return; + } + + if (!types.isSameType(t, contained.type)) + log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained); + } + + private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { + Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym); + + if (containerFor == null) { + log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym); + return; + } + + Type t = null; + List> l = containerFor.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containerfor", container, contained); + return; + } + + if (!types.isSameType(t, contained.type)) + log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained); + } + + private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { + Attribute.RetentionPolicy containerRetention = types.getRetention(container); + Attribute.RetentionPolicy containedRetention = types.getRetention(contained); + + boolean error = false; + switch (containedRetention) { + case RUNTIME: + if (containerRetention != Attribute.RetentionPolicy.RUNTIME) { + error = true; + } + break; + case CLASS: + if (containerRetention == Attribute.RetentionPolicy.SOURCE) { + error = true; + } + } + if (error ) { + log.error(pos, "invalid.containedby.annotation.retention", + container, containerRetention, + contained, containedRetention); + } + } + + private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { + if (contained.attribute(syms.documentedType.tsym) != null) { + if (container.attribute(syms.documentedType.tsym) == null) { + log.error(pos, "invalid.containedby.annotation.not.documented", container, contained); + } + } + } + + private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { + if (contained.attribute(syms.inheritedType.tsym) != null) { + if (container.attribute(syms.inheritedType.tsym) == null) { + log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained); + } + } + } + + private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { + Attribute.Array containedTarget = getAttributeTargetAttribute(contained); + + // If contained has no Target, we are done + if (containedTarget == null) { + return; + } + + // If contained has Target m1, container must have a Target + // annotation, m2, and m2 must be a subset of m1. (This is + // trivially true if contained has no target as per above). + + // contained has target, but container has not, error + Attribute.Array containerTarget = getAttributeTargetAttribute(container); + if (containerTarget == null) { + log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); + return; + } + + Set containerTargets = new HashSet(); + for (Attribute app : containerTarget.values) { + if (!(app instanceof Attribute.Enum)) { + continue; // recovery + } + Attribute.Enum e = (Attribute.Enum)app; + containerTargets.add(e.value.name); + } + + Set containedTargets = new HashSet(); + for (Attribute app : containedTarget.values) { + if (!(app instanceof Attribute.Enum)) { + continue; // recovery + } + Attribute.Enum e = (Attribute.Enum)app; + containedTargets.add(e.value.name); + } + + if (!isTargetSubset(containedTargets, containerTargets)) { + log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); + } + } + + /** Checks that t is a subset of s, with respect to ElementType + * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE} + */ + private boolean isTargetSubset(Set s, Set t) { + // Check that all elements in t are present in s + for (Name n2 : t) { + boolean currentElementOk = false; + for (Name n1 : s) { + if (n1 == n2) { + currentElementOk = true; + break; + } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) { + currentElementOk = true; + break; + } + } + if (!currentElementOk) + return false; + } + return true; + } + /** Is s a method symbol that overrides a method in a superclass? */ boolean isOverrider(Symbol s) { if (s.kind != MTH || s.isStatic()) @@ -2461,12 +2667,10 @@ public class Check { /** Is the annotation applicable to the symbol? */ boolean annotationApplicable(JCAnnotation a, Symbol s) { - Attribute.Compound atTarget = - a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); - if (atTarget == null) return true; - Attribute atValue = atTarget.member(names.value); - if (!(atValue instanceof Attribute.Array)) return true; // error recovery - Attribute.Array arr = (Attribute.Array) atValue; + Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); + if (arr == null) { + return true; + } for (Attribute app : arr.values) { if (!(app instanceof Attribute.Enum)) return true; // recovery Attribute.Enum e = (Attribute.Enum) app; @@ -2508,6 +2712,16 @@ public class Check { return false; } + + Attribute.Array getAttributeTargetAttribute(Symbol s) { + Attribute.Compound atTarget = + s.attribute(syms.annotationTargetType.tsym); + if (atTarget == null) return null; // ok, is applicable + Attribute atValue = atTarget.member(names.value); + if (!(atValue instanceof Attribute.Array)) return null; // error recovery + return (Attribute.Array) atValue; + } + /** Check an annotation value. */ public void validateAnnotation(JCAnnotation a) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index 514d651be93..22e0c9231f5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -157,7 +157,7 @@ public class Enter extends JCTree.Visitor { Env lintEnv = localEnv; while (lintEnv.info.lint == null) lintEnv = lintEnv.next; - localEnv.info.lint = lintEnv.info.lint.augment(sym.attributes_field, sym.flags()); + localEnv.info.lint = lintEnv.info.lint.augment(sym.annotations, sym.flags()); return localEnv; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index fc4fde9a051..3dad6e3b2c3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -406,7 +406,7 @@ public class Flow { Lint lintPrev = lint; pendingExits = new ListBuffer(); - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try { // process all the static initializers @@ -442,7 +442,7 @@ public class Flow { if (tree.body == null) return; Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); Assert.check(pendingExits.isEmpty()); @@ -468,7 +468,7 @@ public class Flow { public void visitVarDef(JCVariableDecl tree) { if (tree.init != null) { Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try{ scan(tree.init); } finally { @@ -783,7 +783,7 @@ public class Flow { } classDef = tree; thrown = List.nil(); - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try { // process all the static initializers @@ -863,7 +863,7 @@ public class Flow { List mthrown = tree.sym.type.getThrownTypes(); Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); Assert.check(pendingExits.isEmpty()); @@ -902,7 +902,7 @@ public class Flow { public void visitVarDef(JCVariableDecl tree) { if (tree.init != null) { Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try{ scan(tree.init); } finally { @@ -1491,7 +1491,7 @@ public class Flow { firstadr = nextadr; } classDef = tree; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try { // define all the static fields @@ -1558,7 +1558,7 @@ public class Flow { int firstadrPrev = firstadr; Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); Assert.check(pendingExits.isEmpty()); @@ -1609,7 +1609,7 @@ public class Flow { if (track && tree.sym.owner.kind == MTH) newVar(tree.sym); if (tree.init != null) { Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try{ scanExpr(tree.init); if (track) letInit(tree.pos(), tree.sym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 1590ee79293..1745da3711b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2257,7 +2257,7 @@ public class Lower extends TreeTranslator { null, List.nil(), List.nil()); ClassSymbol c = tree.packge.package_info; c.flags_field |= flags; - c.attributes_field = tree.packge.attributes_field; + c.annotations.setAttributes(tree.packge.annotations); ClassType ctype = (ClassType) c.type; ctype.supertype_field = syms.objectType; ctype.interfaces_field = List.nil(); @@ -2274,7 +2274,8 @@ public class Lower extends TreeTranslator { case LEGACY: return tree.packageAnnotations.nonEmpty(); case NONEMPTY: - for (Attribute.Compound a: tree.packge.attributes_field) { + for (Attribute.Compound a : + tree.packge.annotations.getAttributes()) { Attribute.RetentionPolicy p = types.getRetention(a); if (p != Attribute.RetentionPolicy.SOURCE) return true; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index ff57daa4d59..70f021da099 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -76,11 +76,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final Annotate annotate; private final Types types; private final JCDiagnostic.Factory diags; + private final Source source; private final Target target; private final DeferredLintHandler deferredLintHandler; - private final boolean skipAnnotations; - public static MemberEnter instance(Context context) { MemberEnter instance = context.get(memberEnterKey); if (instance == null) @@ -102,10 +101,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { annotate = Annotate.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); + source = Source.instance(context); target = Target.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); - Options options = Options.instance(context); - skipAnnotations = options.isSet("skipAnnotations"); } /** A queue for classes whose members still need to be entered into the @@ -690,7 +688,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { public Env getMethodEnv(JCMethodDecl tree, Env env) { Env mEnv = methodEnv(tree, env); - mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags()); + mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags()); for (List l = tree.typarams; l.nonEmpty(); l = l.tail) mEnv.info.scope.enterIfAbsent(l.head.type.tsym); for (List l = tree.params; l.nonEmpty(); l = l.tail) @@ -727,18 +725,24 @@ public class MemberEnter extends JCTree.Visitor implements Completer { void annotateLater(final List annotations, final Env localEnv, final Symbol s) { - if (annotations.isEmpty()) return; - if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now - annotate.later(new Annotate.Annotator() { + if (annotations.isEmpty()) { + return; + } + if (s.kind != PCK) { + s.annotations.reset(); // mark Annotations as incomplete for now + } + annotate.normal(new Annotate.Annotator() { + @Override public String toString() { return "annotate " + annotations + " onto " + s + " in " + s.owner; } + + @Override public void enterAnnotation() { - Assert.check(s.kind == PCK || s.attributes_field == null); + Assert.check(s.kind == PCK || s.annotations.pendingCompletion()); JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { - if (s.attributes_field != null && - s.attributes_field.nonEmpty() && + if (!s.annotations.isEmpty() && annotations.nonEmpty()) log.error(annotations.head.pos, "already.annotated", @@ -756,7 +760,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { * java.lang.Deprecated. **/ private boolean hasDeprecatedAnnotation(List annotations) { - for (List al = annotations; al.nonEmpty(); al = al.tail) { + for (List al = annotations; !al.isEmpty(); al = al.tail) { JCAnnotation a = al.head; if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty()) return true; @@ -764,42 +768,62 @@ public class MemberEnter extends JCTree.Visitor implements Completer { return false; } - /** Enter a set of annotations. */ private void enterAnnotations(List annotations, Env env, Symbol s) { - ListBuffer buf = - new ListBuffer(); - Set annotated = new HashSet(); - if (!skipAnnotations) - for (List al = annotations; al.nonEmpty(); al = al.tail) { + Map> annotated = + new LinkedHashMap>(); + Map pos = + new HashMap(); + + for (List al = annotations; !al.isEmpty(); al = al.tail) { JCAnnotation a = al.head; Attribute.Compound c = annotate.enterAnnotation(a, syms.annotationType, env); - if (c == null) continue; - buf.append(c); + if (c == null) { + continue; + } + + if (annotated.containsKey(a.type.tsym)) { + if (source.allowRepeatedAnnotations()) { + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(c); + annotated.put(a.type.tsym, l); + pos.put(c, a.pos()); + } else { + log.error(a.pos(), "duplicate.annotation"); + } + } else { + annotated.put(a.type.tsym, ListBuffer.of(c)); + pos.put(c, a.pos()); + } + // Note: @Deprecated has no effect on local variables and parameters if (!c.type.isErroneous() && s.owner.kind != MTH - && types.isSameType(c.type, syms.deprecatedType)) + && types.isSameType(c.type, syms.deprecatedType)) { s.flags_field |= Flags.DEPRECATED; - if (!annotated.add(a.type.tsym)) - log.error(a.pos, "duplicate.annotation"); } - s.attributes_field = buf.toList(); + } + + s.annotations.setAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log)); } /** Queue processing of an attribute default value. */ void annotateDefaultValueLater(final JCExpression defaultValue, final Env localEnv, final MethodSymbol m) { - annotate.later(new Annotate.Annotator() { + annotate.normal(new Annotate.Annotator() { + @Override public String toString() { return "annotate " + m.owner + "." + m + " default " + defaultValue; } + + @Override public void enterAnnotation() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index f7dc3669607..b221ba5b705 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1321,7 +1321,7 @@ public class ClassReader implements Completer { else proxies.append(proxy); } - annotate.later(new AnnotationCompleter(sym, proxies.toList())); + annotate.normal(new AnnotationCompleter(sym, proxies.toList())); } } @@ -1347,7 +1347,7 @@ public class ClassReader implements Completer { void attachAnnotationDefault(final Symbol sym) { final MethodSymbol meth = (MethodSymbol)sym; // only on methods final Attribute value = readAttributeValue(); - annotate.later(new AnnotationDefaultCompleter(meth, value)); + annotate.normal(new AnnotationDefaultCompleter(meth, value)); } Type readTypeOrClassSymbol(int i) { @@ -1693,10 +1693,13 @@ public class ClassReader implements Completer { JavaFileObject previousClassFile = currentClassFile; try { currentClassFile = classFile; + Annotations annotations = sym.annotations; List newList = deproxyCompoundList(l); - sym.attributes_field = ((sym.attributes_field == null) - ? newList - : newList.prependList(sym.attributes_field)); + if (annotations.pendingCompletion()) { + annotations.setAttributes(newList); + } else { + annotations.append(newList); + } } finally { currentClassFile = previousClassFile; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index ac5b1387673..4ed076afe83 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -825,7 +825,7 @@ public class ClassWriter extends ClassFile { } public void visitClass(Attribute.Class clazz) { databuf.appendByte('c'); - databuf.appendChar(pool.put(typeSig(clazz.type))); + databuf.appendChar(pool.put(typeSig(clazz.classType))); } public void visitCompound(Attribute.Compound compound) { databuf.appendByte('@'); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java index eda91f31259..765b79190d7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java @@ -157,7 +157,7 @@ public class JNIWriter { if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0) return false; - for (Attribute.Compound a: c.attributes_field) { + for (Attribute.Compound a: c.annotations.getAttributes()) { if (a.type.tsym == syms.nativeHeaderType.tsym) return true; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java index bf1ec29529b..92e1c1790e1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, 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 @@ -177,7 +177,7 @@ public class AnnotationProxyMaker { } public void visitClass(Attribute.Class c) { - value = new MirroredTypeExceptionProxy(c.type); + value = new MirroredTypeExceptionProxy(c.classType); } public void visitArray(Attribute.Array a) { @@ -187,7 +187,7 @@ public class AnnotationProxyMaker { // Construct a proxy for a MirroredTypesException ListBuffer elems = new ListBuffer(); for (Attribute value : a.values) { - Type elem = ((Attribute.Class) value).type; + Type elem = ((Attribute.Class) value).classType; elems.append(elem); } value = new MirroredTypesExceptionProxy(elems.toList()); diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 56e5b767d63..b931053a671 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -250,6 +250,70 @@ compiler.err.duplicate.annotation=\ compiler.err.duplicate.annotation.member.value=\ duplicate annotation member value {0} in {1} +# 0: type +compiler.err.duplicate.annotation.missing.container=\ + duplicate annotation, the declaration of {0} does not have a ContainedBy annotation + +# 0: type, 1: type +compiler.err.invalid.container.no.containedby=\ + invalid contained repeatable annotation, {0} is not annotated with {1} + +# 0: type, 1: type +compiler.err.invalid.container.wrong.containedby=\ + invalid contained repeatable annotation, {0} does not match {1} + +# 0: type, 1: type +compiler.err.invalid.container.no.containerfor=\ + invalid container for repeating annotations, {0} is not annotated with {1} + +# 0: type, 1: type +compiler.err.invalid.container.wrong.containerfor=\ + invalid container for repeating annotations, {0} does not match {1} + +# 0: type +compiler.err.invalid.containedby.annotation=\ + duplicate annotation, {0} is annotated with an invalid ContainedBy annotation + +# 0: type +compiler.err.invalid.containedby.annotation.no.value=\ + duplicate annotation, {0} is not a valid ContainedBy, no value element method declared + +# 0: type, 1: number +compiler.err.invalid.containedby.annotation.multiple.values=\ + duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared + +# 0: type +compiler.err.invalid.containedby.annotation.invalid.value=\ + duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method + +# 0: type, 1: type, 2: type +compiler.err.invalid.containedby.annotation.value.return=\ + duplicate annotation, value element of containing annotation {0} should have type {2}, found {1} + +# 0: type, 1: symbol +compiler.err.invalid.containedby.annotation.elem.nondefault=\ + duplicate annotation, element {1} in containing annotation {0} does not have a default value + +# 0: symbol, 1: type, 2: symbol, 3: type +compiler.err.invalid.containedby.annotation.retention=\ + containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3} + +# 0: symbol, 1: symbol +compiler.err.invalid.containedby.annotation.not.documented=\ + containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is + +# 0: symbol, 1: symbol +compiler.err.invalid.containedby.annotation.not.inherited=\ + containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is + +# 0: symbol, 1: symbol +compiler.err.invalid.containedby.annotation.incompatible.target=\ + target of container annotation {0} is not a subset of target of repeated annotation {1} + +# 0: symbol +compiler.err.invalid.containedby.annotation.repeated.and.container.present=\ + container {0} must not be present at the same time as the element it contains + # 0: name compiler.err.duplicate.class=\ duplicate class: {0} diff --git a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java index 9ee550e5ce8..53b37fb4554 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java +++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, 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 @@ -206,9 +206,7 @@ public class CreateSymbols extends AbstractProcessor { } ClassSymbol cs = (ClassSymbol) sym; if (addLegacyAnnotation) { - cs.attributes_field = (cs.attributes_field == null) - ? List.of(proprietary) - : cs.attributes_field.prepend(proprietary); + cs.annotations.prepend(List.of(proprietary)); } writeClass(pool, cs, writer); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 6191f4b8875..f9be124079f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012, 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 @@ -740,7 +740,7 @@ public class TreeMaker implements JCTree.Factory { result = Literal(v.value); } public void visitClass(Attribute.Class clazz) { - result = ClassLiteral(clazz.type).setType(syms.classType); + result = ClassLiteral(clazz.classType).setType(syms.classType); } public void visitEnum(Attribute.Enum e) { result = QualIdent(e.value); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java index dae37c488d9..82014ca96fc 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -83,7 +83,7 @@ public class AnnotationValueImpl implements AnnotationValue { public void visitClass(Attribute.Class c) { value = TypeMaker.getType(env, - env.types.erasure(c.type)); + env.types.erasure(c.classType)); } public void visitEnum(Attribute.Enum e) { diff --git a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java index 2fd98b00717..4abbc276a58 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java +++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, 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 @@ -506,7 +506,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { List opts = new ArrayList(); opts.add("-proc:only"); opts.addAll(javac_extras); - CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, internalize(classes), null); + CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null); JavahProcessor p = new JavahProcessor(g); t.setProcessors(Collections.singleton(p)); @@ -516,14 +516,6 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { return ok; } - private List internalize(List classes) { - List l = new ArrayList(); - for (String c: classes) { - l.add(c.replace('$', '.')); - } - return l; - } - private List pathToFiles(String path) { List files = new ArrayList(); for (String f: path.split(File.pathSeparator)) { diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java new file mode 100644 index 00000000000..9d9e59c1fc4 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean BasicRepeatingAnnotations BasicRepeatingAnnos BasicNonRepeatingAnno Foo Foos Bar + * @run compile BasicRepeatingAnnotations.java + * @run main BasicRepeatingAnnotations + */ + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Foos.class) +@interface Foo {} + +@ContainerFor(Foo.class) +@Retention(RetentionPolicy.RUNTIME) +@interface Foos { + Foo[] value(); +} + +@interface Bar {} + +@Foo @Foo +@Foo +@Bar +@Foo +@Foo +@Foo +@Foo +@Foo @Foo +@Foo +class BasicRepeatingAnnos {} + +@Foo +class BasicNonRepeatingAnno {} + +public class BasicRepeatingAnnotations { + public static void main(String[] args) throws Exception { + Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + + // verify that container not present on nonrepeating + a = BasicNonRepeatingAnno.class.getAnnotation(Foos.class); + if (a != null) { + throw new RuntimeException("Container annotation present"); + } + a = BasicNonRepeatingAnno.class.getAnnotation(Foo.class); + if (a == null) { + throw new RuntimeException("Repeated annoation not directly present"); + } + } +} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java new file mode 100644 index 00000000000..1489cea562d --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean Foos Foo Bars Bar Baz Bazs CheckTargets + * @run compile CheckTargets.java + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@Target(ElementType.TYPE) +@interface Foo {} + +@ContainerFor(Foo.class) +@Target(ElementType.ANNOTATION_TYPE) +@interface Foos { + Foo[] value(); +} + +@ContainedBy(Bars.class) +@Target(ElementType.TYPE) +@interface Bar {} + +@ContainerFor(Bar.class) +@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) +@interface Bars { + Bar[] value(); +} + + +@ContainedBy(Bazs.class) +@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) +@interface Baz {} + +@ContainerFor(Baz.class) +@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) +@interface Bazs { + Baz[] value(); +} + + +public class CheckTargets {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java new file mode 100644 index 00000000000..ca2345d6b16 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean Bar BarContainer ContainerHasRepeatedContained + * @run compile ContainerHasRepeatedContained.java + */ + +import java.lang.annotation.ContainedBy; +import java.lang.annotation.ContainerFor; + +@ContainedBy(BarContainer.class) +@interface Bar {} + +@Bar +@Bar +@ContainerFor(Bar.class) +@interface BarContainer { + Bar[] value(); +} + +public class ContainerHasRepeatedContained {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java new file mode 100644 index 00000000000..ffceb9c3707 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean DelayRepeatedContainer Bar BarContainer + * @run compile DelayRepeatedContainer.java + */ + +import java.lang.annotation.*; + +public class DelayRepeatedContainer { + @Bar("apa") @Bar("banan") + String meh() { return "meh"; } +} + +@Bar("katt") +@Bar("lol") +@ContainedBy(BarContainer.class) +@interface Bar { + String value(); +} + +@ContainerFor(Bar.class) +@interface BarContainer { + Bar[] value(); +} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java new file mode 100644 index 00000000000..24c23386033 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean Foos Foo + * @run compile/fail InvalidTarget.java + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@Target(ElementType.ANNOTATION_TYPE) +@interface Foo {} + +@ContainerFor(Foo.class) +@Target(ElementType.TYPE) +@interface Foos { + Foo[] value(); +} + +public class InvalidTargets {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java new file mode 100644 index 00000000000..0a141a9e129 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail MissingContainedBy.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + + +@ContainerFor(MissingContainedBy.class) +@interface Foos { + MissingContainedBy[] value(); +} + +public @interface MissingContainedBy {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java new file mode 100644 index 00000000000..7d22aebf9b3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail MissingContainerFor.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@interface Foos { + MissingContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface MissingContainerFor {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java new file mode 100644 index 00000000000..c492258801a --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean NestedContainers BasicRepeatingAnnos BasicRepeatingAnnos2 Foo Foos FoosFoos + * @run compile NestedContainers.java + * @run main NestedContainers + */ + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Foos.class) +@interface Foo {} + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(FoosFoos.class) +@ContainerFor(Foo.class) +@interface Foos { + Foo[] value(); +} + +@ContainerFor(Foos.class) +@Retention(RetentionPolicy.RUNTIME) +@interface FoosFoos { + Foos[] value(); +} + +@Foo +@Foo +class BasicRepeatingAnnos {} + +@Foos({}) +@Foos({}) +class BasicRepeatingAnnos2 {} + +public class NestedContainers { + public static void main(String[] args) throws Exception { + Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + + // Check 2:nd level container + a = BasicRepeatingAnnos2.class.getAnnotation(FoosFoos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + } +} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java new file mode 100644 index 00000000000..bb67c91cee0 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean RepMemberAnno Bar BarContainer + * @run compile RepMemberAnno.java + */ + +import java.lang.annotation.ContainedBy; +import java.lang.annotation.ContainerFor; + +public class RepMemberAnno { + @Bar("Apa") @Bar("Banan") + public void meh() {} +} + +@ContainedBy(BarContainer.class) +@interface Bar { + String value(); +} + +@ContainerFor(Bar.class) +@interface BarContainer { + Bar[] value(); +} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java new file mode 100644 index 00000000000..bc11c69c1f0 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean RepSelfMemberAnno BarContainer BarContainerContainer + * @run compile RepSelfMemberAnno.java + */ + +import java.lang.annotation.*; + + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(BarContainer.class) +public @interface RepSelfMemberAnno { + @RepSelfMemberAnno @RepSelfMemberAnno + String meh() default "banan"; +} + + +@ContainedBy(BarContainerContainer.class) +@Retention(RetentionPolicy.RUNTIME) +@ContainerFor(RepSelfMemberAnno.class) +@interface BarContainer { + RepSelfMemberAnno[] value(); +} + +@ContainerFor(BarContainer.class) +@Retention(RetentionPolicy.RUNTIME) +@interface BarContainerContainer { + BarContainer[] value(); + String meh() default "apa"; +} + +@BarContainer(value={}) +@BarContainer(value={}) +@interface Bar {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java new file mode 100644 index 00000000000..26d98513502 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail RepeatingAndContainerPresent.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@interface Foo {} + +@interface Foos { + Foo[] value(); +} + + +@Foo +@Foo +@Foos({}) +public class RepeatingAndContainerPresent {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java new file mode 100644 index 00000000000..b0eb87d876b --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean SelfRepeatingAnnotations Foos SelfRepeatingAnno + * @run compile SelfRepeatingAnnotations.java + * @run main SelfRepeatingAnnotations + */ + +import java.lang.annotation.*; + +@ContainerFor(SelfRepeatingAnno.class) +@Retention(RetentionPolicy.RUNTIME) +@interface Foos { + SelfRepeatingAnno[] value(); +} + +@SelfRepeatingAnno +@Retention(RetentionPolicy.RUNTIME) +@SelfRepeatingAnno +@ContainedBy(Foos.class) +@interface SelfRepeatingAnno {} + +public class SelfRepeatingAnnotations { + public static void main(String[] args) throws Exception { + Annotation a = SelfRepeatingAnno.class.getAnnotation(Foos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + } +} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java new file mode 100644 index 00000000000..b18d259670f --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile SingleRepeatingAndContainer.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@interface Foo {} + +@ContainerFor(Foo.class) +@interface Foos { + Foo[] value(); +} + +@Foo +@Foos({}) +public class SingleRepeatingAndContainer {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java new file mode 100644 index 00000000000..a8a8a633d6b --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail UseWrongContainedBy.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(UseWrongContainedBy.class) +@interface Foos { + UseWrongContainedBy[] value(); +} + +@ContainedBy(Target.class) +public @interface UseWrongContainedBy {} + +@UseWrongContainedBy @UseWrongContainedBy +@interface Foo {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java new file mode 100644 index 00000000000..5067ef20625 --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail UseWrongContainerFor.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(Retention.class) +@interface Foos { + UseWrongContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface UseWrongContainerFor {} + +@UseWrongContainerFor @UseWrongContainerFor +@interface Foo {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java new file mode 100644 index 00000000000..182acf0534d --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail WrongContainedBy.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(WrongContainedBy.class) +@interface Foos { + WrongContainedBy[] value(); +} + +@ContainedBy(Target.class) +public @interface WrongContainedBy {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java new file mode 100644 index 00000000000..c87bdbcc40b --- /dev/null +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, 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 Smoke test for repeating annotations + * @compile/fail WrongContainerFor.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(Retention.class) +@interface Foos { + WrongContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface WrongContainerFor {} diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index 0262f05b424..9b569fcf309 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -5,6 +5,9 @@ compiler.err.cant.apply.symbol compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.select.static.class.from.param.type compiler.err.illegal.char.for.encoding +compiler.err.invalid.containedby.annotation # should not happen +compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen +compiler.err.invalid.containedby.annotation.multiple.values # can't happen compiler.err.io.exception # (javah.JavahTask?) compiler.err.limit.code # Code compiler.err.limit.code.too.large.for.try.stmt # Gen diff --git a/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java b/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java new file mode 100644 index 00000000000..a5077c7b825 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.not.documented + +import java.lang.annotation.*; + +@Documented +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +class ContainedByDocumentedMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java b/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java new file mode 100644 index 00000000000..d7723bad61c --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.not.inherited + +import java.lang.annotation.*; + +@Inherited +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +class ContainedByInheritedMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java b/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java new file mode 100644 index 00000000000..8cb612808f9 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.no.value + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos {} + +@Anno +@Anno +class ContainedByNoValue { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java b/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java new file mode 100644 index 00000000000..d64b6b31d7c --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.elem.nondefault + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); String foo(); } + +@Anno +@Anno +class ContainedByNonDefault { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java b/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java new file mode 100644 index 00000000000..22680f5b644 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.retention + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +class ContainedByRetentionMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java b/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java new file mode 100644 index 00000000000..3fcd4fb3f5d --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.incompatible.target + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@Target(ElementType.METHOD) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +class ContainedByTargetMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java b/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java new file mode 100644 index 00000000000..9b963bd3f6e --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.value.return + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { String value(); } + +@Anno +@Anno +class ContainedByWrongValueType { } diff --git a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java b/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java index 48a43251e4c..09935e550f4 100644 --- a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java +++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,8 @@ */ // key: compiler.err.duplicate.annotation +// key: compiler.warn.source.no.bootclasspath +// options: -source 7 @interface Anno { } diff --git a/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java b/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java new file mode 100644 index 00000000000..8fcb54949f6 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.duplicate.annotation.missing.container + +@interface Anno { } + +@Anno +@Anno +class DuplicateAnnotationJava8 { } diff --git a/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java new file mode 100644 index 00000000000..07a9bfddefb --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +@Annos(@Anno) +class RepeatingAnnotationAndContainer { } diff --git a/langtools/test/tools/javac/diags/examples/WrongContainedBy.java b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java new file mode 100644 index 00000000000..6914c4bd64e --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.container.no.containerfor +// key: compiler.err.invalid.container.wrong.containedby + +import java.lang.annotation.*; + +@ContainerFor(WrongContainedBy.class) +@interface Foos { + WrongContainedBy[] value(); +} + +@ContainedBy(Target.class) +public @interface WrongContainedBy {} diff --git a/langtools/test/tools/javac/diags/examples/WrongContainerFor.java b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java new file mode 100644 index 00000000000..e439b780fbe --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, 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. + */ + +// key: compiler.err.invalid.container.wrong.containerfor +// key: compiler.err.invalid.container.no.containedby + +import java.lang.annotation.*; + +@ContainerFor(Retention.class) +@interface Foos { + WrongContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface WrongContainerFor {} diff --git a/langtools/test/tools/javah/T7185778.java b/langtools/test/tools/javah/T7185778.java new file mode 100644 index 00000000000..0f45f2b33a1 --- /dev/null +++ b/langtools/test/tools/javah/T7185778.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012, 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 7185778 + * @summary javah error "Not a valid class name" on class names with dollar signs + * The first two tests are on an inner class name whose name does not contain $. + * The second two tests are on an inner class name whose name does contain $. + * The last test is on an outer class whose name contains $. + * @run main T7185778 T7185778$inner + * @run main T7185778 T7185778.inner + * @run main T7185778 T7185778$inner$ + * @run main T7185778 T7185778.inner$ + * @run main T7185778 xx$yy + */ + +public class T7185778 { + class inner { + native byte[] xxxxx(String name); + } + class inner$ { + native byte[] xxxxx(String name); + } + + static public void main(String[] args) { + int rc = com.sun.tools.javah.Main.run(args, null); + if ( rc != 0) { + throw new Error("javah returned non zero: " + rc); + } + } +} + +class xx$yy { + native byte[] xxxxx(String name); +}