do nothing in System.arraycopy if length <= 0

Previously, we risked segfaults by passing negative numbers to memcpy.

This commit also makes arraycopy throw an IndexOutOfBounds exception
instead of an ArrayStoreException if the specified offsets and lengths
would take us outside the bounds of one or both of the arrays, per the
Sun documentation.
This commit is contained in:
Joel Dice 2010-07-13 18:40:29 -06:00
parent 71972fd1b5
commit 4034a219d0
3 changed files with 31 additions and 17 deletions

View File

@ -594,25 +594,32 @@ Avian_java_lang_System_arraycopy
if (LIKELY(elementSize)) {
intptr_t sl = cast<uintptr_t>(src, BytesPerWord);
intptr_t dl = cast<uintptr_t>(dst, BytesPerWord);
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
dstOffset >= 0 and dstOffset + length <= dl))
{
uint8_t* sbody = &cast<uint8_t>(src, ArrayBody);
uint8_t* dbody = &cast<uint8_t>(dst, ArrayBody);
if (src == dst) {
memmove(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
if (LIKELY(length > 0)) {
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
dstOffset >= 0 and dstOffset + length <= dl))
{
uint8_t* sbody = &cast<uint8_t>(src, ArrayBody);
uint8_t* dbody = &cast<uint8_t>(dst, ArrayBody);
if (src == dst) {
memmove(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
} else {
memcpy(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
}
if (classObjectMask(t, objectClass(t, dst))) {
mark(t, dst, ArrayBody + (dstOffset * BytesPerWord), length);
}
return;
} else {
memcpy(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
t->exception = makeIndexOutOfBoundsException(t);
return;
}
if (classObjectMask(t, objectClass(t, dst))) {
mark(t, dst, ArrayBody + (dstOffset * BytesPerWord), length);
}
} else {
return;
}
}

View File

@ -1759,6 +1759,12 @@ makeIllegalMonitorStateException(Thread* t)
return makeIllegalMonitorStateException(t, 0, makeTrace(t), 0);
}
inline object
makeIndexOutOfBoundsException(Thread* t)
{
return makeIndexOutOfBoundsException(t, 0, makeTrace(t), 0);
}
inline object
makeArrayIndexOutOfBoundsException(Thread* t, object message)
{

1
vm.pro
View File

@ -38,6 +38,7 @@
-keep public class java.lang.IllegalArgumentException
-keep public class java.lang.IllegalMonitorStateException
-keep public class java.lang.IllegalThreadStateException
-keep public class java.lang.IndexOutOfBoundsException
-keep public class java.lang.ArrayIndexOutOfBoundsException
-keep public class java.lang.ArrayStoreException
-keep public class java.lang.NegativeArraySizeException