Skip to content

Add assert for zero divisor in BigInt divMod to prevent infinite loop#11009

Open
burner wants to merge 1 commit intodlang:masterfrom
burner:issue_10784_bigint_divmod_zero
Open

Add assert for zero divisor in BigInt divMod to prevent infinite loop#11009
burner wants to merge 1 commit intodlang:masterfrom
burner:issue_10784_bigint_divmod_zero

Conversation

@burner
Copy link
Copy Markdown
Member

@burner burner commented May 5, 2026

Fixes #10784

Comment thread std/bigint.d
@safe pure unittest
{
import std.exception : assertThrown;
assertThrown(BigInt(100) / BigInt(0));
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.

this fails, does assertThrown only catch exceptions?

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.

It can catch any Throwable, but by default it only catches Exception.

@LightBender
Copy link
Copy Markdown
Contributor

LightBender commented May 5, 2026

Do we really need to crash the program for a divide-by-zero? It's not UB. In fact, it's very well defined behavior.

Asserts are for errors in the code itself, not for sanitizing user input.

User input crashing the program is an automatic CVE under the DoS category.

@Herringway
Copy link
Copy Markdown
Contributor

Do we really need to crash the program for a divide-by-zero? It's not UB. In fact, it's very well defined behavior.

https://dlang.org/spec/expression.html#division "Undefined Behavior: is exhibited if they are encountered during run time."

Integer division by zero currently results in a crash with DMD. You may be thinking of floating point division, which has different behaviour.

Asserts are for errors in the code itself, not for sanitizing user input.

User input crashing the program is an automatic CVE under the DoS category.

Wouldn't that mean it should never be possible to trigger an assert in phobos? I think that's a bit unreasonable.

@LightBender
Copy link
Copy Markdown
Contributor

Do we really need to crash the program for a divide-by-zero? It's not UB. In fact, it's very well defined behavior.

https://dlang.org/spec/expression.html#division "Undefined Behavior: is exhibited if they are encountered during run time."

Integer division by zero currently results in a crash with DMD. You may be thinking of floating point division, which has different behaviour.

Walter and I go back and forth on this a few times a year. Integer division behaving differently than float division is a glaring inconsistency in how division is handled. Thank you for giving me this leverage for the next time Walter and I decide to throw down on this topic.

Asserts are for errors in the code itself, not for sanitizing user input.
User input crashing the program is an automatic CVE under the DoS category.

Wouldn't that mean it should never be possible to trigger an assert in phobos? I think that's a bit unreasonable.

No, it would mean that user inputs do not trigger an assert. An assert is for making sure that the Phobos code itself does nothing wrong. Passing a zero to the divide operation is user input. Yes, it's wrong, but it's not a danger to the system and will not cause UB. Throw the exception so that I can log it without crashing all the other users (and causing actual UB in the process).

Crashing works great for single-threaded single-user batch apps. It is global thermonuclear warfare when applied to multi-user multi-threaded apps where crashing the app can interrupt a database update chain and leave user data in a malformed state that requires manual intervention to resolve. It gets worse when you considered that the malformed data can easily trigger another assert (if you use asserts to sanitize data) when loading that malformed data again from the database, causing another crash, which causes more malformed data.

Exceptions are for sanitizing user inputs. Asserts are for verifying the correctness of the code.

@Herringway
Copy link
Copy Markdown
Contributor

Do we really need to crash the program for a divide-by-zero? It's not UB. In fact, it's very well defined behavior.

https://dlang.org/spec/expression.html#division "Undefined Behavior: is exhibited if they are encountered during run time."
Integer division by zero currently results in a crash with DMD. You may be thinking of floating point division, which has different behaviour.

Walter and I go back and forth on this a few times a year. Integer division behaving differently than float division is a glaring inconsistency in how division is handled. Thank you for giving me this leverage for the next time Walter and I decide to throw down on this topic.

I would be quite happy to see floating point division by zero become consistent with integer division by zero.

Asserts are for errors in the code itself, not for sanitizing user input.
User input crashing the program is an automatic CVE under the DoS category.

Wouldn't that mean it should never be possible to trigger an assert in phobos? I think that's a bit unreasonable.

No, it would mean that user inputs do not trigger an assert. An assert is for making sure that the Phobos code itself does nothing wrong. Passing a zero to the divide operation is user input. Yes, it's wrong, but it's not a danger to the system and will not cause UB. Throw the exception so that I can log it without crashing all the other users (and causing actual UB in the process).

Unless there is some way we can call phobos functions without user input, then there must be no asserts.

Crashing works great for single-threaded single-user batch apps. It is global thermonuclear warfare when applied to multi-user multi-threaded apps where crashing the app can interrupt a database update chain and leave user data in a malformed state that requires manual intervention to resolve. It gets worse when you considered that the malformed data can easily trigger another assert (if you use asserts to sanitize data) when loading that malformed data again from the database, causing another crash, which causes more malformed data.

We should not be encouraging the design of such fragile software. This particular problem was solved way back in the 1980s with ACID...

Exceptions are for sanitizing user inputs. Asserts are for verifying the correctness of the code.

Indeed, but I think I'm going to have to disagree with your definition of "user input".

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.

BigInt divMod loops infinitely when dividing by zero

4 participants