Skip to content

Commit 8dcd1be

Browse files
committed
Check that the referenced enum member exists
It detects problems such as the following: - kaitai-io/kaitai_struct_formats#349 (comment) - kaitai-io/kaitai_struct_formats#591 (comment)
1 parent 8913518 commit 8dcd1be

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

shared/src/main/scala/io/kaitai/struct/format/EnumSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import io.kaitai.struct.problems.KSYParseError
44

55
import scala.collection.mutable
66

7-
case class EnumSpec(map: Map[Long, EnumValueSpec]) {
7+
case class EnumSpec(path: List[String], map: Map[Long, EnumValueSpec]) extends YAMLPath {
88
var name = List[String]()
99

1010
/**
@@ -24,7 +24,7 @@ object EnumSpec {
2424
def fromYaml(src: Any, path: List[String]): EnumSpec = {
2525
val srcMap = ParseUtils.asMap(src, path)
2626
val memberNameMap = mutable.Map[String, Long]()
27-
EnumSpec(srcMap.map { case (id, desc) =>
27+
EnumSpec(path, srcMap.map { case (id, desc) =>
2828
val idLong = ParseUtils.asLong(id, path)
2929
val value = EnumValueSpec.fromYaml(desc, path ++ List(idLong.toString))
3030

shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class FieldNotFoundError(val name: String, val curClass: ClassSpec)
1818
extends NotFoundError(s"unable to access '$name' in ${curClass.nameAsStr} context")
1919
class EnumNotFoundError(val name: String, val curClass: ClassSpec)
2020
extends NotFoundError(s"unable to find enum '$name', searching from ${curClass.nameAsStr}")
21+
class EnumMemberNotFoundError(val label: String, val enum: String, val enumDefPath: String)
22+
extends NotFoundError(s"unable to find enum member '$enum::$label' (enum '$enum' defined at /$enumDefPath)")
2123
class MethodNotFoundError(val name: String, val dataType: DataType)
2224
extends NotFoundError(s"don't know how to call method '$name' of object type '$dataType'")
2325

shared/src/main/scala/io/kaitai/struct/translators/ExpressionValidator.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.kaitai.struct.translators
33
import io.kaitai.struct.datatype.DataType
44
import io.kaitai.struct.exprlang.Ast
55
import io.kaitai.struct.format.Identifier
6+
import io.kaitai.struct.precompile.EnumMemberNotFoundError
67

78
/**
89
* Validates expressions usage of types (in typecasting operator,
@@ -33,8 +34,10 @@ class ExpressionValidator(val provider: TypeProvider)
3334
provider.resolveEnum(inType, enumType.name)
3435
validate(id)
3536
case Ast.expr.EnumByLabel(enumType, label, inType) =>
36-
provider.resolveEnum(inType, enumType.name)
37-
// TODO: check that label belongs to that enum
37+
val enumSpec = provider.resolveEnum(inType, enumType.name)
38+
if (!enumSpec.map.values.exists(_.name == label.name)) {
39+
throw new EnumMemberNotFoundError(label.name, enumType.name, enumSpec.path.mkString("/"))
40+
}
3841
case Ast.expr.Name(name: Ast.identifier) =>
3942
if (name.name == Identifier.SIZEOF) {
4043
CommonSizeOf.getByteSizeOfClassSpec(provider.nowClass)

0 commit comments

Comments
 (0)