forked from dfinity/ic
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell_safe.py
More file actions
38 lines (30 loc) · 1.06 KB
/
shell_safe.py
File metadata and controls
38 lines (30 loc) · 1.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import base64
import json
from typing import List
from typing import Union
Command = Union[str, List[str]]
def encode(obj: Command) -> str:
"""
Encode a string in a shell-safe way.
The resulting string is a representation of a python value that is:
* json encoded, then
* utf-8 encoded, then
* base64 encoded.
"""
# here we encode the command to a shell-safe value:
# [ "echo", "hello" ] # python ->
# '[ "echo", "hello" ]' # JSON encoded ->
# b'[ "echo", "hello" ]' # JSON encoded, utf-8 encoded bytes ->
# b'WyJlY2hvIiwgImhlbGxvIl0=' # base64 encoded bytes ->
# 'WyJlY2hvIiwgImhlbGxvIl0=' # ascii representation of the encoded bytes
safe = base64.b64encode(json.dumps(obj).encode("utf-8"))
return safe.decode("ascii")
def decode(s: str) -> Command:
"""
Decode a string that was encoded in a shell-safe way.
The string is a representation of a python value that was:
* json encoded, then
* utf-8 encoded, then
* base64 encoded.
"""
return json.loads(base64.b64decode(s.encode("ascii")))