@@ -43,44 +43,22 @@ def _rpc(tank: str, method: str, params: list[str], namespace: Optional[str] = N
4343 # so no extra args like port, chain, username or password are needed
4444 namespace = get_default_namespace_or (namespace )
4545
46- # Reconstruct JSON parameters that may have been split by shell parsing
47- # This fixes issues where JSON arrays like ["network"] get split into separate arguments
48- reconstructed_params = _reconstruct_json_params (params )
49-
50- if reconstructed_params :
51- # Process each parameter to handle different data types correctly for bitcoin-cli
46+ if params :
47+ # Process parameters to ensure proper shell escaping
5248 processed_params = []
53- for param in reconstructed_params :
54- # Handle boolean and primitive values that should not be quoted
55- if param .lower () in ["true" , "false" , "null" ]:
56- processed_params .append (param .lower ())
57- elif param .isdigit () or (param .startswith ("-" ) and param [1 :].isdigit ()):
58- # Numeric values (integers, negative numbers)
59- processed_params .append (param )
49+ for param in params :
50+ # If the parameter looks like JSON (starts with [ or {), fix malformed patterns
51+ if param .startswith ("[" ) or param .startswith ("{" ):
52+ # Fix common malformed JSON patterns
53+ if '\\ "' in param :
54+ # Convert [\"value\"] to ["value"]
55+ param = param .replace ('\\ "' , '"' )
56+ # Wrap JSON in single quotes to preserve it as a single argument
57+ processed_params .append (f"'{ param } '" )
6058 else :
61- try :
62- # Try to parse as JSON to handle complex data structures
63- parsed_json = json .loads (param )
64- if isinstance (parsed_json , list ):
65- # If it's a list, extract the elements and add them individually
66- # This ensures bitcoin-cli receives each list element as a separate argument
67- for element in parsed_json :
68- if isinstance (element , str ):
69- processed_params .append (f'"{ element } "' )
70- else :
71- processed_params .append (str (element ))
72- elif isinstance (parsed_json , dict ):
73- # If it's a dict, pass it as a single JSON argument
74- # bitcoin-cli expects objects to be passed as JSON strings
75- processed_params .append (param )
76- else :
77- # If it's a primitive value (number, boolean), pass it as-is
78- processed_params .append (str (parsed_json ))
79- except json .JSONDecodeError :
80- # Not valid JSON, pass as-is (treat as plain string)
81- processed_params .append (param )
82-
83- cmd = f"kubectl -n { namespace } exec { tank } --container { BITCOINCORE_CONTAINER } -- bitcoin-cli { method } { ' ' .join (map (str , processed_params ))} "
59+ processed_params .append (param )
60+
61+ cmd = f"kubectl -n { namespace } exec { tank } --container { BITCOINCORE_CONTAINER } -- bitcoin-cli { method } { ' ' .join (processed_params )} "
8462 else :
8563 cmd = f"kubectl -n { namespace } exec { tank } --container { BITCOINCORE_CONTAINER } -- bitcoin-cli { method } "
8664 return run_command (cmd )
@@ -384,96 +362,3 @@ def to_jsonable(obj: str):
384362 return obj .hex ()
385363 else :
386364 return obj
387-
388-
389- def _reconstruct_json_params (params : list [str ]) -> list [str ]:
390- """
391- Reconstruct JSON parameters that may have been split by shell parsing.
392-
393- This function detects when parameters look like they should be JSON and
394- reconstructs them properly. For example:
395- - ['[network]'] -> ['["network"]']
396- - ['[network,', 'message_type]'] -> ['["network", "message_type"]']
397- - ['[{"key":', '"value"}]'] -> ['[{"key": "value"}]']
398-
399- This fixes the issue described in GitHub issue #714 where shell parsing
400- breaks JSON parameters into separate arguments.
401- """
402- if not params :
403- return params
404-
405- reconstructed = []
406- i = 0
407-
408- while i < len (params ):
409- param = params [i ]
410-
411- # Check if this looks like the start of a JSON array or object
412- # that was split across multiple arguments by shell parsing
413- if (param .startswith ("[" ) and not param .endswith ("]" )) or (
414- param .startswith ("{" ) and not param .endswith ("}" )
415- ):
416- # This is the start of a JSON structure, collect all parts
417- json_parts = [param ]
418- i += 1
419-
420- # Collect all parts until we find the closing bracket/brace
421- while i < len (params ):
422- next_param = params [i ]
423- json_parts .append (next_param )
424-
425- if (param .startswith ("[" ) and next_param .endswith ("]" )) or (
426- param .startswith ("{" ) and next_param .endswith ("}" )
427- ):
428- break
429- i += 1
430-
431- # Reconstruct the JSON string by joining all parts
432- json_str = " " .join (json_parts )
433-
434- # Validate that it's valid JSON before adding
435- try :
436- json .loads (json_str )
437- reconstructed .append (json_str )
438- except json .JSONDecodeError :
439- # If it's not valid JSON, add parts as separate parameters
440- # This preserves the original behavior for non-JSON arguments
441- reconstructed .extend (json_parts )
442-
443- elif param .startswith ("[" ) and param .endswith ("]" ):
444- # Single parameter that looks like JSON array
445- # Check if it's missing quotes around string elements
446- if "[" in param and "]" in param and '"' not in param :
447- # This looks like [value] without quotes, try to add them
448- inner_content = param [1 :- 1 ] # Remove brackets
449- if "," in inner_content :
450- # Multiple values: [val1, val2] -> ["val1", "val2"]
451- values = [v .strip () for v in inner_content .split ("," )]
452- quoted_values = [f'"{ v } "' for v in values ]
453- reconstructed_param = f"[{ ', ' .join (quoted_values )} ]"
454- else :
455- # Single value: [value] -> ["value"]
456- reconstructed_param = f'["{ inner_content .strip ()} "]'
457-
458- # Validate the reconstructed JSON
459- try :
460- json .loads (reconstructed_param )
461- reconstructed .append (reconstructed_param )
462- except json .JSONDecodeError :
463- # If reconstruction fails, keep original parameter
464- reconstructed .append (param )
465- else :
466- # Already has quotes or is not a string array
467- try :
468- json .loads (param )
469- reconstructed .append (param )
470- except json .JSONDecodeError :
471- reconstructed .append (param )
472-
473- else :
474- # Regular parameter, add as-is
475- reconstructed .append (param )
476-
477- i += 1
478-
479- return reconstructed
0 commit comments