Skip to content

Commit

Permalink
Partially implement validation for valid key
Browse files Browse the repository at this point in the history
Fixed (4):
```
[info] - attr_bad_valid_expr *** FAILED ***
[info]   []
[info]     did not equal
[info]   [attr_bad_valid_expr.ksy: /seq/0/valid/expr:
[info]          error: invalid type: expected boolean, got Int1Type(true)
[info]   ] (SimpleMatchers.scala:34)
[info] - expr_field_unknown_valid_eq_long *** FAILED ***
[info]   []
[info]     did not equal
[info]   [expr_field_unknown_valid_eq_long.ksy: /seq/0/valid/eq:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_eq_long context
[info]   ] (SimpleMatchers.scala:34)
[info] - expr_field_unknown_valid_expr *** FAILED ***
[info]   []
[info]     did not equal
[info]   [expr_field_unknown_valid_expr.ksy: /seq/0/valid/expr:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_expr context
[info]   ] (SimpleMatchers.scala:34)
[info] - expr_field_unknown_valid_range *** FAILED ***
[info]   []
[info]     did not equal
[info]   [expr_field_unknown_valid_range.ksy: /seq/0/valid/min:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_range context
[info]
[info]   expr_field_unknown_valid_range.ksy: /seq/0/valid/max:
[info]          error: unable to access 'qux' in expr_field_unknown_valid_range context
[info]   ] (SimpleMatchers.scala:34)
```
Changed error message (4, must correct model to distinguish between `valid` and `valid.eq`):
```
[info] - attr_bad_valid_eq_long *** FAILED ***
[info]   [attr_bad_valid_eq_long.ksy: /seq/0/valid/eq:
[info]          error: invalid type: expected Int1Type(false), got CalcStrType
[info]   ]
[info]     did not equal
[info]   [attr_bad_valid_eq_long.ksy: /seq/0/valid/eq:
[info]          error: can't compare Int1Type(false) and CalcStrType
[info]   ] (SimpleMatchers.scala:34)
[info] - attr_bad_valid_eq_short *** FAILED ***
[info]   [attr_bad_valid_eq_short.ksy: /seq/0/valid/eq:
[info]          error: invalid type: expected Int1Type(false), got CalcStrType
[info]   ]
[info]     did not equal
[info]   [attr_bad_valid_eq_short.ksy: /seq/0/valid:
[info]          error: can't compare Int1Type(false) and CalcStrType
[info]   ] (SimpleMatchers.scala:34)
[info] - attr_bad_valid_repeat_eq_short *** FAILED ***
[info]   [attr_bad_valid_repeat_eq_short.ksy: /seq/0/valid/eq:
[info]          error: invalid type: expected IntMultiType(true,Width4,Some(LittleEndian)), got ArrayTypeInStream(CalcIntType)
[info]   ]
[info]     did not equal
[info]   [attr_bad_valid_repeat_eq_short.ksy: /seq/0/valid:
[info]          error: can't compare IntMultiType(true,Width4,Some(LittleEndian)) and ArrayTypeInStream(CalcIntType)
[info]   ] (SimpleMatchers.scala:34)
[info] - expr_field_unknown_valid_eq_short *** FAILED ***
[info]   [expr_field_unknown_valid_eq_short.ksy: /seq/0/valid/eq:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_eq_short context
[info]   ]
[info]     did not equal
[info]   [expr_field_unknown_valid_eq_short.ksy: /seq/0/valid:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_eq_short context
[info]   ] (SimpleMatchers.scala:34)
```
Changed error message (3, expected must be corrected or false-positives):
```
[info] - attr_bad_valid_any_of *** FAILED ***
[info]   [attr_bad_valid_any_of.ksy: /seq/0/valid/any-of/0:
[info]          error: invalid type: expected Int1Type(false), got Int1Type(true)
[info]
[info]   attr_bad_valid_any_of.ksy: /seq/0/valid/any-of/1:
[info]          error: invalid type: expected Int1Type(false), got Int1Type(true)
[info]
[info]   attr_bad_valid_any_of.ksy: /seq/0/valid/any-of/2:
[info]          error: invalid type: expected Int1Type(false), got CalcBooleanType
[info]
[info]   attr_bad_valid_any_of.ksy: /seq/0/valid/any-of/3:
[info]          error: invalid type: expected Int1Type(false), got Int1Type(true)
[info]   ]
[info]     did not equal
[info]   [attr_bad_valid_any_of.ksy: /seq/0/valid/any-of/2:
[info]          error: can't compare Int1Type(false) and CalcBooleanType
[info]   ] (SimpleMatchers.scala:34)
[info] - attr_bad_valid_range *** FAILED ***
[info]   [attr_bad_valid_range.ksy: /seq/0/valid/min:
[info]          error: invalid type: expected Int1Type(false), got CalcBooleanType
[info]
[info]   attr_bad_valid_range.ksy: /seq/0/valid/max:
[info]          error: invalid type: expected Int1Type(false), got CalcStrType
[info]   ]
[info]     did not equal
[info]   [attr_bad_valid_range.ksy: /seq/0/valid/min:
[info]          error: can't compare Int1Type(false) and CalcBooleanType
[info]
[info]   attr_bad_valid_range.ksy: /seq/0/valid/max:
[info]          error: can't compare Int1Type(false) and CalcStrType
[info]   ] (SimpleMatchers.scala:34)
[info] - expr_field_unknown_valid_any_of *** FAILED ***
[info]   [expr_field_unknown_valid_any_of.ksy: /seq/0/valid/any-of/0:
[info]          error: invalid type: expected Int1Type(false), got Int1Type(true)
[info]
[info]   expr_field_unknown_valid_any_of.ksy: /seq/0/valid/any-of/1:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_any_of context
[info]
[info]   expr_field_unknown_valid_any_of.ksy: /seq/0/valid/any-of/2:
[info]          error: invalid type: expected Int1Type(false), got Int1Type(true)
[info]
[info]   expr_field_unknown_valid_any_of.ksy: /seq/0/valid/any-of/3:
[info]          error: unable to access 'qux' in expr_field_unknown_valid_any_of context
[info]   ]
[info]     did not equal
[info]   [expr_field_unknown_valid_any_of.ksy: /seq/0/valid/any-of/1:
[info]          error: unable to access 'bar' in expr_field_unknown_valid_any_of context
[info]
[info]   expr_field_unknown_valid_any_of.ksy: /seq/0/valid/any-of/3:
[info]          error: unable to access 'qux' in expr_field_unknown_valid_any_of context
[info]   ] (SimpleMatchers.scala:34)
```
  • Loading branch information
Mingun committed Sep 10, 2024
1 parent 049b464 commit 8792049
Showing 1 changed file with 48 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ class TypeValidator(specs: ClassSpecs) extends PrecompileStep {

val problemsDataType = validateDataType(attr.dataType, path)

List(problemsIf, problemsRepeat, problemsDataType).flatten
val problemsValid: Iterable[CompilationProblem] = attr.valid match {
case Some(valid) => validateValidClause(valid, attr.dataType, attr.path :+ "valid")
case None => None // all good
}

List(problemsIf, problemsRepeat, problemsDataType, problemsValid).flatten
}

def validateParseInstance(pis: ParseInstanceSpec): Iterable[CompilationProblem] = {
Expand All @@ -100,7 +105,12 @@ class TypeValidator(specs: ClassSpecs) extends PrecompileStep {
case None => None // all good
}

List(problemsAttr, problemsIo, problemsPos).flatten
val problemsValid: Iterable[CompilationProblem] = pis.valid match {
case Some(valid) => validateValidClause(valid, pis.dataType, pis.path :+ "valid")
case None => None // all good
}

List(problemsAttr, problemsIo, problemsPos, problemsValid).flatten
}

def validateValueInstance(vis: ValueInstanceSpec): Option[CompilationProblem] = {
Expand Down Expand Up @@ -204,6 +214,42 @@ class TypeValidator(specs: ClassSpecs) extends PrecompileStep {
}
}

/**
* @param valid The `valid` clause of Kaitai Struct attribute or parse instance definition
* @param attrType The type of attribute, used to check compatibility of valid expressions to that type
* @param path Path where `valid` key is defined
*/
private def validateValidClause(
valid: ValidationSpec,
attrType: DataType,
path: List[String]
): Iterable[CompilationProblem] = {
// TODO: This is not user-face message
val expected = attrType.toString
valid match {
// TODO: Need to distinguish between `valid`, `valid.eq` and `contents`
case ValidationEq(value) =>
checkAssertObject(value, attrType, expected, path, "eq")
case ValidationMin(min) =>
checkAssertObject(min, attrType, expected, path, "min")
case ValidationMax(max) =>
checkAssertObject(max, attrType, expected, path, "max")
case ValidationRange(min, max) => {
checkAssertObject(min, attrType, expected, path, "min") ++
checkAssertObject(max, attrType, expected, path, "max")
}
case ValidationAnyOf(values) => {
val itemPath = path :+ "any-of"
values.zipWithIndex.flatMap { case (value, i) =>
checkAssertObject(value, attrType, expected, itemPath, i.toString)
}
}
case ValidationInEnum() => List()
case ValidationExpr(checkExpr) =>
checkAssert[BooleanType](checkExpr, "boolean", path, "expr")
}
}

/**
* Checks that expression's type conforms to a given datatype, otherwise
* throw a human-readable exception, with some pointers that would help
Expand Down

0 comments on commit 8792049

Please sign in to comment.