From 3ce660a2cf7a003f3c2839215a7e326fb9c93943 Mon Sep 17 00:00:00 2001 From: Mattias Wadman Date: Tue, 3 May 2022 10:05:02 +0200 Subject: [PATCH] decode: Keep decode tree on RangeFn error --- format/asn1/testdata/tc15.ber.fqtest | 8 +++++- format/asn1/testdata/tc16.ber.fqtest | 8 +++++- format/asn1/testdata/tc17.ber.fqtest | 8 +++++- format/asn1/testdata/tc33.ber.fqtest | 3 +- format/asn1/testdata/tc39.ber.fqtest | 1 + format/asn1/testdata/tc42.ber.fqtest | 14 +++++++++- format/asn1/testdata/tc45.ber.fqtest | 1 + format/asn1/testdata/tc47.ber.fqtest | 15 +++++++++- format/asn1/testdata/tc48.ber.fqtest | 23 ++++++++++++++- pkg/decode/decode.go | 42 ++++------------------------ 10 files changed, 80 insertions(+), 43 deletions(-) diff --git a/format/asn1/testdata/tc15.ber.fqtest b/format/asn1/testdata/tc15.ber.fqtest index 018b00a6f..fb212f150 100644 --- a/format/asn1/testdata/tc15.ber.fqtest +++ b/format/asn1/testdata/tc15.ber.fqtest @@ -5,4 +5,10 @@ $ fq -d asn1_ber d tc15.ber 0x0|09 |. | form: "primitive" (0) 0x0|09 |. | tag: "real" (0x9) 0x0| 0c | . | length: 12 -0x0| 83 09 7f ff ff ff ff ff ff ff fb 05| | ............| | unknown0: raw bits +0x0| 83 | . | binary_encoding: true +0x0| 83 | . | sign: 1 (false) +0x0| 83 | . | base: 2 (0) +0x0| 83 | . | scale: 0 +0x0| 83 | . | format: 3 +0x0| 09 | . | exp_bytes: 9 +0x0| 7f ff ff ff ff ff ff ff fb 05| | ..........| | unknown0: raw bits diff --git a/format/asn1/testdata/tc16.ber.fqtest b/format/asn1/testdata/tc16.ber.fqtest index 0dae94d0e..425645495 100644 --- a/format/asn1/testdata/tc16.ber.fqtest +++ b/format/asn1/testdata/tc16.ber.fqtest @@ -5,4 +5,10 @@ $ fq -d asn1_ber d tc16.ber 0x0|09 |. | form: "primitive" (0) 0x0|09 |. | tag: "real" (0x9) 0x0| 0c | . | length: 12 -0x0| 80 fb 05 05 05 05 05 05 05 05 05 05| | ............| | unknown0: raw bits +0x0| 80 | . | binary_encoding: true +0x0| 80 | . | sign: 1 (false) +0x0| 80 | . | base: 2 (0) +0x0| 80 | . | scale: 0 +0x0| 80 | . | format: 0 +0x0| fb | . | exp: -5 +0x0| 05 05 05 05 05 05 05 05 05 05| | ..........| | unknown0: raw bits diff --git a/format/asn1/testdata/tc17.ber.fqtest b/format/asn1/testdata/tc17.ber.fqtest index d2eb82942..38bcc53e6 100644 --- a/format/asn1/testdata/tc17.ber.fqtest +++ b/format/asn1/testdata/tc17.ber.fqtest @@ -5,5 +5,11 @@ $ fq -d asn1_ber d tc17.ber 0x00|09 |. | form: "primitive" (0) 0x00|09 |. | tag: "real" (0x9) 0x00| 14 | . | length: 20 -0x00| af 09 fe ff ff ff ff ff ff ff ff 05 05 05| ..............| unknown0: raw bits +0x00| af | . | binary_encoding: true +0x00| af | . | sign: 1 (false) +0x00| af | . | base: 16 (2) +0x00| af | . | scale: 3 +0x00| af | . | format: 3 +0x00| 09 | . | exp_bytes: 9 +0x00| fe ff ff ff ff ff ff ff ff 05 05 05| ............| unknown0: raw bits 0x10|05 05 05 05 05 05| |......| | diff --git a/format/asn1/testdata/tc33.ber.fqtest b/format/asn1/testdata/tc33.ber.fqtest index 4d191ca21..1ed337310 100644 --- a/format/asn1/testdata/tc33.ber.fqtest +++ b/format/asn1/testdata/tc33.ber.fqtest @@ -5,4 +5,5 @@ $ fq -d asn1_ber d tc33.ber 0x0|03 |. | form: "primitive" (0) 0x0|03 |. | tag: "bit_string" (0x3) 0x0| 02 | . | length: 2 -0x0| 0f 0f| | ..| | unknown0: raw bits +0x0| 0f | . | unused_bits_count: 15 +0x0| 0f| | .| | unknown0: raw bits diff --git a/format/asn1/testdata/tc39.ber.fqtest b/format/asn1/testdata/tc39.ber.fqtest index d33793d83..e60924b2c 100644 --- a/format/asn1/testdata/tc39.ber.fqtest +++ b/format/asn1/testdata/tc39.ber.fqtest @@ -5,3 +5,4 @@ $ fq -d asn1_ber d tc39.ber 0x0|23 |# | form: "constructed" (1) 0x0|23 |# | tag: "bit_string" (0x3) 0x0| 00| | .| | length: "indefinite" (0) + | | | constructed[0:0]: diff --git a/format/asn1/testdata/tc42.ber.fqtest b/format/asn1/testdata/tc42.ber.fqtest index bf1febfa5..5fd70cc5c 100644 --- a/format/asn1/testdata/tc42.ber.fqtest +++ b/format/asn1/testdata/tc42.ber.fqtest @@ -5,4 +5,16 @@ $ fq -d asn1_ber d tc42.ber 0x0|24 |$ | form: "constructed" (1) 0x0|24 |$ | tag: "octet_string" (0x4) 0x0| 80 | . | length: "indefinite" (0) -0x0| 04 03 00 04 05 04 5f 29 1c d0 00 00| | ......_)....| | unknown0: raw bits + | | | constructed[0:2]: + | | | [0]{}: object +0x0| 04 | . | class: "universal" (0) +0x0| 04 | . | form: "primitive" (0) +0x0| 04 | . | tag: "octet_string" (0x4) +0x0| 03 | . | length: 3 +0x0| 00 04 05 | ... | value: raw bits + | | | [1]{}: object +0x0| 04 | . | class: "universal" (0) +0x0| 04 | . | form: "primitive" (0) +0x0| 04 | . | tag: "octet_string" (0x4) +0x0| 5f | _ | length: 95 +0x0| 29 1c d0 00 00| | )....| | unknown0: raw bits diff --git a/format/asn1/testdata/tc45.ber.fqtest b/format/asn1/testdata/tc45.ber.fqtest index 9d4d2e356..66ba0baed 100644 --- a/format/asn1/testdata/tc45.ber.fqtest +++ b/format/asn1/testdata/tc45.ber.fqtest @@ -6,3 +6,4 @@ $ fq -d asn1_ber d tc45.ber 0x0|24 |$ | form: "constructed" (1) 0x0|24 |$ | tag: "octet_string" (0x4) 0x0| 00| | .| | length: "indefinite" (0) + | | | constructed[0:0]: diff --git a/format/asn1/testdata/tc47.ber.fqtest b/format/asn1/testdata/tc47.ber.fqtest index 4bd1fc2f2..99d4b41ec 100644 --- a/format/asn1/testdata/tc47.ber.fqtest +++ b/format/asn1/testdata/tc47.ber.fqtest @@ -5,4 +5,17 @@ $ fq -d asn1_ber d tc47.ber 0x00|23 |# | form: "constructed" (1) 0x00|23 |# | tag: "bit_string" (0x3) 0x00| 0e | . | length: 14 -0x00| 03 02 00 01 00 00 03 02 00 01 03 02 04 0f| ..............| unknown0: raw bits + | | | constructed[0:2]: + | | | [0]{}: object +0x00| 03 | . | class: "universal" (0) +0x00| 03 | . | form: "primitive" (0) +0x00| 03 | . | tag: "bit_string" (0x3) +0x00| 02 | . | length: 2 +0x00| 00 | . | unused_bits_count: 0 +0x00| 01 | . | value: raw bits + | | | [1]{}: object +0x00| 00 | . | class: "universal" (0) +0x00| 00 | . | form: "primitive" (0) +0x00| 00 | . | tag: "end_of_content" (0x0) +0x00| 00 | . | length: "indefinite" (0) +0x00| 03 02 00 01 03 02 04 0f| ........| unknown0: raw bits diff --git a/format/asn1/testdata/tc48.ber.fqtest b/format/asn1/testdata/tc48.ber.fqtest index b5ca91d8a..b47537665 100644 --- a/format/asn1/testdata/tc48.ber.fqtest +++ b/format/asn1/testdata/tc48.ber.fqtest @@ -5,4 +5,25 @@ $ fq -d asn1_ber d tc48.ber 0x00|23 |# | form: "constructed" (1) 0x00|23 |# | tag: "bit_string" (0x3) 0x00| 80 | . | length: "indefinite" (0) -0x00| 03 02 00 01 03 02 00 01 03 02 0f 0f 00 00| ..............| unknown0: raw bits + | | | constructed[0:3]: + | | | [0]{}: object +0x00| 03 | . | class: "universal" (0) +0x00| 03 | . | form: "primitive" (0) +0x00| 03 | . | tag: "bit_string" (0x3) +0x00| 02 | . | length: 2 +0x00| 00 | . | unused_bits_count: 0 +0x00| 01 | . | value: raw bits + | | | [1]{}: object +0x00| 03 | . | class: "universal" (0) +0x00| 03 | . | form: "primitive" (0) +0x00| 03 | . | tag: "bit_string" (0x3) +0x00| 02 | . | length: 2 +0x00| 00 | . | unused_bits_count: 0 +0x00| 01 | . | value: raw bits + | | | [2]{}: object +0x00| 03 | . | class: "universal" (0) +0x00| 03 | . | form: "primitive" (0) +0x00| 03 | . | tag: "bit_string" (0x3) +0x00| 02 | . | length: 2 +0x00| 0f | . | unused_bits_count: 15 +0x00| 0f 00 00| ...| unknown0: raw bits diff --git a/pkg/decode/decode.go b/pkg/decode/decode.go index ba17e90b4..c7a074821 100644 --- a/pkg/decode/decode.go +++ b/pkg/decode/decode.go @@ -9,7 +9,6 @@ import ( "math/big" "github.com/wader/fq/internal/bitioextra" - "github.com/wader/fq/internal/mathextra" "github.com/wader/fq/internal/recoverfn" "github.com/wader/fq/pkg/bitio" "github.com/wader/fq/pkg/ranges" @@ -877,49 +876,20 @@ func (d *D) LimitedFn(nBits int64, fn func(d *D)) int64 { // RangeFn decode from current position nBits forward. Position will not be changed. func (d *D) RangeFn(firstBit int64, nBits int64, fn func(d *D)) int64 { - var subV interface{} - switch vv := d.Value.V.(type) { - case *Compound: - subV = &Compound{IsArray: vv.IsArray} - default: - panic("unreachable") - } - if nBits < 0 { - nBits = d.Len() - firstBit - } + startPos := d.Pos() // TODO: do some kind of DecodeLimitedLen/RangeFn? br := d.BitBufRange(0, firstBit+nBits) if _, err := br.SeekBits(firstBit, io.SeekStart); err != nil { d.IOPanic(err, "RangeFn: SeekAbs") } - sd := d.FieldDecoder("", br, subV) - - startPos := d.Pos() - endPos := startPos - - fn(sd) - - // TODO: refactor, similar to decode() - if err := sd.Value.WalkRootPreOrder(func(v *Value, rootV *Value, depth int, rootDepth int) error { - //v.Range.Start += firstBit - v.RootReader = d.Value.RootReader - endPos = mathextra.MaxInt64(endPos, v.Range.Stop()) - - return nil - }); err != nil { - panic(err) - } - switch vv := sd.Value.V.(type) { - case *Compound: - for _, f := range vv.Children { - d.AddChild(f) - } - default: - panic("unreachable") - } + pbr := d.bitBuf + d.bitBuf = br + fn(d) + endPos := d.Pos() + d.bitBuf = pbr return endPos - startPos }