Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Gruetzmacher
asm
Commits
d209ecc3
Commit
d209ecc3
authored
Jun 13, 2018
by
Eric Bruneton
Browse files
Merge branch 'retronymm/asm-unfork/error-messages'
parents
416c88f6
94a06049
Changes
7
Hide whitespace changes
Inline
Side-by-side
asm/src/main/java/org/objectweb/asm/ByteVector.java
View file @
d209ecc3
...
...
@@ -242,7 +242,7 @@ public class ByteVector {
public
ByteVector
putUTF8
(
final
String
stringValue
)
{
int
charLength
=
stringValue
.
length
();
if
(
charLength
>
65535
)
{
throw
new
IllegalArgumentException
();
throw
new
IllegalArgumentException
(
"UTF8 string too large"
);
}
int
currentLength
=
length
;
if
(
currentLength
+
2
+
charLength
>
data
.
length
)
{
...
...
@@ -294,7 +294,7 @@ public class ByteVector {
}
}
if
(
byteLength
>
maxByteLength
)
{
throw
new
IllegalArgumentException
();
throw
new
IllegalArgumentException
(
"UTF8 string too large"
);
}
// Compute where 'byteLength' must be stored in 'data', and store it at this location.
int
byteLengthOffset
=
length
-
offset
-
2
;
...
...
asm/src/main/java/org/objectweb/asm/ClassTooLargeException.java
0 → 100644
View file @
d209ecc3
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package
org.objectweb.asm
;
/**
* Exception thrown when the constant pool of a class produced by a {@link ClassWriter} is too
* large.
*
* @author Jason Zaugg
*/
public
final
class
ClassTooLargeException
extends
IndexOutOfBoundsException
{
private
final
String
className
;
private
final
int
constantPoolCount
;
/**
* Constructs a new {@link ClassTooLargeException}.
*
* @param className the internal name of the class.
* @param constantPoolCount the number of constant pool items of the class.
*/
public
ClassTooLargeException
(
final
String
className
,
final
int
constantPoolCount
)
{
super
(
"Class too large: "
+
className
);
this
.
className
=
className
;
this
.
constantPoolCount
=
constantPoolCount
;
}
/** @return the internal name of the class. */
public
String
getClassName
()
{
return
className
;
}
/** @return the number of constant pool items of the class. */
public
int
getConstantPoolCount
()
{
return
constantPoolCount
;
}
}
asm/src/main/java/org/objectweb/asm/ClassWriter.java
View file @
d209ecc3
...
...
@@ -436,8 +436,10 @@ public class ClassWriter extends ClassVisitor {
* Returns the content of the class file that was built by this ClassWriter.
*
* @return the binary content of the JVMS ClassFile structure that was built by this ClassWriter.
* @throws ClassTooLargeException if the constant pool of the class is too large.
* @throws MethodTooLargeException if the Code attribute of a method is too large.
*/
public
byte
[]
toByteArray
()
{
public
byte
[]
toByteArray
()
throws
ClassTooLargeException
,
MethodTooLargeException
{
// First step: compute the size in bytes of the ClassFile structure.
// The magic field uses 4 bytes, 10 mandatory fields (minor_version, major_version,
// constant_pool_count, access_flags, this_class, super_class, interfaces_count, fields_count,
...
...
@@ -543,8 +545,9 @@ public class ClassWriter extends ClassVisitor {
// IMPORTANT: this must be the last part of the ClassFile size computation, because the previous
// statements can add attribute names to the constant pool, thereby changing its size!
size
+=
symbolTable
.
getConstantPoolLength
();
if
(
symbolTable
.
getConstantPoolCount
()
>
0xFFFF
)
{
throw
new
IndexOutOfBoundsException
(
"Class file too large!"
);
int
constantPoolCount
=
symbolTable
.
getConstantPoolCount
();
if
(
constantPoolCount
>
0xFFFF
)
{
throw
new
ClassTooLargeException
(
symbolTable
.
getClassName
(),
constantPoolCount
);
}
// Second step: allocate a ByteVector of the correct size (in order to avoid any array copy in
...
...
asm/src/main/java/org/objectweb/asm/MethodTooLargeException.java
0 → 100644
View file @
d209ecc3
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package
org.objectweb.asm
;
/**
* Exception thrown when the Code attribute of a method produced by a {@link ClassWriter} is too
* large.
*
* @author Jason Zaugg
*/
public
final
class
MethodTooLargeException
extends
IndexOutOfBoundsException
{
private
final
String
className
;
private
final
String
methodName
;
private
final
String
descriptor
;
private
final
int
codeSize
;
/**
* Constructs a new {@link MethodTooLargeException}.
*
* @param className the internal name of the owner class.
* @param methodName the name of the method.
* @param descriptor the descriptor of the method.
* @param codeSize the size of the method's Code attribute, in bytes.
*/
public
MethodTooLargeException
(
final
String
className
,
final
String
methodName
,
final
String
descriptor
,
final
int
codeSize
)
{
super
(
"Method too large: "
+
className
+
"."
+
methodName
+
" "
+
descriptor
);
this
.
className
=
className
;
this
.
methodName
=
methodName
;
this
.
descriptor
=
descriptor
;
this
.
codeSize
=
codeSize
;
}
/** @return the internal name of the owner class. */
public
String
getClassName
()
{
return
className
;
}
/** @return the name of the method. */
public
String
getMethodName
()
{
return
methodName
;
}
/** @return the descriptor of the method. */
public
String
getDescriptor
()
{
return
descriptor
;
}
/** @return the size of the method's Code attribute, in bytes. */
public
int
getCodeSize
()
{
return
codeSize
;
}
}
asm/src/main/java/org/objectweb/asm/MethodWriter.java
View file @
d209ecc3
...
...
@@ -299,6 +299,9 @@ final class MethodWriter extends MethodVisitor {
/** The name_index field of the method_info JVMS structure. */
private
final
int
nameIndex
;
/** The name of this method. */
private
final
String
name
;
/** The descriptor_index field of the method_info JVMS structure. */
private
final
int
descriptorIndex
;
...
...
@@ -592,6 +595,7 @@ final class MethodWriter extends MethodVisitor {
this
.
symbolTable
=
symbolTable
;
this
.
accessFlags
=
"<init>"
.
equals
(
name
)
?
access
|
Constants
.
ACC_CONSTRUCTOR
:
access
;
this
.
nameIndex
=
symbolTable
.
addConstantUtf8
(
name
);
this
.
name
=
name
;
this
.
descriptorIndex
=
symbolTable
.
addConstantUtf8
(
descriptor
);
this
.
descriptor
=
descriptor
;
this
.
signatureIndex
=
signature
==
null
?
0
:
symbolTable
.
addConstantUtf8
(
signature
);
...
...
@@ -2058,7 +2062,8 @@ final class MethodWriter extends MethodVisitor {
// For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
if
(
code
.
length
>
0
)
{
if
(
code
.
length
>
65535
)
{
throw
new
IndexOutOfBoundsException
(
"Method code too large!"
);
throw
new
MethodTooLargeException
(
symbolTable
.
getClassName
(),
name
,
descriptor
,
code
.
length
);
}
symbolTable
.
addConstantUtf8
(
Constants
.
CODE
);
// The Code attribute has 6 header bytes, plus 2, 2, 4 and 2 bytes respectively for max_stack,
...
...
asm/src/test/java/org/objectweb/asm/ByteVectorTest.java
View file @
d209ecc3
...
...
@@ -31,7 +31,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
java.util.Arrays
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.params.ParameterizedTest
;
import
org.junit.jupiter.params.provider.ValueSource
;
/**
* ByteVector tests.
...
...
@@ -113,10 +116,27 @@ public class ByteVectorTest {
assertContains
(
byteVector
,
0
,
8
,
'a'
,
-
64
,
-
128
,
-
62
,
-
128
,
-
32
,
-
96
,
-
128
);
char
[]
charBuffer
=
new
char
[
32768
];
for
(
int
i
=
0
;
i
<
charBuffer
.
length
;
++
i
)
{
charBuffer
[
i
]
=
'\
u07FF
'
;
Arrays
.
fill
(
charBuffer
,
'\
u07FF
'
);
IllegalArgumentException
thrown
=
assertThrows
(
IllegalArgumentException
.
class
,
()
->
byteVector
.
putUTF8
(
new
String
(
charBuffer
)));
assertEquals
(
"UTF8 string too large"
,
thrown
.
getMessage
());
}
@ParameterizedTest
@ValueSource
(
ints
=
{
65535
,
65536
})
public
void
testPutUTF8_tooLong
(
int
size
)
{
ByteVector
byteVector
=
new
ByteVector
(
0
);
char
[]
charBuffer
=
new
char
[
size
];
Arrays
.
fill
(
charBuffer
,
'A'
);
String
utf8
=
new
String
(
charBuffer
);
if
(
size
>
65535
)
{
IllegalArgumentException
thrown
=
assertThrows
(
IllegalArgumentException
.
class
,
()
->
byteVector
.
putUTF8
(
utf8
));
assertEquals
(
"UTF8 string too large"
,
thrown
.
getMessage
());
}
else
{
byteVector
.
putUTF8
(
utf8
);
}
assertThrows
(
IllegalArgumentException
.
class
,
()
->
byteVector
.
putUTF8
(
new
String
(
charBuffer
)));
}
@Test
...
...
asm/src/test/java/org/objectweb/asm/ClassWriterTest.java
View file @
d209ecc3
...
...
@@ -28,8 +28,7 @@
package
org.objectweb.asm
;
import
static
java
.
util
.
stream
.
Collectors
.
toSet
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.*;
import
static
org
.
objectweb
.
asm
.
test
.
Assertions
.
assertThat
;
import
java.io.FileInputStream
;
...
...
@@ -129,11 +128,18 @@ public class ClassWriterTest extends AsmTest {
@ValueSource
(
ints
=
{
65535
,
65536
})
public
void
testConstantPoolSizeTooLarge
(
final
int
constantPoolCount
)
{
ClassWriter
classWriter
=
new
ClassWriter
(
0
);
for
(
int
i
=
0
;
i
<
constantPoolCount
-
1
;
++
i
)
{
String
className
=
"A"
;
classWriter
.
visit
(
Opcodes
.
V1_7
,
Opcodes
.
ACC_PUBLIC
,
className
,
null
,
"java/lang/Object"
,
null
);
int
initConstantPoolCount
=
5
;
for
(
int
i
=
0
;
i
<
constantPoolCount
-
initConstantPoolCount
;
++
i
)
{
classWriter
.
newConst
(
Integer
.
valueOf
(
i
));
}
if
(
constantPoolCount
>
65535
)
{
assertThrows
(
IndexOutOfBoundsException
.
class
,
()
->
classWriter
.
toByteArray
());
ClassTooLargeException
thrown
=
assertThrows
(
ClassTooLargeException
.
class
,
()
->
classWriter
.
toByteArray
());
assertEquals
(
className
,
thrown
.
getClassName
());
assertEquals
(
constantPoolCount
,
thrown
.
getConstantPoolCount
());
assertEquals
(
"Class too large: A"
,
thrown
.
getMessage
());
}
else
{
classWriter
.
toByteArray
();
}
...
...
@@ -143,8 +149,12 @@ public class ClassWriterTest extends AsmTest {
@ValueSource
(
ints
=
{
65535
,
65536
})
void
testMethodCodeSizeTooLarge
(
final
int
methodCodeSize
)
{
ClassWriter
classWriter
=
new
ClassWriter
(
0
);
String
className
=
"A"
;
String
methodName
=
"m"
;
String
descriptor
=
"()V"
;
classWriter
.
visit
(
Opcodes
.
V1_7
,
Opcodes
.
ACC_PUBLIC
,
className
,
null
,
"java/lang/Object"
,
null
);
MethodVisitor
methodVisitor
=
classWriter
.
visitMethod
(
Opcodes
.
ACC_STATIC
,
"m"
,
"()V"
,
null
,
null
);
classWriter
.
visitMethod
(
Opcodes
.
ACC_STATIC
,
methodName
,
descriptor
,
null
,
null
);
methodVisitor
.
visitCode
();
for
(
int
i
=
0
;
i
<
methodCodeSize
-
1
;
++
i
)
{
methodVisitor
.
visitInsn
(
Opcodes
.
NOP
);
...
...
@@ -153,7 +163,13 @@ public class ClassWriterTest extends AsmTest {
methodVisitor
.
visitMaxs
(
0
,
0
);
methodVisitor
.
visitEnd
();
if
(
methodCodeSize
>
65535
)
{
assertThrows
(
IndexOutOfBoundsException
.
class
,
()
->
classWriter
.
toByteArray
());
MethodTooLargeException
thrown
=
assertThrows
(
MethodTooLargeException
.
class
,
()
->
classWriter
.
toByteArray
());
assertEquals
(
methodName
,
thrown
.
getMethodName
());
assertEquals
(
className
,
thrown
.
getClassName
());
assertEquals
(
descriptor
,
thrown
.
getDescriptor
());
assertEquals
(
methodCodeSize
,
thrown
.
getCodeSize
());
assertEquals
(
"Method too large: A.m ()V"
,
thrown
.
getMessage
());
}
else
{
classWriter
.
toByteArray
();
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment