Skip to content

Commit 20f9cc2

Browse files
committed
fix --detail error
1 parent ca98dad commit 20f9cc2

File tree

6 files changed

+103
-53
lines changed

6 files changed

+103
-53
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ Usage:
1818

1919
Available Commands:
2020
decode encode a string into ascii85(re-map), which tbc file used
21-
disassemble disassemble a .tbc file, which can be on disk/url
21+
decompile disassemble a .tbc file, which can be on disk/url
2222
encode A brief description of your command
2323

2424
Example:
2525
tbcload encode 123456
26-
tbcload disassemble test.tbc #disassemble a file named test.tbc
27-
tbcload disassemble http://127.0.0.1/test.tcl #disassemble from a url
26+
tbcload encode --hex "00010203"
27+
tbcload decompile test.tbc #disassemble a file named test.tbc
28+
tbcload decompile --detail test.tbc
29+
tbcload decompile http://127.0.0.1/test.tcl #disassemble from a url
2830

2931
example url, can be found as https://github.com/ActiveState/teapot/raw/master/lib/tbcload/tests/tbc10/proc.tbc
3032
```

encoding.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ func Encode(dst, src []byte) int {
3737

3838
//step 5 map special char
3939
for index := 0; index < encodeLen; index++ {
40-
dst[index] = encodeMap[dst[index]-'!']
40+
//there is 'z'(122) special for 0x00000000
41+
if n := int(dst[index] - '!'); n < len(encodeMap) {
42+
dst[index] = encodeMap[n]
43+
}
4144
}
42-
43-
return encodeLen - (len(srcCopy) - len(src))
45+
//if 0x00 00 00 00->'z', we cannot known how many '!' drop
46+
return encodeLen
47+
//return encodeLen - (len(srcCopy) - len(src))
4448
}
4549

4650
/*
@@ -61,10 +65,12 @@ func Decode(dst, src []byte) (ndst int) {
6165
srcCopy[index] = decodeMap[src[index]] + '!'
6266
}
6367

64-
//step 1 align to 5 bytes,padding as 0
68+
//step 1 align to 5 bytes,padding as 0 (but not for z)
69+
//no need do this
70+
//BUGBUG, if there is 'z' in middle
6571
srcCopy = align5Bytes(srcCopy, '!')
6672

67-
//step 2 Big-Endian to Little-Endian
73+
//step 2 Big-Endian to Little-Endian(but not for 'z')
6874
exchangeEvery5(srcCopy)
6975

7076
//step 3 ascii85 decode
@@ -241,7 +247,11 @@ func align4Bytes(src []byte, padding byte) []byte {
241247
}
242248

243249
func align5Bytes(src []byte, padding byte) []byte {
244-
switch len(src) % 5 {
250+
//'z' dont need align to 5 bytes
251+
numZ := bytes.Count(src, []byte{'z'})
252+
nLen := len(src) - numZ
253+
254+
switch nLen % 5 {
245255
case 1:
246256
src = append(src, padding)
247257
fallthrough
@@ -272,14 +282,18 @@ func exchangeEvery4(src []byte) {
272282
}
273283
}
274284
func exchangeEvery5(src []byte) {
275-
if len(src)%5 != 0 {
276-
return
277-
}
278-
285+
//special 'z' for 0x00000000, dont exchange 'z'
279286
for len(src) > 0 {
280-
src[0], src[1], src[3], src[4] = src[4], src[3], src[1], src[0]
281-
src = src[5:]
287+
if src[0] == 'z' {
288+
src = src[1:]
289+
} else if len(src) >= 5 {
290+
src[0], src[1], src[3], src[4] = src[4], src[3], src[1], src[0]
291+
src = src[5:]
292+
} else {
293+
return
294+
}
282295
}
296+
return
283297
}
284298

285299
var encodeMap = [...]byte{
@@ -497,7 +511,8 @@ var decodeMap = [...]byte{
497511
3, /* w (replaces $) */
498512
58, /* x (replaces [) */
499513
59, /* y (replaces \) */
500-
a85Z, /* z */
514+
89, /* z->z,special for 0x00000000 */
515+
// a85Z, /* z */
501516
a85IllegalChar, /* { */
502517
60, /* | (replaces ]) */
503518
a85IllegalChar, /* } */

encoding_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ func ExampleChainReader2() {
8484
// 345
8585
}
8686
func ExampleEncode() {
87-
src := []byte("testing aliases for non-existent targets")
87+
//src := []byte("testing aliases for non-existent targets")
88+
src := []byte{0, 0, 0, 0}
8889
dst := make([]byte, 280)
8990
length := Encode(dst, src)
9091
fmt.Printf("%s", dst[:length])
@@ -93,7 +94,8 @@ func ExampleEncode() {
9394
}
9495

9596
func ExampleDecode() {
96-
src := []byte("4;,>!?.EH&ih-(!e2xi6zyiE<!22>:v35>:v22Ppv2j:U!*|yTv0#>6#5cSs!)'!!")
97+
src := []byte("4;,>!?.EH&ih-(!e2xi6zyiE<!22>:v35>:v22Ppv2j:U!*|yTv0#>6#5cSs!)'!")
98+
//src := []byte("z")
9799
dst := make([]byte, 280)
98100
length := Decode(dst, src)
99101
fmt.Printf("%s", string(dst[:length]))

parser.go

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@ import (
88
"errors"
99
"fmt"
1010
"io"
11+
"math"
1112
"os"
1213
"strconv"
1314
"strings"
1415
)
1516

1617
//Parser read tbc file and write 'dissemble' to w
1718
type Parser struct {
18-
r Decoder
19-
w bufio.Writer
20-
Detail bool //true: disassemble bytecode
21-
codeBytes []byte
22-
codeDelta []byte
23-
codeLength []byte
19+
r Decoder
20+
w bufio.Writer
21+
Detail bool //true: disassemble bytecode
22+
23+
codeBytes bytes.Buffer
24+
codeDelta bytes.Buffer
25+
codeLength bytes.Buffer
2426
}
2527

2628
//NewParser create Parser
@@ -276,58 +278,74 @@ func (p *Parser) parseAuxDataArray() (err error) {
276278
func (p *Parser) parseCodeDelta() (err error) {
277279
var buf [20480]byte
278280
var nRead int
279-
if _, err = p.parseIntLine(); err != nil {
281+
var nRes int64
282+
if nRes, err = p.parseIntLine(); err != nil {
280283
return
281284
}
282285
if nRead, err = p.r.Read(buf[:]); err != nil {
283286
return
284287
}
285-
s := hex.EncodeToString(buf[:nRead])
286-
_, err = p.w.WriteString(s)
287-
err = p.w.WriteByte('\n')
288+
p.codeDelta.Reset()
289+
290+
if nRes > 0 && nRead > 0 {
291+
s := hex.EncodeToString(buf[:nRead])
292+
_, err = p.w.WriteString(s)
293+
err = p.w.WriteByte('\n')
288294

289-
if nRead > 0 {
290-
p.codeDelta = make([]byte, nRead)
291-
copy(p.codeDelta, buf[:nRead])
295+
if nRead > int(nRes) {
296+
nRead = int(nRes)
297+
}
298+
p.codeDelta.Write(buf[:nRead])
292299
}
293300
return
294301
}
295302
func (p *Parser) parseCodeLength() (err error) {
296303
var buf [20480]byte
297304
var nRead int
298-
if _, err = p.parseIntLine(); err != nil {
305+
var nRes int64
306+
if nRes, err = p.parseIntLine(); err != nil {
299307
return
300308
}
301309
if nRead, err = p.r.Read(buf[:]); err != nil {
302310
return
303311
}
304-
s := hex.EncodeToString(buf[:nRead])
305-
_, err = p.w.WriteString(s)
306-
err = p.w.WriteByte('\n')
307312

308-
if nRead > 0 {
309-
p.codeLength = make([]byte, nRead)
310-
copy(p.codeLength, buf[:nRead])
313+
p.codeLength.Reset()
314+
315+
if nRes > 0 && nRead > 0 {
316+
s := hex.EncodeToString(buf[:nRead])
317+
_, err = p.w.WriteString(s)
318+
err = p.w.WriteByte('\n')
319+
320+
if nRead > int(nRes) {
321+
nRead = int(nRes)
322+
}
323+
p.codeLength.Write(buf[:nRead])
311324
}
312325
return
313326
}
314327

315328
func (p *Parser) parseCode() (err error) {
316329
var buf [20480]byte
317330
var nRead int
318-
if _, err = p.parseIntLine(); err != nil {
331+
var nRes int64
332+
if nRes, err = p.parseIntLine(); err != nil {
319333
return
320334
}
321335
if nRead, err = p.r.Read(buf[:]); err != nil {
322336
return
323337
}
324-
s := hex.EncodeToString(buf[:nRead])
325-
_, err = p.w.WriteString(s)
326-
err = p.w.WriteByte('\n')
338+
p.codeBytes.Reset()
327339

328-
if nRead > 0 {
329-
p.codeBytes = make([]byte, nRead)
330-
copy(p.codeBytes, buf[:nRead])
340+
if nRes > 0 && nRead > 0 {
341+
s := hex.EncodeToString(buf[:nRead])
342+
_, err = p.w.WriteString(s)
343+
err = p.w.WriteByte('\n')
344+
345+
if nRead > int(nRes) {
346+
nRead = int(nRes)
347+
}
348+
p.codeBytes.Write(buf[:nRead])
331349
}
332350
return
333351
}
@@ -424,9 +442,11 @@ func (p *Parser) parseDecompile() (err error) {
424442
var str string
425443
var bytes int
426444
var totalBytes int
427-
src := p.codeBytes
445+
src := p.codeBytes.Bytes()
446+
codeDelta := p.codeDelta.Bytes()
447+
codeLength := p.codeLength.Bytes()
428448

429-
numCmds := len(p.codeDelta)
449+
numCmds := len(codeDelta)
430450
indexCmds := 0
431451
cmdBegin := true
432452
var cmdBytes, cmdDelta int
@@ -439,7 +459,8 @@ func (p *Parser) parseDecompile() (err error) {
439459
return err
440460
}
441461
//1. print command title: command %d,pc=xx-xx
442-
if numCmds > 0 && indexCmds < (numCmds-1) {
462+
if numCmds > 0 && indexCmds < (numCmds) {
463+
443464
if cmdBegin {
444465
cmdBytes = bytes
445466
cmdBegin = false
@@ -448,14 +469,23 @@ func (p *Parser) parseDecompile() (err error) {
448469

449470
for samePCforCmds {
450471

451-
cmdDelta = int(p.codeDelta[indexCmds+1])
472+
//cmdDelta = int(p.codeDelta[indexCmds+1])
473+
452474
p.w.WriteString(fmt.Sprintf("\tCommand %d", indexCmds))
453-
if indexCmds < len(p.codeLength) {
475+
if indexCmds < len(codeLength) {
454476
//BUG,FIXME, we dont consider codeLength = 0xFF 4bytes case
455-
p.w.WriteString(fmt.Sprintf(",pc= %d-%d", totalBytes, totalBytes+int(p.codeLength[indexCmds])-1))
477+
p.w.WriteString(fmt.Sprintf(",pc= %d-%d", totalBytes, totalBytes+int(codeLength[indexCmds])-1))
456478
}
457479
p.w.WriteByte('\n')
480+
458481
indexCmds++
482+
//cmdDelta 是下一条Command 相对于当前Comand的bytes偏移量
483+
//如果是最后一条命令,cmdDelta赋值MAX
484+
if indexCmds < len(codeDelta) {
485+
cmdDelta = int(codeDelta[indexCmds])
486+
} else {
487+
cmdDelta = math.MaxInt32
488+
}
459489

460490
if cmdDelta != 0 {
461491
samePCforCmds = false

parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func TestParser(t *testing.T) {
7676

7777
func TestSingleFile(t *testing.T) {
7878
//sFile := "D:\\Program Files (x86)\\TclPro1.4\\win32-ix86\\bin\\simple.tbc"
79-
sFile := "d:\\Project\\go\\src\\github.com\\corbamico\\tbcload\\test\\aux1.tbc"
79+
sFile := "c:\\Project\\go\\src\\github.com\\corbamico\\tbcload\\test\\aux1.tbc"
8080
fs, err := os.Open(sFile)
8181
if err != nil {
8282
t.Error(err)

tbcload/cmd/decode.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ For example:
3535
var src []byte
3636

3737
if len(args) == 1 {
38-
dst := make([]byte, len(args[0]))
38+
//if there is 'z' ,length will large than src
39+
dst := make([]byte, len(args[0])*4)
3940

4041
src = []byte(args[0])
4142
if ndst := tbcload.Decode(dst, src); ndst > 0 {

0 commit comments

Comments
 (0)