Skip to content

fix(bigint): treat empty octets as zero in BigInt::from_octets - #4115

Merged
bobzhang merged 2 commits into
mainfrom
hongbo/from_octets_empty_zero
Aug 20, 2026
Merged

fix(bigint): treat empty octets as zero in BigInt::from_octets#4115
bobzhang merged 2 commits into
mainfrom
hongbo/from_octets_empty_zero

Conversation

@bobzhang

Copy link
Copy Markdown
Contributor

Summary

Follow mainstream bigint behavior by treating an empty octet sequence as zero in BigInt::from_octets, instead of panicking when signum != 0.

An empty big-endian magnitude naturally denotes zero, and the mainstream APIs agree:

  • Java: BigInteger(signum, magnitude) explicitly permits a zero-length magnitude and returns 0 for any signum
  • Python: int.from_bytes(b"") returns 0
  • Rust: num_bigint::BigInt::from_bytes_be(Sign::Minus, b"") normalizes to zero; BigUint::from_bytes_be(b"") returns 0 (same for ibig, rug/GMP)

MoonBit was the outlier with abort("empty octet string"), and inconsistently so: the morally identical all-zero magnitude (b"\x00" with signum=-1) was already accepted and returned 0, while the zero-length one panicked.

Changes

  • bigint/bigint_nonjs.mbt, bigint/bigint_js.mbt: return zero for empty input on all signum paths; update doc comments (and add an empty-input line to the docstring example)
  • bigint/bigint_test.mbt: extend the empty-input test to cover signum default, 0, and -1
  • bigint/panic_test.mbt: remove the two now-obsolete panic tests

Relaxing a documented panic into defined behavior; no public API signature changes (moon info reports no .mbti diff).

Follow-up to the contract discussion around #3748 / #3750.

Validation

  • moon fmt
  • moon check --target all
  • moon test bigint --target all (187/187 on wasm, wasm-gc, native; 162/162 on js)
  • moon info (no .mbti changes)

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings August 20, 2026 07:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns MoonBit’s BigInt::from_octets with mainstream bigint APIs by normalizing an empty magnitude (b"") to zero (instead of panicking for non-zero signum), and updates docs/tests accordingly.

Changes:

  • Make BigInt::from_octets return zero on empty input for all signum paths (JS + non-JS implementations).
  • Update public doc comments and examples to describe/cover empty-input behavior.
  • Adjust tests: extend empty-input assertions and remove now-obsolete panic tests.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
bigint/bigint_nonjs.mbt Normalize empty input to zero and update docs/examples for the non-JS implementation.
bigint/bigint_js.mbt Normalize empty input to 0N and update docs for the JS implementation.
bigint/bigint_test.mbt Extend regression coverage for empty input across default/0/-1 signum.
bigint/panic_test.mbt Remove panic tests that no longer apply after behavior change.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread bigint/bigint_nonjs.mbt Outdated
Comment on lines 1430 to 1434
/// * `bytes` : A sequence of bytes representing the magnitude of the number in
/// big-endian order. The sequence must not be empty unless `sign` is 0.
/// big-endian order. An empty sequence represents a zero magnitude.
/// * `sign` : An integer specifying the sign of the resulting number (default:
/// 1). A value of 1 creates a positive number, -1 creates a negative number, and
/// 0 returns zero regardless of the input bytes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2c92339 — the docstring now uses input/signum to match the signature.

Comment thread bigint/bigint_nonjs.mbt Outdated
Comment on lines +1439 to +1440
/// An empty byte sequence yields zero for any `sign`, matching the behavior of
/// Java's `BigInteger`, Python's `int.from_bytes`, and Rust's `num-bigint`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2c92339 — the note now says signum, consistent with the signature and examples.

@bobzhang
bobzhang force-pushed the hongbo/from_octets_empty_zero branch from 9465eb1 to feaa577 Compare August 20, 2026 07:42
@coveralls

coveralls commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 6237

Coverage remained the same at 90.734%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 1 of 1 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 17969
Covered Lines: 16304
Line Coverage: 90.73%
Coverage Strength: 331711.67 hits per line

💛 - Coveralls

bobzhang added a commit that referenced this pull request Aug 20, 2026
The docstring referred to `bytes`/`sign` while the actual parameters are
`input`/`signum`. Addresses Copilot review comments on #4115.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bobzhang added a commit that referenced this pull request Aug 20, 2026
The docstring referred to `bytes`/`sign` while the actual parameters are
`input`/`signum`. Addresses Copilot review comments on #4115.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bobzhang
bobzhang force-pushed the hongbo/from_octets_empty_zero branch from 2c92339 to a670704 Compare August 20, 2026 08:43
@bobzhang
bobzhang enabled auto-merge (squash) August 20, 2026 08:44
bobzhang and others added 2 commits August 20, 2026 17:09
An empty big-endian magnitude naturally denotes zero, and mainstream
bigint APIs agree: Java's BigInteger(signum, magnitude) permits a
zero-length magnitude for any signum, Python's int.from_bytes(b"")
returns 0, and Rust's num-bigint normalizes Sign::Minus with an empty
magnitude to zero. Previously MoonBit was the outlier, aborting with
"empty octet string" whenever signum != 0, while still accepting the
morally identical all-zero magnitude (e.g. b"\x00" with signum=-1).

Relax the panic on both backends to return zero, update the docs, and
replace the panic tests with value tests covering every signum.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The docstring referred to `bytes`/`sign` while the actual parameters are
`input`/`signum`. Addresses Copilot review comments on #4115.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bobzhang
bobzhang force-pushed the hongbo/from_octets_empty_zero branch from a670704 to 1d261a8 Compare August 20, 2026 09:09
@bobzhang
bobzhang merged commit dc17f50 into main Aug 20, 2026
16 checks passed
@bobzhang
bobzhang deleted the hongbo/from_octets_empty_zero branch August 20, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants