Skip to content

Commit

Permalink
RTTI: Improve and speedup error handling of invalid core binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadelessFox committed Mar 18, 2024
1 parent 92be277 commit 5824f9c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,47 @@ public RTTICoreFile read(@NotNull InputStream is, boolean lenient) throws IOExce
break;
}

if (read != header.limit()) {
throw new IOException("Unexpected end of stream while reading object header");
}
final RTTIClass type;
final ByteBuffer data;

try {
if (read != header.limit()) {
throw new IOException("Unexpected end of stream while reading object header");
}

final var hash = header.getLong(0);
type = registry.find(hash);

if (type == null) {
continue;
}

final var type = header.getLong(0);
final var size = header.getInt(8);
final var data = ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN);
final var size = header.getInt(8);
data = ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN);

if (is.read(data.array()) != size) {
throw new IOException("Unexpected end of stream while reading object data");
}
} catch (Exception e) {
if (!lenient) {
throw e;
}

if (is.read(data.array()) != size) {
throw new IOException("Unexpected end of stream while reading object data");
continue;
}

RTTIObject object = null;

try {
object = registry
.<RTTIClass>find(type)
.read(registry, data);
object = type.read(registry, data);
} catch (Exception e) {
if (!lenient) {
throw e;
}
}

if (object == null || data.remaining() > 0) {
object = UnknownEntry.read(registry, data.position(0), type);
object = InvalidObject.read(registry, data.position(0), type.getFullTypeName());
}

objects.add(object);
Expand Down Expand Up @@ -128,22 +143,22 @@ private <T> void visitAllObjects(@Nullable Object parent, @NotNull Predicate<Obj
}

@RTTIExtends(@Type(name = "RTTIRefObject"))
public static class UnknownEntry {
public static class InvalidObject {
@RTTIField(type = @Type(name = "GGUUID"), name = "ObjectUUID")
public Object uuid;
@RTTIField(type = @Type(name = "uint64"))
public long hash;
@RTTIField(type = @Type(name = "String"))
public String type;
@RTTIField(type = @Type(name = "Array<uint8>"))
public byte[] data;

@NotNull
public static RTTIObject read(@NotNull RTTITypeRegistry registry, @NotNull ByteBuffer buffer, long hash) {
final UnknownEntry entry = new UnknownEntry();
public static RTTIObject read(@NotNull RTTITypeRegistry registry, @NotNull ByteBuffer buffer, @NotNull String type) {
final InvalidObject entry = new InvalidObject();
entry.uuid = registry.find("GGUUID").read(registry, buffer);
entry.hash = hash;
entry.type = type;
entry.data = BufferUtils.getBytes(buffer, buffer.remaining());

return new RTTIObject(registry.find(UnknownEntry.class), entry);
return new RTTIObject(registry.find(InvalidObject.class), entry);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.shade.decima.model.rtti.RTTIType;
import com.shade.decima.model.rtti.RTTITypeSerialized;
import com.shade.util.NotNull;
import com.shade.util.Nullable;

import java.io.IOException;
import java.util.*;
Expand Down Expand Up @@ -51,16 +52,10 @@ public <T extends RTTIType<?>> T find(@NotNull Class<?> clazz) {
return (T) type;
}

@NotNull
@Nullable
@SuppressWarnings("unchecked")
public <T extends RTTIType<?>> T find(long hash) {
final RTTIType<?> type = cacheByHash.get(hash);

if (type == null) {
throw new IllegalArgumentException("Can't find type with hash 0x" + Long.toHexString(hash) + " in the registry");
}

return (T) type;
return (T) cacheByHash.get(hash);
}

@NotNull
Expand Down

0 comments on commit 5824f9c

Please sign in to comment.