Repository: mitmproxy/mitmproxy

Issue:
Crash when invoking replay.server.count from console
#### Problem Description
Invoking `replay.server.count` from the console causes a crash. I don't think it happens all the time, but see below for repeatable reproduction.

#### Steps to reproduce the behavior:
1. Start `mitmproxy`
2. Hit `n` to create a new flow
3. Hit Enter
4. Hit `r` to issue the request
5. With the same flow selected, issue the command `:replay.server @focus`
6. Issue the command `:replay.server.count`

Sample stack trace:
```python
  File "/home/elespike/venvs/mitmproxy/lib/python3.9/site-packages/mitmproxy/tools/console/grideditor/editors.py", line 222, in __init__
    if not isinstance(vals[0], list):
TypeError: 'int' object is not subscriptable
```

#### System Information
```
Mitmproxy: 7.0.4
Python:    3.9.2
```


Discussion:

Resolving patch:
diff --git a/mitmproxy/types.py b/mitmproxy/types.py
--- a/mitmproxy/types.py
+++ b/mitmproxy/types.py
@@ -369,7 +369,7 @@ class _FlowType(_BaseFlowType):
 
     def parse(self, manager: "CommandManager", t: type, s: str) -> flow.Flow:
         try:
-            flows = manager.execute("view.flows.resolve %s" % (s))
+            flows = manager.call_strings("view.flows.resolve", [s])
         except exceptions.CommandError as e:
             raise exceptions.TypeError(str(e)) from e
         if len(flows) != 1:
@@ -388,7 +388,7 @@ class _FlowsType(_BaseFlowType):
 
     def parse(self, manager: "CommandManager", t: type, s: str) -> typing.Sequence[flow.Flow]:
         try:
-            return manager.execute("view.flows.resolve %s" % (s))
+            return manager.call_strings("view.flows.resolve", [s])
         except exceptions.CommandError as e:
             raise exceptions.TypeError(str(e)) from e
 


Test patch:
diff --git a/test/mitmproxy/test_types.py b/test/mitmproxy/test_types.py
--- a/test/mitmproxy/test_types.py
+++ b/test/mitmproxy/test_types.py
@@ -183,7 +183,10 @@ class DummyConsole:
     def resolve(self, spec: str) -> typing.Sequence[flow.Flow]:
         if spec == "err":
             raise mitmproxy.exceptions.CommandError()
-        n = int(spec)
+        try:
+            n = int(spec)
+        except ValueError:
+            n = 1
         return [tflow.tflow(resp=True)] * n
 
     @command.command("cut")
@@ -201,6 +204,7 @@ def test_flow():
         b = mitmproxy.types._FlowType()
         assert len(b.completion(tctx.master.commands, flow.Flow, "")) == len(b.valid_prefixes)
         assert b.parse(tctx.master.commands, flow.Flow, "1")
+        assert b.parse(tctx.master.commands, flow.Flow, "has space")
         assert b.is_valid(tctx.master.commands, flow.Flow, tflow.tflow()) is True
         assert b.is_valid(tctx.master.commands, flow.Flow, "xx") is False
         with pytest.raises(mitmproxy.exceptions.TypeError):
@@ -224,6 +228,7 @@ def test_flows():
         assert len(b.parse(tctx.master.commands, typing.Sequence[flow.Flow], "0")) == 0
         assert len(b.parse(tctx.master.commands, typing.Sequence[flow.Flow], "1")) == 1
         assert len(b.parse(tctx.master.commands, typing.Sequence[flow.Flow], "2")) == 2
+        assert len(b.parse(tctx.master.commands, typing.Sequence[flow.Flow], "has space")) == 1
         with pytest.raises(mitmproxy.exceptions.TypeError):
             b.parse(tctx.master.commands, typing.Sequence[flow.Flow], "err")