From e9d73c6faa63ab5be9782bc1e206d5acff98659d Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Thu, 31 Oct 2024 10:43:10 -0700 Subject: [PATCH] server: do not serialize python nan in rpc protocol. This causes protocol failure and plugin to be killed. Javascript behavior is to convert NaN to null. Mimicing this behavior ensures stability though all JSON dicts are recursively inspected. --- server/python/rpc_reader.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/server/python/rpc_reader.py b/server/python/rpc_reader.py index 36edc829f..6fca24822 100644 --- a/server/python/rpc_reader.py +++ b/server/python/rpc_reader.py @@ -12,7 +12,23 @@ import multiprocessing.connection import rpc import concurrent.futures import json +import math +def convert_nan_inf_to_none(obj): + if isinstance(obj, dict): + return {key: convert_nan_inf_to_none(value) for key, value in obj.items()} + elif isinstance(obj, list): + return [convert_nan_inf_to_none(item) for item in obj] + elif isinstance(obj, float): + if math.isnan(obj): + return None + if math.isinf(obj): + return None + return obj + +def json_dumps_clean(obj, **kwargs): + cleaned_obj = convert_nan_inf_to_none(obj) + return json.dumps(cleaned_obj, **kwargs) class BufferSerializer(rpc.RpcSerializer): def serialize(self, value, serializationContext): @@ -94,7 +110,7 @@ class RpcFileTransport(RpcTransport): reject(e) def writeJSON(self, j, reject): - return self.writeMessage(0, bytes(json.dumps(j), 'utf8'), reject) + return self.writeMessage(0, bytes(json_dumps_clean(j), 'utf8'), reject) def writeBuffer(self, buffer, reject): return self.writeMessage(1, buffer, reject) @@ -128,7 +144,7 @@ class RpcStreamTransport(RpcTransport): reject(e) def writeJSON(self, j, reject): - return self.writeMessage(0, bytes(json.dumps(j), 'utf8'), reject) + return self.writeMessage(0, bytes(json_dumps_clean(j), 'utf8'), reject) def writeBuffer(self, buffer, reject): return self.writeMessage(1, buffer, reject)