1 /* 2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/classFileStream.hpp" 27 #include "classfile/vmSymbols.hpp" 28 29 void ClassFileStream::truncated_file_error(TRAPS) { 30 THROW_MSG(vmSymbols::java_lang_ClassFormatError(), "Truncated class file"); 31 } 32 33 ClassFileStream::ClassFileStream(u1* buffer, int length, const char* source) { 34 _buffer_start = buffer; 35 _buffer_end = buffer + length; 36 _current = buffer; 37 _source = source; 38 _need_verify = false; 39 } 40 41 const u1* ClassFileStream::clone_buffer() const { 42 u1* const new_buffer_start = NEW_RESOURCE_ARRAY(u1, length()); 43 memcpy(new_buffer_start, _buffer_start, length()); 44 return new_buffer_start; 45 } 46 47 const char* const ClassFileStream::clone_source() const { 48 const char* const src = source(); 49 char* source_copy = NULL; 50 if (src != NULL) { 51 size_t source_len = strlen(src); 52 source_copy = NEW_RESOURCE_ARRAY(char, source_len + 1); 53 strncpy(source_copy, src, source_len + 1); 54 } 55 return source_copy; 56 } 57 58 // Caller responsible for ResourceMark 59 // clone stream with a rewound position 60 const ClassFileStream* ClassFileStream::clone() const { 61 const u1* const new_buffer_start = clone_buffer(); 62 return new ClassFileStream(const_cast<u1*>(new_buffer_start), 63 length(), 64 clone_source()/*, 65 need_verify()*/); 66 } 67 68 u1 ClassFileStream::get_u1(TRAPS) { 69 if (_need_verify) { 70 guarantee_more(1, CHECK_0); 71 } else { 72 assert(1 <= _buffer_end - _current, "buffer overflow"); 73 } 74 return *_current++; 75 } 76 77 u2 ClassFileStream::get_u2(TRAPS) { 78 if (_need_verify) { 79 guarantee_more(2, CHECK_0); 80 } else { 81 assert(2 <= _buffer_end - _current, "buffer overflow"); 82 } 83 u1* tmp = _current; 84 _current += 2; 85 return Bytes::get_Java_u2(tmp); 86 } 87 88 u4 ClassFileStream::get_u4(TRAPS) { 89 if (_need_verify) { 90 guarantee_more(4, CHECK_0); 91 } else { 92 assert(4 <= _buffer_end - _current, "buffer overflow"); 93 } 94 u1* tmp = _current; 95 _current += 4; 96 return Bytes::get_Java_u4(tmp); 97 } 98 99 u8 ClassFileStream::get_u8(TRAPS) { 100 if (_need_verify) { 101 guarantee_more(8, CHECK_0); 102 } else { 103 assert(8 <= _buffer_end - _current, "buffer overflow"); 104 } 105 u1* tmp = _current; 106 _current += 8; 107 return Bytes::get_Java_u8(tmp); 108 } 109 110 void ClassFileStream::skip_u1(int length, TRAPS) { 111 if (_need_verify) { 112 guarantee_more(length, CHECK); 113 } 114 _current += length; 115 } 116 117 void ClassFileStream::skip_u2(int length, TRAPS) { 118 if (_need_verify) { 119 guarantee_more(length * 2, CHECK); 120 } 121 _current += length * 2; 122 } 123 124 void ClassFileStream::skip_u4(int length, TRAPS) { 125 if (_need_verify) { 126 guarantee_more(length * 4, CHECK); 127 } 128 _current += length * 4; 129 }