From 2d2c069ffe6db76133d07e14e5db4a3c761fa3f5 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi <1591639+s1na@users.noreply.github.com> Date: Thu, 19 Jan 2023 19:43:29 +0100 Subject: [PATCH] console, internal/jsre: fix autocomplete issues (#26518) Fixes #26505 where the console crashed when a property getter raised an exception during autocompletion. I also noticed while fixing this issue that autocomplete wasn't working for objects/fields with numbers in them (most importantly web3.) which is also now fixed. --- console/console.go | 8 ++------ internal/jsre/completion.go | 13 ++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/console/console.go b/console/console.go index fde673be8..f72c35072 100644 --- a/console/console.go +++ b/console/console.go @@ -305,12 +305,8 @@ func (c *Console) AutoCompleteInput(line string, pos int) (string, []string, str start := pos - 1 for ; start > 0; start-- { // Skip all methods and namespaces (i.e. including the dot) - if line[start] == '.' || (line[start] >= 'a' && line[start] <= 'z') || (line[start] >= 'A' && line[start] <= 'Z') { - continue - } - // Handle web3 in a special way (i.e. other numbers aren't auto completed) - if start >= 3 && line[start-3:start] == "web3" { - start -= 3 + c := line[start] + if c == '.' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '1' && c <= '9') { continue } // We've hit an unexpected character, autocomplete form here diff --git a/internal/jsre/completion.go b/internal/jsre/completion.go index 538fca298..844a0532f 100644 --- a/internal/jsre/completion.go +++ b/internal/jsre/completion.go @@ -17,12 +17,16 @@ package jsre import ( + "regexp" "sort" "strings" "github.com/dop251/goja" ) +// JS numerical token +var numerical = regexp.MustCompile(`^(NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity))$`) + // CompleteKeywords returns potential continuations for the given line. Since line is // evaluated, callers need to make sure that evaluating line does not have side effects. func (jsre *JSRE) CompleteKeywords(line string) []string { @@ -43,6 +47,9 @@ func getCompletions(vm *goja.Runtime, line string) (results []string) { // and "x.y" is an object, obj will reference "x.y". obj := vm.GlobalObject() for i := 0; i < len(parts)-1; i++ { + if numerical.MatchString(parts[i]) { + return nil + } v := obj.Get(parts[i]) if v == nil || goja.IsNull(v) || goja.IsUndefined(v) { return nil // No object was found @@ -67,7 +74,11 @@ func getCompletions(vm *goja.Runtime, line string) (results []string) { // Append opening parenthesis (for functions) or dot (for objects) // if the line itself is the only completion. if len(results) == 1 && results[0] == line { - obj := obj.Get(parts[len(parts)-1]) + // Accessing the property will cause it to be evaluated. + // This can cause an error, e.g. in case of web3.eth.protocolVersion + // which has been dropped from geth. Ignore the error for autocompletion + // purposes. + obj := SafeGet(obj, parts[len(parts)-1]) if obj != nil { if _, isfunc := goja.AssertFunction(obj); isfunc { results[0] += "("