diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp index 120dd1a7dfa..4f694b1775a 100644 --- a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2013, Red Hat Inc. - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. * All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -150,8 +150,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, if (index->is_register()) { // apply the shift and accumulate the displacement if (shift > 0) { - LIR_Opr tmp = new_pointer_register(); - __ shift_left(index, shift, tmp); + // Use long register to avoid overflow when shifting large index values left. + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + __ shift_left(tmp, shift, tmp); index = tmp; } if (disp != 0) { diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index f1160792a1e..b2e6491cd49 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -156,8 +156,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, if (index->is_register()) { // apply the shift and accumulate the displacement if (shift > 0) { - LIR_Opr tmp = new_pointer_register(); - __ shift_left(index, shift, tmp); + // Use long register to avoid overflow when shifting large index values left. + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + __ shift_left(tmp, shift, tmp); index = tmp; } if (disp != 0) { diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index fe3474ef440..ab9547c79f7 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -1235,14 +1235,13 @@ oop java_lang_Throwable::message(Handle throwable) { } -// Return Symbol for detailed_message or NULL -Symbol* java_lang_Throwable::detail_message(oop throwable) { - PRESERVE_EXCEPTION_MARK; // Keep original exception - oop detailed_message = java_lang_Throwable::message(throwable); - if (detailed_message != NULL) { - return java_lang_String::as_symbol(detailed_message, THREAD); +const char* java_lang_Throwable::message_as_utf8(oop throwable) { + oop msg = java_lang_Throwable::message(throwable); + const char* msg_utf8 = NULL; + if (msg != NULL) { + msg_utf8 = java_lang_String::as_utf8_string(msg); } - return NULL; + return msg_utf8; } void java_lang_Throwable::set_message(oop throwable, oop value) { diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 75950200f47..10f6a77d804 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -523,12 +523,12 @@ class java_lang_Throwable: AllStatic { static void set_backtrace(oop throwable, oop value); // Needed by JVMTI to filter out this internal field. static int get_backtrace_offset() { return backtrace_offset;} - static int get_detailMessage_offset() { return detailMessage_offset;} // Message + static int get_detailMessage_offset() { return detailMessage_offset;} static oop message(oop throwable); static oop message(Handle throwable); + static const char* message_as_utf8(oop throwable); static void set_message(oop throwable, oop value); - static Symbol* detail_message(oop throwable); static void print_stack_element(outputStream *st, Handle mirror, int method, int version, int bci, int cpref); static void print_stack_element(outputStream *st, methodHandle method, int bci); diff --git a/hotspot/src/share/vm/classfile/resolutionErrors.cpp b/hotspot/src/share/vm/classfile/resolutionErrors.cpp index cef42b1888d..347670c0393 100644 --- a/hotspot/src/share/vm/classfile/resolutionErrors.cpp +++ b/hotspot/src/share/vm/classfile/resolutionErrors.cpp @@ -33,7 +33,7 @@ // add new entry to the table void ResolutionErrorTable::add_entry(int index, unsigned int hash, constantPoolHandle pool, int cp_index, - Symbol* error, Symbol* message) + Symbol* error, const char* message) { assert_locked_or_safepoint(SystemDictionary_lock); assert(!pool.is_null() && error != NULL, "adding NULL obj"); @@ -64,16 +64,14 @@ void ResolutionErrorEntry::set_error(Symbol* e) { _error->increment_refcount(); } -void ResolutionErrorEntry::set_message(Symbol* c) { - assert(c != NULL, "must set a value"); - _message = c; - _message->increment_refcount(); +void ResolutionErrorEntry::set_message(const char* c) { + _message = c != NULL ? os::strdup(c) : NULL; } // create new error entry ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error, - Symbol* message) + const char* message) { ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable::new_entry(hash, pool); entry->set_cp_index(cp_index); @@ -87,7 +85,9 @@ void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) { // decrement error refcount assert(entry->error() != NULL, "error should be set"); entry->error()->decrement_refcount(); - entry->message()->decrement_refcount(); + if (entry->message() != NULL) { + FREE_C_HEAP_ARRAY(char, entry->message(), mtInternal); + } Hashtable::free_entry(entry); } diff --git a/hotspot/src/share/vm/classfile/resolutionErrors.hpp b/hotspot/src/share/vm/classfile/resolutionErrors.hpp index c9e76827cb4..bb7a9d069c3 100644 --- a/hotspot/src/share/vm/classfile/resolutionErrors.hpp +++ b/hotspot/src/share/vm/classfile/resolutionErrors.hpp @@ -39,7 +39,7 @@ class ResolutionErrorTable : public Hashtable { ResolutionErrorTable(int table_size); ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, - Symbol* error, Symbol* message); + Symbol* error, const char* message); void free_entry(ResolutionErrorEntry *entry); ResolutionErrorEntry* bucket(int i) { @@ -56,7 +56,7 @@ class ResolutionErrorTable : public Hashtable { } void add_entry(int index, unsigned int hash, - constantPoolHandle pool, int which, Symbol* error, Symbol* message); + constantPoolHandle pool, int cp_index, Symbol* error, const char* error_msg); // find error given the constant pool and constant pool index @@ -80,7 +80,7 @@ class ResolutionErrorEntry : public HashtableEntry { private: int _cp_index; Symbol* _error; - Symbol* _message; + const char* _message; public: ConstantPool* pool() const { return literal(); } @@ -91,8 +91,9 @@ class ResolutionErrorEntry : public HashtableEntry { Symbol* error() const { return _error; } void set_error(Symbol* e); - Symbol* message() const { return _message; } - void set_message(Symbol* c); + const char* message() const { return _message; } + // The incoming message is copied to the C-Heap. + void set_message(const char* c); ResolutionErrorEntry* next() const { return (ResolutionErrorEntry*)HashtableEntry::next(); diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 9501c9e45f1..e9b2f9aa1e3 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -2280,7 +2280,7 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name, // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed. void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, - Symbol* error, Symbol* message) { + Symbol* error, const char* message) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { @@ -2296,7 +2296,7 @@ void SystemDictionary::delete_resolution_error(ConstantPool* pool) { // Lookup resolution error table. Returns error if found, otherwise NULL. Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which, - Symbol** message) { + const char** message) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index 365ece01612..4254f03bcc0 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -549,10 +549,10 @@ class SystemDictionary : AllStatic { // Record the error when the first attempt to resolve a reference from a constant // pool entry to a class fails. static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error, - Symbol* message); + const char* message); static void delete_resolution_error(ConstantPool* pool); static Symbol* find_resolution_error(constantPoolHandle pool, int which, - Symbol** message); + const char** message); protected: diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 5d2845383ca..cad9d290084 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -451,11 +451,11 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea // tracing if (TraceExceptions) { ResourceMark rm(thread); - Symbol* message = java_lang_Throwable::detail_message(h_exception()); + const char* detail_message = java_lang_Throwable::message_as_utf8(h_exception()); ttyLocker ttyl; // Lock after getting the detail message - if (message != NULL) { + if (detail_message != NULL) { tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")", - h_exception->print_value_string(), message->as_C_string(), + h_exception->print_value_string(), detail_message, (address)h_exception()); } else { tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 921d30fbad9..bc2a7816bf9 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -569,13 +569,16 @@ bool ConstantPool::resolve_class_constants(TRAPS) { return true; } -Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) { +const char* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) { + // Note: caller needs ResourceMark + // Dig out the detailed message to reuse if possible - Symbol* message = java_lang_Throwable::detail_message(pending_exception); - if (message != NULL) { - return message; + const char* msg = java_lang_Throwable::message_as_utf8(pending_exception); + if (msg != NULL) { + return msg; } + Symbol* message = NULL; // Return specific message for the tag switch (tag.value()) { case JVM_CONSTANT_UnresolvedClass: @@ -594,16 +597,16 @@ Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, ShouldNotReachHere(); } - return message; + return message != NULL ? message->as_C_string() : NULL; } void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) { - Symbol* message = NULL; + ResourceMark rm(THREAD); + const char* message = NULL; Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message); assert(error != NULL && message != NULL, "checking"); CLEAR_PENDING_EXCEPTION; - ResourceMark rm; - THROW_MSG(error, message->as_C_string()); + THROW_MSG(error, message); } // If resolution for Class, MethodHandle or MethodType fails, save the exception @@ -622,7 +625,9 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int whi // and OutOfMemoryError, etc, or if the thread was hit by stop() // Needs clarification to section 5.4.3 of the VM spec (see 6308271) } else if (this_oop->tag_at(which).value() != error_tag) { - Symbol* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION); + ResourceMark rm(THREAD); + + const char* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION); SystemDictionary::add_resolution_error(this_oop, which, error, message); this_oop->tag_at_put(which, error_tag); } else { diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index ec111df04eb..635bf6d1bc3 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -830,7 +830,7 @@ class ConstantPool : public Metadata { // Exception handling static void throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS); - static Symbol* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception); + static const char* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception); static void save_and_throw_exception(constantPoolHandle this_oop, int which, constantTag tag, TRAPS); public: diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java index a04b440525a..66c3ea91a73 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java @@ -32,6 +32,8 @@ import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.List; import java.util.jar.JarOutputStream; import java.util.jar.Pack200; import java.util.zip.CRC32; @@ -77,8 +79,13 @@ class NativeUnpack { private int _estFileLimit; // ditto private int _prevPercent = -1; // for monotonicity - private final CRC32 _crc32 = new CRC32(); - private byte[] _buf = new byte[1<<14]; + private final CRC32 _crc32 = new CRC32(); + private static final int MAX_BUFFER_SIZE = 1 << 20; // 1 MB byte[] + private byte[] _buf = new byte[1 << 14]; // 16 KB byte[] initially + private List _extra_buf = new LinkedList<>(); // extra buffers + // for large files + private byte[] _current_buf; // buffer being filled + private int _current_buf_pos; // position to fill in more data private UnpackerImpl _p200; private PropMap _props; @@ -195,41 +202,44 @@ void run(InputStream inRaw, JarOutputStream jstream, updateProgress(); // reset progress bar for (;;) { // Read the packed bits. - long counts = start(presetInput, 0); - _byteCount = _estByteLimit = 0; // reset partial scan counts - ++_segCount; // just finished scanning a whole segment... - int nextSeg = (int)( counts >>> 32 ); - int nextFile = (int)( counts >>> 0 ); - - // Estimate eventual total number of segments and files. - _estSegLimit = _segCount + nextSeg; - double filesAfterThisSeg = _fileCount + nextFile; - _estFileLimit = (int)( (filesAfterThisSeg * - _estSegLimit) / _segCount ); - - // Write the files. - int[] intParts = { 0,0, 0, 0 }; - // intParts = {size.hi/lo, mod, defl} - Object[] parts = { intParts, null, null, null }; - // parts = { {intParts}, name, data0/1 } - while (getNextFile(parts)) { - //BandStructure.printArrayTo(System.out, intParts, 0, parts.length); - String name = (String) parts[1]; - long size = ( (long)intParts[0] << 32) - + (((long)intParts[1] << 32) >>> 32); - - long mtime = (modtime != Constants.NO_MODTIME ) ? - modtime : intParts[2] ; - boolean deflateHint = (intParts[3] != 0); - ByteBuffer data0 = (ByteBuffer) parts[2]; - ByteBuffer data1 = (ByteBuffer) parts[3]; - writeEntry(jstream, name, mtime, size, deflateHint, - data0, data1); - ++_fileCount; - updateProgress(); + long counts = start(presetInput, 0), consumed; + try { + _byteCount = _estByteLimit = 0; // reset partial scan counts + ++_segCount; // just finished scanning a whole segment... + int nextSeg = (int) (counts >>> 32); + int nextFile = (int) (counts >>> 0); + + // Estimate eventual total number of segments and files. + _estSegLimit = _segCount + nextSeg; + double filesAfterThisSeg = _fileCount + nextFile; + _estFileLimit = (int) ((filesAfterThisSeg * + _estSegLimit) / _segCount); + + // Write the files. + int[] intParts = {0, 0, 0, 0}; + // intParts = {size.hi/lo, mod, defl} + Object[] parts = {intParts, null, null, null}; + // parts = { {intParts}, name, data0/1 } + while (getNextFile(parts)) { + //BandStructure.printArrayTo(System.out, intParts, 0, parts.length); + String name = (String) parts[1]; + long size = ((long) intParts[0] << 32) + + (((long) intParts[1] << 32) >>> 32); + + long mtime = (modtime != Constants.NO_MODTIME) ? + modtime : intParts[2]; + boolean deflateHint = (intParts[3] != 0); + ByteBuffer data0 = (ByteBuffer) parts[2]; + ByteBuffer data1 = (ByteBuffer) parts[3]; + writeEntry(jstream, name, mtime, size, deflateHint, + data0, data1); + ++_fileCount; + updateProgress(); + } + presetInput = getUnusedInput(); + } finally { + consumed = finish(); } - presetInput = getUnusedInput(); - long consumed = finish(); if (_verbose > 0) Utils.log.info("bytes consumed = "+consumed); if (presetInput == null && @@ -256,76 +266,145 @@ void run(File inFile, JarOutputStream jstream) throws IOException { // Note: caller is responsible to finish with jstream. } - private void writeEntry(JarOutputStream j, String name, - long mtime, long lsize, boolean deflateHint, - ByteBuffer data0, ByteBuffer data1) throws IOException { - int size = (int)lsize; - if (size != lsize) - throw new IOException("file too large: "+lsize); - - CRC32 crc32 = _crc32; - - if (_verbose > 1) - Utils.log.fine("Writing entry: "+name+" size="+size - +(deflateHint?" deflated":"")); - - if (_buf.length < size) { - int newSize = size; - while (newSize < _buf.length) { - newSize <<= 1; - if (newSize <= 0) { - newSize = size; - break; - } - } - _buf = new byte[newSize]; + private void writeEntry(JarOutputStream j, String name, long mtime, + long lsize, boolean deflateHint, ByteBuffer data0, + ByteBuffer data1) throws IOException { + if (lsize < 0 || lsize > Integer.MAX_VALUE) { + throw new IOException("file too large: " + lsize); } - assert(_buf.length >= size); + int size = (int) lsize; - int fillp = 0; - if (data0 != null) { - int size0 = data0.capacity(); - data0.get(_buf, fillp, size0); - fillp += size0; - } - if (data1 != null) { - int size1 = data1.capacity(); - data1.get(_buf, fillp, size1); - fillp += size1; - } - while (fillp < size) { - // Fill in rest of data from the stream itself. - int nr = in.read(_buf, fillp, size - fillp); - if (nr <= 0) throw new IOException("EOF at end of archive"); - fillp += nr; + if (_verbose > 1) { + Utils.log.fine("Writing entry: " + name + " size=" + size + + (deflateHint ? " deflated" : "")); } ZipEntry z = new ZipEntry(name); z.setTime(mtime * 1000); - + z.setSize(size); if (size == 0) { z.setMethod(ZipOutputStream.STORED); - z.setSize(0); + z.setCompressedSize(size); z.setCrc(0); - z.setCompressedSize(0); + j.putNextEntry(z); } else if (!deflateHint) { z.setMethod(ZipOutputStream.STORED); - z.setSize(size); z.setCompressedSize(size); - crc32.reset(); - crc32.update(_buf, 0, size); - z.setCrc(crc32.getValue()); + writeEntryData(j, z, data0, data1, size, true); } else { z.setMethod(Deflater.DEFLATED); - z.setSize(size); + writeEntryData(j, z, data0, data1, size, false); } + j.closeEntry(); - j.putNextEntry(z); + if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); + } - if (size > 0) - j.write(_buf, 0, size); + private void writeEntryData(JarOutputStream j, ZipEntry z, ByteBuffer data0, + ByteBuffer data1, int size, boolean computeCrc32) + throws IOException { + prepareReadBuffers(size); + try { + int inBytes = size; + inBytes -= readDataByteBuffer(data0); + inBytes -= readDataByteBuffer(data1); + inBytes -= readDataInputStream(inBytes); + if (inBytes != 0L) { + throw new IOException("invalid size: " + size); + } + if (computeCrc32) { + _crc32.reset(); + processReadData((byte[] buff, int offset, int len) -> { + _crc32.update(buff, offset, len); + }); + z.setCrc(_crc32.getValue()); + } + j.putNextEntry(z); + processReadData((byte[] buff, int offset, int len) -> { + j.write(buff, offset, len); + }); + } finally { + resetReadBuffers(); + } + } - j.closeEntry(); - if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); + private void prepareReadBuffers(int size) { + if (_buf.length < size && _buf.length < MAX_BUFFER_SIZE) { + // Grow the regular buffer to accomodate lsize up to a limit. + long newIdealSize = _buf.length; + while (newIdealSize < size && newIdealSize < MAX_BUFFER_SIZE) { + // Never overflows: size is [0, 0x7FFFFFFF]. + newIdealSize <<= 1; + } + int newSize = (int) Long.min(newIdealSize, MAX_BUFFER_SIZE); + _buf = new byte[newSize]; + } + resetReadBuffers(); + } + + private void resetReadBuffers() { + _extra_buf.clear(); + _current_buf = _buf; + _current_buf_pos = 0; + } + + private int readDataByteBuffer(ByteBuffer data) throws IOException { + if (data == null) { + return 0; + } + return readData(data.remaining(), + (byte[] buff, int offset, int len) -> { + data.get(buff, offset, len); + return len; + }); + } + + private int readDataInputStream(int inBytes) throws IOException { + return readData(inBytes, (byte[] buff, int offset, int len) -> { + return in.read(buff, offset, len); + }); + } + + private static interface ReadDataCB { + public int read(byte[] buff, int offset, int len) throws IOException; + } + + private int readData(int bytesToRead, ReadDataCB readDataCb) + throws IOException { + int bytesRemaining = bytesToRead; + while (bytesRemaining > 0) { + if (_current_buf_pos == _current_buf.length) { + byte[] newBuff = new byte[Integer.min(bytesRemaining, + MAX_BUFFER_SIZE)]; + _extra_buf.add(newBuff); + _current_buf = newBuff; + _current_buf_pos = 0; + } + int current_buffer_space = _current_buf.length - _current_buf_pos; + int nextRead = Integer.min(current_buffer_space, bytesRemaining); + int bytesRead = readDataCb.read(_current_buf, _current_buf_pos, + nextRead); + if (bytesRead <= 0) { + throw new IOException("EOF at end of archive"); + } + _current_buf_pos += bytesRead; + bytesRemaining -= bytesRead; + } + return bytesToRead - bytesRemaining; + } + + private static interface ProcessDataCB { + public void apply(byte[] buff, int offset, int len) throws IOException; + } + + private void processReadData(ProcessDataCB processDataCB) + throws IOException { + processDataCB.apply(_buf, 0, _buf == _current_buf ? _current_buf_pos : + _buf.length); + for (byte[] buff : _extra_buf) { + // Extra buffers are allocated of a size such that they are always + // full, including the last one. + processDataCB.apply(buff, 0, buff.length); + }; } } diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java index 4cb407e2508..7c52eafe6c2 100644 --- a/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java +++ b/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java @@ -247,14 +247,6 @@ public AlgorithmParameterSpec getParams() { return keyParams; } - // return a string representation of this key for debugging - @Override - public String toString() { - return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength() - + " bits" + "\n params: " + keyParams + "\n modulus: " + n - + "\n private exponent: " + d; - } - /** * Parse the key. Called by PKCS8Key. */ diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java index b443caf91fd..599d28200ad 100644 --- a/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java +++ b/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java @@ -123,14 +123,6 @@ public AlgorithmParameterSpec getParams() { return keyParams; } - // return a string representation of this key for debugging - @Override - public String toString() { - return "Sun " + getAlgorithm() + " private key, " + n.bitLength() - + " bits" + "\n params: " + keyParams + "\n modulus: " + n - + "\n private exponent: " + d; - } - /** * Restores the state of this object from the stream. *

diff --git a/jdk/src/windows/classes/sun/security/mscapi/CKey.java b/jdk/src/windows/classes/sun/security/mscapi/CKey.java index 84d3e82cec1..2a2e9a9c104 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/CKey.java +++ b/jdk/src/windows/classes/sun/security/mscapi/CKey.java @@ -76,10 +76,14 @@ protected void finalize() throws Throwable { protected final String algorithm; - protected CKey(String algorithm, NativeHandles handles, int keyLength) { + private final boolean isPublic; + + protected CKey(String algorithm, NativeHandles handles, int keyLength, + boolean isPublic) { this.algorithm = algorithm; this.handles = handles; this.keyLength = keyLength; + this.isPublic = isPublic; } // Native method to cleanup the key handle. @@ -102,6 +106,18 @@ public String getAlgorithm() { return algorithm; } + public String toString() { + String typeStr; + if (handles.hCryptKey != 0) { + typeStr = getKeyType(handles.hCryptKey) + ", container=" + + getContainerName(handles.hCryptProv); + } else { + typeStr = "CNG"; + } + return algorithm + " " + (isPublic ? "PublicKey" : "PrivateKey") + + " [size=" + keyLength + " bits, type=" + typeStr + "]"; + } + protected native static String getContainerName(long hCryptProv); protected native static String getKeyType(long hCryptKey); diff --git a/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java b/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java index cea2f93ed5f..8effc135155 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java +++ b/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java @@ -41,7 +41,7 @@ class CPrivateKey extends CKey implements PrivateKey { private static final long serialVersionUID = 8113152807912338063L; private CPrivateKey(String alg, NativeHandles handles, int keyLength) { - super(alg, handles, keyLength); + super(alg, handles, keyLength, false); } // Called by native code inside security.cpp @@ -64,16 +64,6 @@ public byte[] getEncoded() { return null; } - public String toString() { - if (handles.hCryptKey != 0) { - return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" + - getKeyType(handles.hCryptKey) + ", container=" + - getContainerName(handles.hCryptProv) + "]"; - } else { - return algorithm + "PrivateKey [size=" + keyLength + " bits, type=CNG]"; - } - } - // This class is not serializable private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { diff --git a/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java b/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java index 93c11c8d561..9ca0955bc53 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java +++ b/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java @@ -110,9 +110,8 @@ public ECParameterSpec getParams() { } public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(algorithm).append("PublicKey [size=").append(keyLength) - .append("]\n ECPoint: ").append(getW()) + StringBuffer sb = new StringBuffer(super.toString()); + sb.append("\n ECPoint: ").append(getW()) .append("\n params: ").append(getParams()); return sb.toString(); } @@ -129,16 +128,8 @@ public static class CRSAPublicKey extends CPublicKey implements RSAPublicKey { } public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(algorithm).append("PublicKey [size=").append(keyLength) - .append(" bits, type="); - if (handles.hCryptKey != 0) { - sb.append(getKeyType(handles.hCryptKey)) - .append(", container=").append(getContainerName(handles.hCryptProv)); - } else { - sb.append("CNG"); - } - sb.append("]\n modulus: ").append(getModulus()) + StringBuffer sb = new StringBuffer(super.toString()); + sb.append("\n modulus: ").append(getModulus()) .append("\n public exponent: ").append(getPublicExponent()); return sb.toString(); } @@ -209,7 +200,7 @@ public static CPublicKey of( protected CPublicKey( String alg, NativeHandles handles, int keyLength) { - super(alg, handles, keyLength); + super(alg, handles, keyLength, true); } @Override