-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpbdecode.sh
127 lines (124 loc) · 3.23 KB
/
pbdecode.sh
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/bin/sh
#
# Protobuf wire format decoder
# dependency: xxd
TYPE_VARINT=0
TYPE_FIXED64=1
TYPE_BYTES=2
TYPE_FIXED32=5
automata() {
n=
t=
len=0
v=
state=read_tag
delimiter="{"
for b in $@; do
case $state in
read_tag)
printf "$delimiter"
[ "$delimiter" = "{" ] && delimiter=","
n=$((0x$b >> 3))
printf "\"$n\":"
t=$((0x$b & 0x7))
case $t in
$TYPE_VARINT)
v=0x0
state=read_varint_0;;
$TYPE_FIXED64)
buf=
state=read_fixed64_0;;
$TYPE_BYTES)
buf=
v=
len=0x0
state=read_length_0;;
$TYPE_FIXED32)
buf=
state=read_fixed32_0;;
*)
echo "error: invalid field type" >&2
return 1
;;
esac
buf=
;;
read_length_*)
nth=${state#read_length_}
shifts=$(($nth * 7))
num=$(printf "%x" $(((0x$b & 0x7f) << $shifts)))
len=$(($len | 0x$num))
if [ "$((0x$b >> 7))" -eq 0 ]; then
if [ "$len" -gt 0 ]; then
state=read_bytes
else
printf "\"\""
state=read_tag
fi
else
state=read_length_$(($nth + 1))
fi
;;
read_varint_*)
nth=${state#read_varint_}
shifts=$(($nth * 7))
num=$(printf "%x" $(((0x$b & 0x7f) << $shifts)))
v=$(($v | 0x$num))
if [ "$((0x$b >> 7))" -eq 0 ]; then
printf "$v"
state=read_tag
else
state=read_varint_$(($nth + 1))
fi
;;
read_fixed64_*)
nth=${state#read_fixed64_}
buf=$b$buf
if [ "$nth" -eq 7 ]; then
v=$(printf "%d" 0x$buf)
printf "$v"
state=read_tag
else
state=read_fixed64_$(($nth + 1))
fi
;;
read_bytes)
buf="$buf $b"
v=$v$(echo $b | xxd -r -p)
len=$(($len - 1))
if [ "$len" -eq 0 ]; then
buf=$(automata $buf 2>&1)
if [ $? -eq 0 ]; then
printf "$buf"
else
printf "\"$v\""
fi
state=read_tag
fi
;;
read_fixed32_*)
nth=${state#read_fixed32_}
buf=$b$buf
if [ "$nth" -eq 3 ]; then
v=$(printf "%d" 0x$buf)
buf=
printf "$v"
state=read_tag
else
state=read_fixed32_$(($nth + 1))
fi
;;
*)
echo "error: invalid state \"$state\"" >&2
return 1
;;
esac
done
if [ $state != "read_tag" ]; then
echo "error: incomplete protobuf" >&2
return 1
fi
[ "$delimiter" != "{" ] && printf "}"
}
str=$(automata $(xxd -ps -c1))
[ $? -eq 0 ] && echo $str