From 212a4c6da7de714f06d9aa5a6c90e575f2667716 Mon Sep 17 00:00:00 2001 From: Yahor Yuzefovich Date: Mon, 23 Mar 2026 16:22:04 -0700 Subject: [PATCH] Fix nil panic in NumDigits for large negative numbers Variable shadowing bug caused nil pointer dereference when computing digit count for negative BigInts exceeding 128 bits. Fixes https://github.com/cockroachdb/cockroach/issues/165525 Co-Authored-By: roachdev-claude --- table.go | 3 ++- table_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/table.go b/table.go index d23dbd7..9a48750 100644 --- a/table.go +++ b/table.go @@ -52,6 +52,7 @@ func init() { } // NumDigits returns the number of decimal digits of d.Coeff. +// //gcassert:inline func (d *Decimal) NumDigits() int64 { return NumDigits(&d.Coeff) @@ -94,7 +95,7 @@ func NumDigits(b *BigInt) int64 { var a *BigInt if b.Sign() < 0 { var tmpA BigInt - a := &tmpA + a = &tmpA a.Abs(b) } else { a = b diff --git a/table_test.go b/table_test.go index 36fd193..16abf77 100644 --- a/table_test.go +++ b/table_test.go @@ -171,3 +171,30 @@ func TestTableExp10(t *testing.T) { } } } + +// TestNumDigitsLargeNegative is a regression test for a bug where NumDigits +// would panic with a nil pointer dereference when processing large negative +// numbers (more than 128 bits). Seen in +// https://github.com/cockroachdb/cockroach/issues/165525. +func TestNumDigitsLargeNegative(t *testing.T) { + // Create a BigInt directly with more than 128 bits. + var b BigInt + b.SetInt64(2) + exp := NewBigInt(200) + b.Exp(&b, exp, nil) + b.Neg(&b) + + numDigits := NumDigits(&b) + // 2^200 has 61 decimal digits. + expectedDigits := int64(61) + if numDigits != expectedDigits { + t.Errorf("expected %d digits, got %d", expectedDigits, numDigits) + } + + // Also test via Decimal. + d := NewWithBigInt(&b, 0) + numDigits2 := d.NumDigits() + if numDigits2 != expectedDigits { + t.Errorf("expected %d digits via Decimal, got %d", expectedDigits, numDigits2) + } +}