Skip to content

Commit 871454a

Browse files
fix(api): sanitize GET /instruments output to ensure JSON-encodable (bytes->str, containers deep) and robust IDN handling
Co-authored-by: openhands <openhands@all-hands.dev>
1 parent 32d2d16 commit 871454a

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

  • benchmesh-serial-service/src/benchmesh_service

benchmesh-serial-service/src/benchmesh_service/api.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,26 @@ def _load_valid_classes() -> set[str]:
5050
return _valid_classes
5151

5252

53+
54+
def _json_sanitize(obj: Any) -> Any:
55+
if obj is None or isinstance(obj, (str, int, float, bool)):
56+
return obj
57+
if isinstance(obj, (bytes, bytearray)):
58+
try:
59+
return obj.decode('utf-8', errors='ignore')
60+
except Exception:
61+
return str(obj)
62+
if isinstance(obj, dict):
63+
return {str(k): _json_sanitize(v) for k, v in obj.items()}
64+
if isinstance(obj, (list, tuple, set)):
65+
return [_json_sanitize(x) for x in obj]
66+
# Fallback
67+
try:
68+
return str(obj)
69+
except Exception:
70+
return repr(obj)
71+
72+
5373
def _start_frontend_dev_if_available():
5474
"""
5575
Try to start the Vite dev server for the React UI. This is best-effort and will
@@ -172,7 +192,15 @@ def list_instruments():
172192
entry: Dict[str, Any] = {"id": dev_id}
173193
reg_data = registry.get(dev_id, {})
174194
if 'IDN' in reg_data:
175-
entry['IDN'] = reg_data['IDN']
195+
idn_val = reg_data['IDN']
196+
try:
197+
if isinstance(idn_val, (bytes, bytearray)):
198+
entry['IDN'] = idn_val.decode('utf-8', errors='ignore').strip()
199+
else:
200+
entry['IDN'] = str(idn_val)
201+
except Exception:
202+
# Fallback to repr to ensure JSON-serializable
203+
entry['IDN'] = repr(idn_val)
176204

177205
# Attempt to populate classes/channels from manifest based on device driver and model
178206
try:
@@ -229,7 +257,7 @@ def list_instruments():
229257
entry['classes'] = classes_list
230258

231259
items.append(entry)
232-
return items
260+
return _json_sanitize(items)
233261

234262

235263
@app.get("/instruments/{klass}/{device_id}", summary="Get manifest features for class on device", response_model=dict)

0 commit comments

Comments
 (0)