Last active
July 12, 2016 11:19
-
-
Save deoxxa/e1c2b1af3049074fb0d2891093eb80b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/binary" | |
"encoding/hex" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"os" | |
"unicode/utf8" | |
) | |
func decode(input []byte, offset int64, depth int) (int, []string, error) { | |
r := bytes.NewReader(input) | |
var a []string | |
n := 0 | |
for { | |
o, err := r.Seek(0, os.SEEK_CUR) | |
if err != nil { | |
return n, a, err | |
} | |
o += offset | |
i, err := binary.ReadUvarint(r) | |
if err != nil { | |
if err == io.EOF { | |
return n, a, nil | |
} | |
return n, a, err | |
} | |
if i == 0 { | |
return n, a, fmt.Errorf("tag was zero") | |
} | |
t := i & 0x03 | |
k := i >> 3 | |
if k < 0 { | |
return n, a, fmt.Errorf("invalid key %d", k) | |
} | |
if k > 1024 { | |
return n, a, fmt.Errorf("probably invalid key %d", k) | |
} | |
switch t { | |
case 0: | |
v, err := binary.ReadUvarint(r) | |
if err != nil { | |
return n, a, err | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (varint @ %d)", k, t, o)) | |
a = append(a, fmt.Sprintf(" signed: %d", v)) | |
a = append(a, fmt.Sprintf(" unsigned: %d", uint64(v))) | |
case 1: | |
v := make([]byte, 8) | |
if _, err := r.Read(v); err != nil { | |
return n, a, err | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (64bit @ %d): %s", k, t, o, hex.EncodeToString(v))) | |
case 2: | |
l, err := binary.ReadUvarint(r) | |
if err != nil { | |
return n, a, err | |
} | |
if l < 0 { | |
return n, a, fmt.Errorf("invalid length %d", l) | |
} | |
if l > 1024*32 { | |
return n, a, fmt.Errorf("probably invalid length %d", l) | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (length-prefix @ %d): %d", k, t, o, l)) | |
o, err = r.Seek(0, os.SEEK_CUR) | |
if err != nil { | |
return n, a, err | |
} | |
o += offset | |
v := make([]byte, l) | |
if j, err := r.Read(v); err != nil && err != io.EOF { | |
return n, a, err | |
} else if j < len(v) { | |
return n, a, fmt.Errorf("couldn't read enough data") | |
} | |
_, ma, merr := decode(v, o, depth+1) | |
if merr == nil { | |
for _, s := range ma { | |
a = append(a, " "+s) | |
} | |
} else { | |
if utf8.ValidString(string(v)) { | |
a = append(a, fmt.Sprintf(" %q", string(v))) | |
} else { | |
a = append(a, fmt.Sprintf(" %s", hex.EncodeToString(v))) | |
} | |
} | |
case 5: | |
v := make([]byte, 4) | |
if _, err := r.Read(v); err != nil { | |
return n, a, err | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (32bit @ %d): %s", k, t, o, hex.EncodeToString(v))) | |
default: | |
return n, a, fmt.Errorf("invalid type %d @ %d", t, o) | |
} | |
n++ | |
} | |
} | |
func main() { | |
for _, f := range os.Args[1:] { | |
fmt.Printf("parsing %s\n", f) | |
d, err := ioutil.ReadFile(f) | |
if err != nil { | |
panic(err) | |
} | |
n, lines, err := decode(d, 0, 0) | |
if n > 0 && err == nil { | |
fmt.Printf("decoded %d fields\n", n) | |
if err != nil { | |
fmt.Printf("error was %s\n", err.Error()) | |
} | |
fmt.Printf("\n") | |
for _, l := range lines { | |
fmt.Printf(" %s\n", l) | |
} | |
fmt.Printf("\n") | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/binary" | |
"encoding/hex" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"os" | |
"unicode/utf8" | |
) | |
func decode(input []byte, offset int64, depth int) (int, []string, error) { | |
r := bytes.NewReader(input) | |
var a []string | |
n := 0 | |
for { | |
o, err := r.Seek(0, os.SEEK_CUR) | |
if err != nil { | |
return n, a, err | |
} | |
o += offset | |
i, err := binary.ReadUvarint(r) | |
if err != nil { | |
if err == io.EOF { | |
return n, a, nil | |
} | |
return n, a, err | |
} | |
if i == 0 { | |
return n, a, fmt.Errorf("tag was zero") | |
} | |
t := i & 0x03 | |
k := i >> 3 | |
if k < 0 { | |
return n, a, fmt.Errorf("invalid key %d", k) | |
} | |
if k > 1024 { | |
return n, a, fmt.Errorf("probably invalid key %d", k) | |
} | |
switch t { | |
case 0: | |
v, err := binary.ReadUvarint(r) | |
if err != nil { | |
return n, a, err | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (varint @ %d)", k, t, o)) | |
a = append(a, fmt.Sprintf(" signed: %d", v)) | |
a = append(a, fmt.Sprintf(" unsigned: %d", uint64(v))) | |
case 1: | |
v := make([]byte, 8) | |
if _, err := r.Read(v); err != nil { | |
return n, a, err | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (64bit @ %d): %s", k, t, o, hex.EncodeToString(v))) | |
{ | |
var fbe float64 | |
if err := binary.Read(bytes.NewReader(v), binary.BigEndian, &fbe); err == nil { | |
a = append(a, fmt.Sprintf(" (doublebe) %f", fbe)) | |
} | |
var fle float64 | |
if err := binary.Read(bytes.NewReader(v), binary.LittleEndian, &fle); err == nil { | |
a = append(a, fmt.Sprintf(" (doublele) %f", fle)) | |
} | |
var slbe int64 | |
if err := binary.Read(bytes.NewReader(v), binary.BigEndian, &slbe); err == nil { | |
a = append(a, fmt.Sprintf(" (int64be) %d", slbe)) | |
} | |
var slle int64 | |
if err := binary.Read(bytes.NewReader(v), binary.LittleEndian, &slle); err == nil { | |
a = append(a, fmt.Sprintf(" (int64le) %d", slle)) | |
} | |
var ulbe uint64 | |
if err := binary.Read(bytes.NewReader(v), binary.BigEndian, &ulbe); err == nil { | |
a = append(a, fmt.Sprintf(" (uint64be) %d", ulbe)) | |
} | |
var ulle uint64 | |
if err := binary.Read(bytes.NewReader(v), binary.LittleEndian, &ulle); err == nil { | |
a = append(a, fmt.Sprintf(" (uint64le) %d", ulle)) | |
} | |
} | |
case 2: | |
l, err := binary.ReadUvarint(r) | |
if err != nil { | |
return n, a, err | |
} | |
if l < 0 { | |
return n, a, fmt.Errorf("invalid length %d", l) | |
} | |
if l > 1024*32 { | |
return n, a, fmt.Errorf("probably invalid length %d", l) | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (length-prefix @ %d): %d", k, t, o, l)) | |
o, err = r.Seek(0, os.SEEK_CUR) | |
if err != nil { | |
return n, a, err | |
} | |
o += offset | |
v := make([]byte, l) | |
if j, err := r.Read(v); err != nil && err != io.EOF { | |
return n, a, err | |
} else if j < len(v) { | |
return n, a, fmt.Errorf("couldn't read enough data") | |
} | |
_, ma, merr := decode(v, o, depth+1) | |
if merr == nil { | |
for _, s := range ma { | |
a = append(a, " "+s) | |
} | |
} else { | |
if utf8.ValidString(string(v)) { | |
a = append(a, fmt.Sprintf(" %q", string(v))) | |
} else { | |
a = append(a, fmt.Sprintf(" %s", hex.EncodeToString(v))) | |
} | |
} | |
case 5: | |
v := make([]byte, 4) | |
if _, err := r.Read(v); err != nil { | |
return n, a, err | |
} | |
a = append(a, fmt.Sprintf("[%d] %d (32bit @ %d): %s", k, t, o, hex.EncodeToString(v))) | |
{ | |
var fbe float32 | |
if err := binary.Read(bytes.NewReader(v), binary.BigEndian, &fbe); err == nil { | |
a = append(a, fmt.Sprintf(" (floatbe) %f", fbe)) | |
} | |
var fle float32 | |
if err := binary.Read(bytes.NewReader(v), binary.LittleEndian, &fle); err == nil { | |
a = append(a, fmt.Sprintf(" (floatle) %f", fle)) | |
} | |
var slbe int32 | |
if err := binary.Read(bytes.NewReader(v), binary.BigEndian, &slbe); err == nil { | |
a = append(a, fmt.Sprintf(" (int32be) %d", slbe)) | |
} | |
var slle int32 | |
if err := binary.Read(bytes.NewReader(v), binary.LittleEndian, &slle); err == nil { | |
a = append(a, fmt.Sprintf(" (int32le) %d", slle)) | |
} | |
var ulbe uint32 | |
if err := binary.Read(bytes.NewReader(v), binary.BigEndian, &ulbe); err == nil { | |
a = append(a, fmt.Sprintf(" (uin324be) %d", ulbe)) | |
} | |
var ulle uint32 | |
if err := binary.Read(bytes.NewReader(v), binary.LittleEndian, &ulle); err == nil { | |
a = append(a, fmt.Sprintf(" (uin324le) %d", ulle)) | |
} | |
} | |
default: | |
return n, a, fmt.Errorf("invalid type %d @ %d", t, o) | |
} | |
n++ | |
} | |
} | |
func main() { | |
for _, f := range os.Args[1:] { | |
fmt.Printf("parsing %s\n", f) | |
d, err := ioutil.ReadFile(f) | |
if err != nil { | |
panic(err) | |
} | |
n, lines, err := decode(d, 0, 0) | |
if n > 0 && err == nil { | |
fmt.Printf("decoded %d fields\n", n) | |
if err != nil { | |
fmt.Printf("error was %s\n", err.Error()) | |
} | |
fmt.Printf("\n") | |
for _, l := range lines { | |
fmt.Printf(" %s\n", l) | |
} | |
fmt.Printf("\n") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment