You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2026/10/20 23:01:56 UTC
(mynewt-newt) 07/30: newt/parse: Fix crash on empty parentheses in expressions
This is an automated email from the ASF dual-hosted git repository.
sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git
commit 3a7a7e58bb4718257c518017b9e828aea60adda4
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Mon Oct 19 17:45:44 2026 +0200
newt/parse: Fix crash on empty parentheses in expressions
An empty parenthesized group, e.g. "X == ()" or "() < 1", was parsed
into a nil operand node. Evaluating such a binary operator later
dereferenced the nil node and newt crashed with a nil pointer panic.
Treat an empty parenthesized group as a parse error.
Assisted-by: Claude:claude-opus-5-5
---
newt/parse/parse.go | 3 ++
newt/parse/parse_test.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/newt/parse/parse.go b/newt/parse/parse.go
index 1d474ec3..05ed0e49 100644
--- a/newt/parse/parse.go
+++ b/newt/parse/parse.go
@@ -304,6 +304,9 @@ func Parse(tokens []Token) (*Node, error) {
return nil, fmt.Errorf("unexpected %s after parenthesis",
tokens[len(stripped)+2].Text)
}
+ if len(stripped) == 0 {
+ return nil, fmt.Errorf("empty parentheses")
+ }
return Parse(stripped)
}
diff --git a/newt/parse/parse_test.go b/newt/parse/parse_test.go
new file mode 100644
index 00000000..0413e21e
--- /dev/null
+++ b/newt/parse/parse_test.go
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package parse
+
+import (
+ "testing"
+
+ "mynewt.apache.org/newt/newt/cfgv"
+)
+
+func TestParseEmptyParens(t *testing.T) {
+ settings := cfgv.NewSettingsFromMap(map[string]string{"X": "1"})
+
+ exprs := []string{
+ "()",
+ "X == ()",
+ "() == 1",
+ "X != ()",
+ "X < ()",
+ "() >= X",
+ "X && ()",
+ "!()",
+ "(())",
+ "X == (())",
+ }
+ for _, expr := range exprs {
+ _, err := ParseAndEval(expr, settings)
+ if err == nil {
+ t.Errorf("expected error for expression [%s]", expr)
+ }
+ }
+}
+
+func TestParseValid(t *testing.T) {
+ settings := cfgv.NewSettingsFromMap(map[string]string{
+ "X": "1",
+ "Y": "0",
+ })
+
+ exprs := map[string]bool{
+ "": true,
+ "X": true,
+ "(X)": true,
+ "((X) == (1))": true,
+ "X == (Y)": false,
+ "!(Y)": true,
+ "X > Y": true,
+ }
+ for expr, want := range exprs {
+ got, err := ParseAndEval(expr, settings)
+ if err != nil {
+ t.Errorf("unexpected error for expression [%s]: %v", expr, err)
+ continue
+ }
+ if got != want {
+ t.Errorf("expression [%s]: got %v, want %v", expr, got, want)
+ }
+ }
+}