mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
fix handling of classe, method, and field names with non-ASCII characters
This commit is contained in:
parent
1db67e463f
commit
1890e348fb
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
30
src/stream.h
30
src/stream.h
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user