]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: validate result of Float.GobDecode
authorAlexander Yastrebov <yastrebov.alex@gmail.com>
Mon, 23 Jan 2023 16:52:33 +0000 (16:52 +0000)
committerRobert Griesemer <gri@google.com>
Mon, 23 Jan 2023 18:18:05 +0000 (18:18 +0000)
Fixes #57946

Change-Id: Ia499ebfd8801432122f89fdf6bda4d1e7b6dd832
GitHub-Last-Rev: 29e099388680bc5b7075e0fa63499b39697579ca
GitHub-Pull-Request: golang/go#57951
Reviewed-on: https://go-review.googlesource.com/c/go/+/463017
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
src/math/big/float.go
src/math/big/floatmarsh.go
src/math/big/floatmarsh_test.go

index 84666d817bb56943a6739e1ee22f7d12775c8626..2f0635a03b2b8ad13e5715cda05f5eb67d19caf4 100644 (file)
@@ -365,20 +365,27 @@ func (x *Float) validate() {
                // avoid performance bugs
                panic("validate called but debugFloat is not set")
        }
+       if msg := x.validate0(); msg != "" {
+               panic(msg)
+       }
+}
+
+func (x *Float) validate0() string {
        if x.form != finite {
-               return
+               return ""
        }
        m := len(x.mant)
        if m == 0 {
-               panic("nonzero finite number with empty mantissa")
+               return "nonzero finite number with empty mantissa"
        }
        const msb = 1 << (_W - 1)
        if x.mant[m-1]&msb == 0 {
-               panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0)))
+               return fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0))
        }
        if x.prec == 0 {
-               panic("zero precision finite number")
+               return "zero precision finite number"
        }
+       return ""
 }
 
 // round rounds z according to z.mode to z.prec bits and sets z.acc accordingly.
index 990e085abe8d053c4c170dbac474753f63e3dd6a..2a78c69e34aaf8c9c0287198566d814dbcbe32f4 100644 (file)
@@ -99,6 +99,10 @@ func (z *Float) GobDecode(buf []byte) error {
                z.SetPrec(uint(oldPrec))
        }
 
+       if msg := z.validate0(); msg != "" {
+               return errors.New("Float.GobDecode: " + msg)
+       }
+
        return nil
 }
 
index 401f45a51fe7e046f08e13ef76d581701fa7cede..20def68a6d3c613a4ae89362fc8943837195b185 100644 (file)
@@ -9,6 +9,7 @@ import (
        "encoding/gob"
        "encoding/json"
        "io"
+       "strings"
        "testing"
 )
 
@@ -149,3 +150,24 @@ func TestFloatGobDecodeShortBuffer(t *testing.T) {
                }
        }
 }
+
+func TestFloatGobDecodeInvalid(t *testing.T) {
+       for _, tc := range []struct {
+               buf []byte
+               msg string
+       }{
+               {
+                       []byte{0x1, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x0, 0x20, 0x20, 0x20, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc},
+                       "Float.GobDecode: msb not set in last word",
+               },
+               {
+                       []byte{1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+                       "Float.GobDecode: nonzero finite number with empty mantissa",
+               },
+       } {
+               err := NewFloat(0).GobDecode(tc.buf)
+               if err == nil || !strings.HasPrefix(err.Error(), tc.msg) {
+                       t.Errorf("expected GobDecode error prefix: %s, got: %v", tc.msg, err)
+               }
+       }
+}