Fix Windows netstat encoding in agent bridge (#894)
This commit is contained in:
@@ -14,6 +14,7 @@ import copy
|
|||||||
import hashlib
|
import hashlib
|
||||||
import importlib.util
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
|
import locale
|
||||||
import os
|
import os
|
||||||
import queue
|
import queue
|
||||||
import shutil
|
import shutil
|
||||||
@@ -1649,6 +1650,13 @@ def _tcp_endpoint_port(endpoint: str) -> int | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _platform_text_encoding() -> str:
|
||||||
|
getencoding = getattr(locale, "getencoding", None)
|
||||||
|
if callable(getencoding):
|
||||||
|
return getencoding() or "utf-8"
|
||||||
|
return locale.getpreferredencoding(False) or "utf-8"
|
||||||
|
|
||||||
|
|
||||||
def _windows_listening_pids_on_port(port: int) -> list[int]:
|
def _windows_listening_pids_on_port(port: int) -> list[int]:
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
return []
|
return []
|
||||||
@@ -1658,12 +1666,15 @@ def _windows_listening_pids_on_port(port: int) -> list[int]:
|
|||||||
check=False,
|
check=False,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
|
encoding=_platform_text_encoding(),
|
||||||
|
errors="ignore",
|
||||||
timeout=5,
|
timeout=5,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
return []
|
return []
|
||||||
|
stdout = result.stdout or ""
|
||||||
pids: set[int] = set()
|
pids: set[int] = set()
|
||||||
for line in result.stdout.splitlines():
|
for line in stdout.splitlines():
|
||||||
parts = line.strip().split()
|
parts = line.strip().split()
|
||||||
if len(parts) < 5:
|
if len(parts) < 5:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ function tcpEndpointPort(endpoint: string): number | undefined {
|
|||||||
|
|
||||||
function windowsListeningPidsOnPort(port: number): number[] {
|
function windowsListeningPidsOnPort(port: number): number[] {
|
||||||
try {
|
try {
|
||||||
const output = execFileSync('netstat.exe', ['-ano', '-p', 'tcp'], { encoding: 'utf-8', windowsHide: true })
|
const output = execFileSync('netstat.exe', ['-ano', '-p', 'tcp'], { windowsHide: true }).toString('utf8')
|
||||||
const pids = new Set<number>()
|
const pids = new Set<number>()
|
||||||
for (const line of output.split(/\r?\n/)) {
|
for (const line of output.split(/\r?\n/)) {
|
||||||
const parts = line.trim().split(/\s+/)
|
const parts = line.trim().split(/\s+/)
|
||||||
|
|||||||
@@ -234,4 +234,55 @@ print(json.dumps({
|
|||||||
restored_glm: 'shell-glm',
|
restored_glm: 'shell-glm',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('handles Windows netstat output decode failures without crashing', async () => {
|
||||||
|
const result = await runBridgeProbe(`
|
||||||
|
import importlib.util
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
spec = importlib.util.spec_from_file_location("hermes_bridge", os.environ["BRIDGE_PATH"])
|
||||||
|
bridge = importlib.util.module_from_spec(spec)
|
||||||
|
sys.modules["hermes_bridge"] = bridge
|
||||||
|
spec.loader.exec_module(bridge)
|
||||||
|
|
||||||
|
class EmptyStdoutResult:
|
||||||
|
stdout = None
|
||||||
|
|
||||||
|
def fake_run_empty(*args, **kwargs):
|
||||||
|
return EmptyStdoutResult()
|
||||||
|
|
||||||
|
class NetstatResult:
|
||||||
|
stdout = " TCP 127.0.0.1:18765 0.0.0.0:0 LISTENING 4321\\r\\n"
|
||||||
|
|
||||||
|
def fake_run_listener(*args, **kwargs):
|
||||||
|
return NetstatResult()
|
||||||
|
|
||||||
|
original_name = bridge.os.name
|
||||||
|
original_pid = bridge.os.getpid
|
||||||
|
original_run = bridge.subprocess.run
|
||||||
|
try:
|
||||||
|
bridge.os.name = "nt"
|
||||||
|
bridge.os.getpid = lambda: 1234
|
||||||
|
bridge.subprocess.run = fake_run_empty
|
||||||
|
empty = bridge._windows_listening_pids_on_port(18765)
|
||||||
|
bridge.subprocess.run = fake_run_listener
|
||||||
|
listener = bridge._windows_listening_pids_on_port(18765)
|
||||||
|
finally:
|
||||||
|
bridge.os.name = original_name
|
||||||
|
bridge.os.getpid = original_pid
|
||||||
|
bridge.subprocess.run = original_run
|
||||||
|
|
||||||
|
print(json.dumps({
|
||||||
|
"empty": empty,
|
||||||
|
"listener": listener,
|
||||||
|
}))
|
||||||
|
`)
|
||||||
|
|
||||||
|
expect(result).toEqual({
|
||||||
|
empty: [],
|
||||||
|
listener: [4321],
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user