fix handling of classe, method, and field names with non-ASCII characters

This commit is contained in:
Joel Dice 2013-02-03 14:09:29 -07:00
parent 1db67e463f
commit 1890e348fb
5 changed files with 113 additions and 17 deletions

View File

@ -504,6 +504,8 @@ class MyClasspath : public Classpath {
object charArray = makeCharArray(t, length);
for (int i = 0; i < length; ++i) {
expect(t, (byteArrayBody(t, array, offset + i) & 0x80) == 0);
charArrayBody(t, charArray, i) = byteArrayBody(t, array, offset + i);
}
@ -5039,7 +5041,7 @@ jvmConstantPoolGetUTF8At(Thread* t, uintptr_t* arguments)
jobject pool = reinterpret_cast<jobject>(arguments[0]);
jint index = arguments[1];
object array = singletonObject(t, *pool, index - 1);
object array = parseUtf8(t, singletonObject(t, *pool, index - 1));
return reinterpret_cast<uint64_t>
(makeLocalReference

View File

@ -727,7 +727,7 @@ finalizeObject(Thread* t, object o, const char* name)
}
unsigned
readByte(Stream& s, unsigned* value)
readByte(AbstractStream& s, unsigned* value)
{
if (*value == NoByte) {
return s.read1();
@ -739,8 +739,9 @@ readByte(Stream& s, unsigned* value)
}
object
parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
unsigned sourceIndex, unsigned byteA, unsigned byteB)
parseUtf8NonAscii(Thread* t, AbstractStream& s, object bytesSoFar,
unsigned byteCount, unsigned sourceIndex, unsigned byteA,
unsigned byteB)
{
PROTECT(t, bytesSoFar);
@ -792,7 +793,7 @@ parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
}
object
parseUtf8(Thread* t, Stream& s, unsigned length)
parseUtf8(Thread* t, AbstractStream& s, unsigned length)
{
object value = makeByteArray(t, length + 1);
unsigned vi = 0;
@ -830,6 +831,14 @@ parseUtf8(Thread* t, Stream& s, unsigned length)
return value;
}
object
makeByteArray(Thread* t, Stream& s, unsigned length)
{
object value = makeByteArray(t, length + 1);
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, value, 0)), length);
return value;
}
void
removeByteArray(Thread* t, object o)
{
@ -885,10 +894,7 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i)
case CONSTANT_Utf8: {
if (singletonObject(t, pool, i) == 0) {
object value = parseUtf8(t, s, s.read2());
if (objectClass(t, value) == type(t, Machine::ByteArrayType)) {
value = internByteArray(t, value);
}
object value = internByteArray(t, makeByteArray(t, s, s.read2()));
set(t, pool, SingletonBody + (i * BytesPerWord), value);
if(DebugClassReader) {
@ -916,7 +922,7 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i)
unsigned si = s.read2() - 1;
parsePoolEntry(t, s, index, pool, si);
object value = singletonObject(t, pool, si);
object value = parseUtf8(t, singletonObject(t, pool, si));
value = t->m->classpath->makeString
(t, value, 0, cast<uintptr_t>(value, BytesPerWord) - 1);
value = intern(t, value);
@ -4886,6 +4892,62 @@ parseUtf8(Thread* t, const char* data, unsigned length)
return ::parseUtf8(t, s, length);
}
object
parseUtf8(Thread* t, object array)
{
for (unsigned i = 0; i < byteArrayLength(t, array) - 1; ++i) {
if (byteArrayBody(t, array, i) & 0x80) {
goto slow_path;
}
}
return array;
slow_path:
class Client: public Stream::Client {
public:
Client(Thread* t): t(t) { }
virtual void handleError() {
// vm::abort(t);
}
private:
Thread* t;
} client(t);
class MyStream: public AbstractStream {
public:
class MyProtector: public Thread::Protector {
public:
MyProtector(Thread* t, MyStream* s):
Protector(t), s(s)
{ }
virtual void visit(Heap::Visitor* v) {
v->visit(&(s->array));
}
MyStream* s;
};
MyStream(Thread* t, Client* client, object array):
AbstractStream(client, byteArrayLength(t, array) - 1),
array(array),
protector(t, this)
{ }
virtual void copy(uint8_t* dst, unsigned offset, unsigned size) {
memcpy(dst, &byteArrayBody(protector.t, array, offset), size);
}
object array;
MyProtector protector;
} s(t, &client, array);
return ::parseUtf8(t, s, byteArrayLength(t, array) - 1);
}
object
getCaller(Thread* t, unsigned target, bool skipMethodInvoke)
{

View File

@ -2525,6 +2525,9 @@ emptyMethod(Thread* t, object method)
object
parseUtf8(Thread* t, const char* data, unsigned length);
object
parseUtf8(Thread* t, object array);
object
parseClass(Thread* t, object loader, const uint8_t* data, unsigned length,
Machine::Type throwType = Machine::NoClassDefFoundErrorType);

View File

@ -15,15 +15,15 @@
namespace vm {
class Stream {
class AbstractStream {
public:
class Client {
public:
virtual void handleError() = 0;
};
Stream(Client* client, const uint8_t* data, unsigned size):
client(client), data(data), size(size), position_(0)
AbstractStream(Client* client, unsigned size):
client(client), size(size), position_(0)
{ }
unsigned position() {
@ -42,13 +42,13 @@ class Stream {
}
}
void read(uint8_t* data, unsigned size) {
void read(uint8_t* dst, unsigned size) {
if (size > this->size - position_) {
memset(data, 0, size);
memset(dst, 0, size);
client->handleError();
} else {
memcpy(data, this->data + position_, size);
copy(dst, position_, size);
position_ += size;
}
}
@ -85,13 +85,29 @@ class Stream {
return read8();
}
protected:
virtual void copy(uint8_t* dst, unsigned offset, unsigned size) = 0;
private:
Client* client;
const uint8_t* data;
unsigned size;
unsigned position_;
};
class Stream: public AbstractStream {
public:
Stream(Client* client, const uint8_t* data, unsigned size):
AbstractStream(client, size), data(data)
{ }
private:
virtual void copy(uint8_t* dst, unsigned offset, unsigned size) {
memcpy(dst, data + offset, size);
}
const uint8_t* data;
};
} // namespace vm
#endif//STREAM_H

View File

@ -1,4 +1,12 @@
public class Misc {
private static class μClass {
public int μField;
public void μMethod(int i) {
μField = i;
}
}
private interface Bar {
public int baz();
}
@ -237,5 +245,10 @@ public class Misc {
System.out.println(new char[] { 'h', 'i' });
expect(! (((Object) new int[0]) instanceof Object[]));
{ μClass μInstance = new μClass();
μInstance.μMethod(8933);
expect(μInstance.μField == 8933);
}
}
}