|
1 | | -import json |
2 | 1 | import os |
3 | 2 | import re |
| 3 | +import shlex |
4 | 4 | import sys |
5 | 5 | from datetime import datetime |
6 | 6 | from io import BytesIO |
@@ -39,54 +39,15 @@ def rpc(tank: str, method: str, params: list[str], namespace: Optional[str]): |
39 | 39 |
|
40 | 40 |
|
41 | 41 | def _rpc(tank: str, method: str, params: list[str], namespace: Optional[str] = None): |
42 | | - # bitcoin-cli should be able to read bitcoin.conf inside the container |
43 | | - # so no extra args like port, chain, username or password are needed |
44 | 42 | namespace = get_default_namespace_or(namespace) |
45 | 43 |
|
46 | 44 | if params: |
47 | | - # Process parameters to ensure proper shell escaping |
48 | | - processed_params = [] |
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 | | - |
57 | | - # Try to parse as JSON to determine how to handle it |
58 | | - try: |
59 | | - parsed_json = json.loads(param) |
60 | | - if isinstance(parsed_json, list): |
61 | | - # For JSON arrays, extract elements for methods that expect individual parameters |
62 | | - # (like getblock, gettransaction, etc.) |
63 | | - # But keep as JSON for methods that expect JSON arrays (like logging) |
64 | | - if method in ["logging", "importdescriptors", "importmulti"]: |
65 | | - # These methods expect JSON arrays as-is |
66 | | - processed_params.append(f"'{param}'") |
67 | | - else: |
68 | | - # For single-parameter methods, only extract the first element |
69 | | - # For multi-parameter methods, extract all elements |
70 | | - if method in ["getblockhash", "getblock", "gettransaction"]: |
71 | | - # These methods expect a single parameter, so only take the first element |
72 | | - if parsed_json: |
73 | | - processed_params.append(str(parsed_json[0])) |
74 | | - else: |
75 | | - # Extract all array elements for other methods |
76 | | - for element in parsed_json: |
77 | | - processed_params.append(str(element)) |
78 | | - else: |
79 | | - # For JSON objects, pass as-is |
80 | | - processed_params.append(f"'{param}'") |
81 | | - except json.JSONDecodeError: |
82 | | - # If it's not valid JSON, pass as-is |
83 | | - processed_params.append(param) |
84 | | - else: |
85 | | - processed_params.append(param) |
86 | | - |
87 | | - cmd = f"kubectl -n {namespace} exec {tank} --container {BITCOINCORE_CONTAINER} -- bitcoin-cli {method} {' '.join(processed_params)}" |
| 45 | + # Shell-escape each param to preserve quotes and special characters |
| 46 | + bitcoin_cli_args = " ".join(shlex.quote(p) for p in params) |
| 47 | + cmd = f"kubectl -n {namespace} exec {tank} --container {BITCOINCORE_CONTAINER} -- bitcoin-cli {method} {bitcoin_cli_args}" |
88 | 48 | else: |
89 | 49 | cmd = f"kubectl -n {namespace} exec {tank} --container {BITCOINCORE_CONTAINER} -- bitcoin-cli {method}" |
| 50 | + |
90 | 51 | return run_command(cmd) |
91 | 52 |
|
92 | 53 |
|
|
0 commit comments