From f7cc51f83b0935f333e2554761319973f0e4fc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20G=C3=BCnzler?= Date: Tue, 7 Aug 2018 12:49:10 +0200 Subject: [PATCH] pkg/search: fix dir search with logical not constraints As demonstrated by the test case added in this commit, a search panics if the DirConstraint contains a LogicalConstraint with Op set to "not". This is because the isFileOrDirConstraint function doesn't account for unset "B". Change-Id: I111ace62486160254ba22ab1498de78cde2a5e9b --- pkg/search/query.go | 3 +++ pkg/search/query_test.go | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/pkg/search/query.go b/pkg/search/query.go index 791426bc8..1f74ca2e5 100644 --- a/pkg/search/query.go +++ b/pkg/search/query.go @@ -2063,6 +2063,9 @@ func (c *DirConstraint) checkValid() error { func (c *Constraint) isFileOrDirConstraint() bool { if l := c.Logical; l != nil { + if l.Op == "not" { + return l.A.isFileOrDirConstraint() // l.B is nil + } return l.A.isFileOrDirConstraint() && l.B.isFileOrDirConstraint() } return c.File != nil || c.Dir != nil diff --git a/pkg/search/query_test.go b/pkg/search/query_test.go index 5be69ce97..943837114 100644 --- a/pkg/search/query_test.go +++ b/pkg/search/query_test.go @@ -789,6 +789,48 @@ func TestQueryDirWithFileConstraint(t *testing.T) { }) } +// find a dir that doesn't contain any text files +func TestQueryDirWithLogicalNotConstraint(t *testing.T) { + testQuery(t, func(qt *queryTest) { + id := qt.id + fileRef1, _ := id.UploadFile("some-stuff.txt", "hello", time.Unix(123, 0)) + qt.t.Logf("fileRef1 = %q", fileRef1) + fileRef2, _ := id.UploadFile("more-stuff.txt", "world", time.Unix(456, 0)) + qt.t.Logf("fileRef2 = %q", fileRef2) + dirRef1 := id.UploadDir("somedir", []blob.Ref{fileRef1, fileRef2}, time.Unix(789, 0)) + qt.t.Logf("dirRef1 = %q", dirRef1) + p1 := id.NewPlannedPermanode("1") + id.SetAttribute(p1, "camliContent", dirRef1.String()) + + fileRef3, _ := id.UploadFile("other-file", "hellooooo", time.Unix(101112, 0)) + qt.t.Logf("fileRef3 = %q", fileRef3) + dirRef2 := id.UploadDir("anotherdir", []blob.Ref{fileRef3}, time.Unix(181112, 0)) + qt.t.Logf("dirRef2 = %q", dirRef2) + p2 := id.NewPlannedPermanode("2") + id.SetAttribute(p2, "camliContent", dirRef2.String()) + + sq := &SearchQuery{ + Constraint: &Constraint{ + Dir: &DirConstraint{ + Contains: &Constraint{ + Logical: &LogicalConstraint{ + A: &Constraint{ + File: &FileConstraint{ + FileName: &StringConstraint{ + HasSuffix: ".txt", + }, + }, + }, + Op: "not", + }, + }, + }, + }, + } + qt.wantRes(sq, dirRef2) + }) +} + // find permanode with a dir that contains a certain file or dir func TestQueryDirWithFileOrDirConstraint(t *testing.T) { testQuery(t, func(qt *queryTest) {