mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-661: Fixing schema issues. Fixing dbgeng/model schemas.
This commit is contained in:
parent
5387946fab
commit
7d5c35138a
9 changed files with 31 additions and 33 deletions
|
@ -73,9 +73,6 @@ public abstract class AbstractTargetObject<P extends TargetObject>
|
|||
this.typeHint = typeHint;
|
||||
|
||||
this.schema = schema;
|
||||
if (schema != null) {
|
||||
schema.validateTypeAndInterfaces(getProxy(), null, enforcesStrictSchema());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -239,7 +239,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
}
|
||||
TargetObjectSchema schemax = getSchema();
|
||||
if (schemax != null) {
|
||||
schemax.validateElementDelta(getProxy(), delta, enforcesStrictSchema());
|
||||
schemax.validateElementDelta(getPath(), delta, enforcesStrictSchema());
|
||||
}
|
||||
doInvalidateElements(delta.removed.values(), reason);
|
||||
if (!delta.isEmpty()) {
|
||||
|
@ -284,7 +284,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
}
|
||||
TargetObjectSchema schemax = getSchema();
|
||||
if (schemax != null) {
|
||||
schemax.validateElementDelta(getProxy(), delta, enforcesStrictSchema());
|
||||
schemax.validateElementDelta(getPath(), delta, enforcesStrictSchema());
|
||||
}
|
||||
doInvalidateElements(delta.removed.values(), reason);
|
||||
if (!delta.isEmpty()) {
|
||||
|
@ -403,7 +403,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
}
|
||||
TargetObjectSchema schemax = getSchema();
|
||||
if (schemax != null) {
|
||||
schemax.validateAttributeDelta(getProxy(), delta, enforcesStrictSchema());
|
||||
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
}
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
if (!delta.isEmpty()) {
|
||||
|
@ -448,7 +448,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
}
|
||||
TargetObjectSchema schemax = getSchema();
|
||||
if (schemax != null) {
|
||||
schemax.validateAttributeDelta(getProxy(), delta, enforcesStrictSchema());
|
||||
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
}
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
if (!delta.isEmpty()) {
|
||||
|
|
|
@ -131,7 +131,7 @@ public interface TargetLauncher<T extends TargetLauncher<T>> extends TypedTarget
|
|||
}
|
||||
}
|
||||
|
||||
@TargetAttributeType(name = TargetMethod.PARAMETERS_ATTRIBUTE_NAME, required = true, fixed = true, hidden = true)
|
||||
@TargetAttributeType(name = TargetMethod.PARAMETERS_ATTRIBUTE_NAME, required = true, hidden = true)
|
||||
default public TargetParameterMap getParameters() {
|
||||
return TargetMethod.getParameters(this);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.*;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ghidra.dbg.DebugModelConventions;
|
||||
import ghidra.dbg.agent.DefaultTargetObject;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.schema.DefaultTargetObjectSchema.DefaultAttributeSchema;
|
||||
|
@ -427,13 +426,16 @@ public interface TargetObjectSchema {
|
|||
*
|
||||
* @param value the value
|
||||
*/
|
||||
default void validateTypeAndInterfaces(Object value, String key, boolean strict) {
|
||||
default void validateTypeAndInterfaces(Object value, List<String> parentPath, String key,
|
||||
boolean strict) {
|
||||
Class<?> cls = value.getClass();
|
||||
if (!getType().isAssignableFrom(cls)) {
|
||||
String msg = key == null
|
||||
String path =
|
||||
key == null ? null : PathUtils.toString(PathUtils.extend(parentPath, key));
|
||||
String msg = path == null
|
||||
? "Value " + value + " does not conform to required type " +
|
||||
getType() + " of schema " + this
|
||||
: "Value " + value + " for " + key + " does not conform to required type " +
|
||||
: "Value " + value + " for " + path + " does not conform to required type " +
|
||||
getType() + " of schema " + this;
|
||||
if (strict) {
|
||||
throw new AssertionError(msg);
|
||||
|
@ -495,21 +497,18 @@ public interface TargetObjectSchema {
|
|||
*
|
||||
* @param delta the delta, before or after the fact
|
||||
*/
|
||||
default void validateAttributeDelta(TargetObject object, Delta<?, ?> delta, boolean strict) {
|
||||
default void validateAttributeDelta(List<String> parentPath, Delta<?, ?> delta,
|
||||
boolean strict) {
|
||||
for (Map.Entry<String, ?> ent : delta.added.entrySet()) {
|
||||
String key = ent.getKey();
|
||||
Object value = ent.getValue();
|
||||
AttributeSchema as = getAttributeSchema(key);
|
||||
TargetObjectSchema schema = getContext().getSchema(as.getSchema());
|
||||
/**
|
||||
* TODO: There's some duplication of effort here, since canonical attributes will
|
||||
* already have been checked at construction.
|
||||
*/
|
||||
schema.validateTypeAndInterfaces(value, key, strict);
|
||||
schema.validateTypeAndInterfaces(value, parentPath, key, strict);
|
||||
|
||||
if (value instanceof TargetObject) {
|
||||
TargetObject ov = (TargetObject) value;
|
||||
if (!PathUtils.isLink(object.getPath(), ent.getKey(), ov.getPath())) {
|
||||
if (!PathUtils.isLink(parentPath, ent.getKey(), ov.getPath())) {
|
||||
schema.validateRequiredAttributes(ov, strict);
|
||||
}
|
||||
}
|
||||
|
@ -524,7 +523,7 @@ public interface TargetObjectSchema {
|
|||
.filter(delta.getKeysRemoved()::contains)
|
||||
.collect(Collectors.toSet());
|
||||
if (!violatesRequired.isEmpty()) {
|
||||
String msg = "Object " + object + " removed required attributes " +
|
||||
String msg = "Object " + parentPath + " removed required attributes " +
|
||||
violatesRequired + " of schema " + this;
|
||||
if (strict) {
|
||||
throw new AssertionError(msg);
|
||||
|
@ -542,10 +541,7 @@ public interface TargetObjectSchema {
|
|||
.filter(delta.removed::containsKey)
|
||||
.collect(Collectors.toSet());
|
||||
if (!violatesFixed.isEmpty()) {
|
||||
if (strict) {
|
||||
|
||||
}
|
||||
String msg = "Object " + object + " modified or removed fixed attributes " +
|
||||
String msg = "Object " + parentPath + " modified or removed fixed attributes " +
|
||||
violatesFixed + " of schema " + this;
|
||||
if (strict) {
|
||||
throw new AssertionError(msg);
|
||||
|
@ -563,11 +559,14 @@ public interface TargetObjectSchema {
|
|||
*
|
||||
* @param delta the delta, before or after the fact
|
||||
*/
|
||||
default void validateElementDelta(TargetObject object, Delta<?, ? extends TargetObject> delta,
|
||||
default void validateElementDelta(List<String> parentPath,
|
||||
Delta<?, ? extends TargetObject> delta,
|
||||
boolean strict) {
|
||||
for (Map.Entry<String, ? extends TargetObject> ent : delta.added.entrySet()) {
|
||||
TargetObject element = ent.getValue();
|
||||
TargetObjectSchema schema = getContext().getSchema(getElementSchema(ent.getKey()));
|
||||
schema.validateRequiredAttributes(ent.getValue(), strict);
|
||||
schema.validateTypeAndInterfaces(element, parentPath, ent.getKey(), strict);
|
||||
schema.validateRequiredAttributes(element, strict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,8 @@ public class TargetObjectSchemaValidationTest {
|
|||
.addInterface(TargetAggregate.class)
|
||||
.buildAndAdd();
|
||||
|
||||
new ValidatedModelRoot(model, "Root", schemaRoot);
|
||||
schemaRoot.validateTypeAndInterfaces(new ValidatedModelRoot(model, "Root", schemaRoot),
|
||||
List.of(), null, true);
|
||||
// pass
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,8 @@ public class TargetObjectSchemaValidationTest {
|
|||
.addInterface(TargetProcess.class)
|
||||
.buildAndAdd();
|
||||
|
||||
new ValidatedModelRoot(model, "Root", schemaRoot);
|
||||
schemaRoot.validateTypeAndInterfaces(new ValidatedModelRoot(model, "Root", schemaRoot),
|
||||
List.of(), null, true);
|
||||
}
|
||||
|
||||
protected ValidatedModelRoot createRootAttrWReq() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue