Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions pkg/corset/compiler/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,10 @@ func (t *translator) translateDefLookup(decl *ast.DefLookup) []SyntaxError {
func (t *translator) translateDefLookupSources(selector ast.Expr,
sources []ast.Expr) (lookup.Vector[mir.Term], ast.Context, []SyntaxError) {
// Determine context of ith set of targets
context, j := ast.ContextOfExpressions(sources...)
var (
context, j = ast.ContextOfExpressions(sources...)
vector lookup.Vector[mir.Term]
)
// Include selector (when present)
if selector != nil {
context = context.Join(selector.Context())
Expand All @@ -408,10 +411,51 @@ func (t *translator) translateDefLookupSources(selector ast.Expr,
s, errs := t.translateExpression(selector, module, 0)
errors = append(errors, errs...)

return lookup.FilteredVector(module.Id(), s, terms...), context, errors
vector = lookup.FilteredVector(module.Id(), s, terms...)
} else {
vector = lookup.UnfilteredVector(module.Id(), terms...)
}
// Sanity check vector
errors = append(errors, t.checkLookupVector(vector, selector, sources)...)
//
return vector, context, errors
}

func (t *translator) checkLookupVector(vector lookup.Vector[mir.Term], selector ast.Expr,
terms []ast.Expr) []SyntaxError {
//
return lookup.UnfilteredVector(module.Id(), terms...), context, errors
var (
modmap = t.schema.Module(vector.Module)
errors []SyntaxError
)
// Look for any negative terms
for i, ith := range vector.Terms {
// Determine value range of ith term
valrange := ith.ValueRange(modmap)
// Determine bitwidth for that range
_, signed := valrange.BitWidth()
// Sanity check signed lookups
if signed {
errors = append(errors, *t.srcmap.SyntaxError(terms[i], "signed term encountered"))
}
}
// Check selector is binary
if vector.HasSelector() {
// Determine value range of ith term
valrange := vector.Selector.Unwrap().ValueRange(modmap)
// Determine bitwidth for that range

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Vector Lookup Bugs: Mismatched Lengths, Nil Terms

The checkLookupVector function contains two bugs:

  1. It can panic with an index out of bounds error when iterating vector.Terms and accessing terms[i], as the lengths of vector.Terms (translated mir.Terms) and terms (original ast.Exprs) are not guaranteed to match.
  2. It can panic with a null pointer dereference when calling ValueRange() on elements of vector.Terms or on vector.Selector.Unwrap(). This occurs if prior translation steps (translateUnitExpressions or translateExpression) resulted in nil mir.Terms being included in the vector.
Locations (1)

Fix in Cursor Fix in Web

bitwidth, signed := valrange.BitWidth()
// Check for signed selector
if signed {
errors = append(errors, *t.srcmap.SyntaxError(selector, "signed selector encountered"))
}
// Check for non-binary selector
if bitwidth > 1 {
errors = append(errors, *t.srcmap.SyntaxError(selector, "non-binary selector encountered"))
}
}
// Done
return errors
}

// Translate a "definrange" declaration.
Expand Down
13 changes: 13 additions & 0 deletions pkg/test/invalid_corset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,19 @@ func Test_Invalid_Lookup_10(t *testing.T) {
CheckInvalid(t, "invalid/lookup_invalid_10")
}

func Test_Invalid_Lookup_11(t *testing.T) {
CheckInvalid(t, "invalid/lookup_invalid_11")
}
func Test_Invalid_Lookup_12(t *testing.T) {
CheckInvalid(t, "invalid/lookup_invalid_12")
}
func Test_Invalid_Lookup_13(t *testing.T) {
CheckInvalid(t, "invalid/lookup_invalid_13")
}
func Test_Invalid_Lookup_14(t *testing.T) {
CheckInvalid(t, "invalid/lookup_invalid_14")
}

// ===================================================================
// Interleavings
// ===================================================================
Expand Down
3 changes: 3 additions & 0 deletions testdata/invalid/lookup_invalid_11.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
;;error:3:16-23:signed term encountered
(defcolumns (X :u16) (Y :u16))
(deflookup l1 ((- 1 X)) (Y))
3 changes: 3 additions & 0 deletions testdata/invalid/lookup_invalid_12.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
;;error:3:20-27:signed term encountered
(defcolumns (X :u16) (Y :u16))
(deflookup l1 (X) ((- 1 Y)))
3 changes: 3 additions & 0 deletions testdata/invalid/lookup_invalid_13.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
;;error:3:20-27:signed selector encountered
(defcolumns (P :u1) (X :u16) (Y :u16))
(defclookup l1 (X) (- 0 P) (Y))
3 changes: 3 additions & 0 deletions testdata/invalid/lookup_invalid_14.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
;;error:3:20-21:non-binary selector encountered
(defcolumns (P :u2) (X :u16) (Y :u16))
(defclookup l1 (X) P (Y))