Skip to content

Commit

Permalink
Attempt to read invalid core entries as the RTTIRefObject
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadelessFox committed Sep 18, 2022
1 parent 6508740 commit b3106dd
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 25 deletions.
33 changes: 15 additions & 18 deletions src/main/java/com/shade/decima/model/base/CoreBinary.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.shade.decima.model.base;

import com.shade.decima.model.rtti.RTTIType;
import com.shade.decima.model.rtti.RTTIUtils;
import com.shade.decima.model.rtti.objects.RTTIObject;
import com.shade.decima.model.rtti.registry.RTTITypeRegistry;
Expand Down Expand Up @@ -29,33 +28,31 @@ public static CoreBinary from(@NotNull byte[] data, @NotNull RTTITypeRegistry re
final int size = buffer.getInt();
final ByteBuffer slice = buffer.slice(buffer.position(), size).order(ByteOrder.LITTLE_ENDIAN);

// It doesn't seem that this is the best place for handling the `lenient` option.
// We need to figure a better way to display unknown or incomplete entries in UI.
RTTITypeClass type;
RTTIObject entry;

try {
final RTTIType<?> type = registry.find(id);
final RTTIObject entry = (RTTIObject) type.read(registry, slice);

if (slice.remaining() > 0) {
final Byte[] remaining = IOUtils.box(IOUtils.getBytesExact(slice, slice.remaining()));
entry.define("$Remaining", registry.find("Array<uint8>"), remaining);
}

entries.add(entry);
type = (RTTITypeClass) registry.find(id);
entry = type.read(registry, slice);
} catch (Exception e) {
if (!lenient) {
throw e;
}

final Byte[] remaining = IOUtils.box(IOUtils.getBytesExact(slice, slice.position(0).remaining()));
final RTTIObject entry = RTTIUtils.newClassBuilder(registry, "UnknownEntry<%8x>".formatted(id))
.member("Data", "Array<uint8>")
.build().instantiate();
entry = null;
}

if (entry == null) {
type = RTTIUtils.newClassBuilder(registry, "RTTIRefObject", "UnknownEntry<%8x>".formatted(id)).build();
entry = type.read(registry, slice);
}

entry.set("Data", remaining);
entries.add(entry);
if (slice.remaining() > 0) {
final Byte[] remaining = IOUtils.box(IOUtils.getBytesExact(slice, slice.remaining()));
entry.define("$Remaining", registry.find("Array<uint8>"), remaining);
}

entries.add(entry);
buffer.position(buffer.position() + size);
}

Expand Down
20 changes: 18 additions & 2 deletions src/main/java/com/shade/decima/model/rtti/RTTIUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.shade.decima.model.rtti.registry.RTTITypeRegistry;
import com.shade.decima.model.rtti.types.RTTITypeClass;
import com.shade.util.NotNull;
import com.shade.util.Nullable;

import java.lang.reflect.Array;
import java.nio.ByteBuffer;
Expand All @@ -19,6 +20,11 @@ public static ClassBuilder newClassBuilder(@NotNull RTTITypeRegistry registry, @
return new ClassBuilder(registry, name);
}

@NotNull
public static ClassBuilder newClassBuilder(@NotNull RTTITypeRegistry registry, @NotNull String base, @NotNull String name) {
return new ClassBuilder(registry, (RTTITypeClass) registry.find(base), name);
}

@SuppressWarnings("unchecked")
@NotNull
public static <T> T[] readCollection(@NotNull RTTITypeRegistry registry, @NotNull ByteBuffer buffer, @NotNull RTTIType<T> type, int count) {
Expand All @@ -32,14 +38,20 @@ public static <T> T[] readCollection(@NotNull RTTITypeRegistry registry, @NotNul
public static class ClassBuilder {
private final RTTITypeRegistry registry;
private final String name;
private final RTTITypeClass base;
private final Map<String, RTTIType<?>> members;

public ClassBuilder(@NotNull RTTITypeRegistry registry, @NotNull String name) {
public ClassBuilder(@NotNull RTTITypeRegistry registry, @Nullable RTTITypeClass base, @NotNull String name) {
this.registry = registry;
this.name = name;
this.base = base;
this.members = new LinkedHashMap<>();
}

public ClassBuilder(@NotNull RTTITypeRegistry registry, @NotNull String name) {
this(registry, null, name);
}

@NotNull
public ClassBuilder member(@NotNull String name, @NotNull String type) {
return member(name, registry.find(type));
Expand All @@ -54,13 +66,17 @@ public ClassBuilder member(@NotNull String name, @NotNull RTTIType<?> type) {
@NotNull
public RTTITypeClass build() {
final RTTITypeClass clazz = new RTTITypeClass(name,
new RTTITypeClass.Base[0],
new RTTITypeClass.Base[base != null ? 1 : 0],
new RTTITypeClass.Member[members.size()],
Collections.emptyMap(),
0,
0
);

if (base != null) {
clazz.getBases()[0] = new RTTITypeClass.Base(clazz, base, 0);
}

final RTTITypeClass.Member[] members = this.members.entrySet().stream()
.map(info -> new RTTITypeClass.Member(clazz, info.getValue(), info.getKey(), "", 0, 0))
.toArray(RTTITypeClass.Member[]::new);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
import com.shade.util.NotNull;

public class CoreNodeEntry extends CoreNodeObject {
private final RTTIObject objectUUID;

public CoreNodeEntry(@NotNull CoreNodeBinary parent, @NotNull RTTIObject object) {
super(parent, object.getType(), object, RTTITypeRegistry.getFullTypeName(object.getType()), new PathElementUUID(object.get("ObjectUUID")));
this.objectUUID = object.get("ObjectUUID");
}

@NotNull
public RTTIObject getObjectUUID() {
return objectUUID;
return getObject().get("ObjectUUID");
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class CoreNodeObject extends TreeNodeLazy {
private final PathElement element;
private Object object;

public CoreNodeObject(@NotNull TreeNode parent, @NotNull RTTIType<?> type, @NotNull Object object, @NotNull String name, PathElement element) {
public CoreNodeObject(@NotNull TreeNode parent, @NotNull RTTIType<?> type, @NotNull Object object, @NotNull String name, @NotNull PathElement element) {
super(parent);
this.type = type;
this.handler = ValueHandlerProvider.getValueHandler(type);
Expand Down

0 comments on commit b3106dd

Please sign in to comment.