Integer overflow

From NetHackWiki
Jump to navigation Jump to search

Integer overflow occurs when an integer value exceeds the range of its data type.

When a signed integer variable overflows, a program's behavior is undefined, according to the C standard. Often, what happens is that, because negative numbers are represented as a two's complement, the variable wraps to the opposite end of the data type's range: a negative value which just exceeds the range becomes a large positive value, and vice versa. When an unsigned integer variable overflows, the C standard defines the exact behavior: an unsigned value that just exceeds the type's range becomes zero or a small positive value, and subtracting a little more than an unsigned variable's value produces a large value.

NetHack protects most variables against integer overflow, both signed and unsigned - however, it is possible to find ways to avoid these limits in wizard mode. For example, in wizard mode, the character might wish for one billion dwarf corpses, producing an object stack whose total weight may appear to be negative (depending on details of the C implementation used to compile NetHack).

Any case where an ordinary game (i.e., not in wizard mode) can produce an integer overflow is a software bug.

Known overflows

Wrapping the turn counter

In NetHack 3.6.7 and earlier versions, the turn counter has no protection against overflow.[1]

NAO reports one game that ended with less than 0 turns played.[2]. There are no ascended games with 1 turn or any number of turns less than 2000.

Since that time, NAO switched from 32-bit binaries to 64-bit binaries, as evidenced by several games recorded with scores higher than 2,147,483,647. Nowadays, wrapping the turn counter on an NAO game would take 4 billion times as long as before.

The following information pertains to an upcoming version (NetHack 3.7.0). If this version is now released, please verify that the information below is still accurate, then update the page to incorporate it.

For games running over 100,000 turns, prayer timeout increases by 1 every 100 turns - this is implemented to prevent denial-of-service attacks against public servers. If a game runs over one billion turns, it ends immediately in an escape:

The dungeon capitulates.

History

In NetHack 3.4.3 and previous versions, including some variants based on those versions, cases of integer overflow that are fixed in NetHack 3.6.0 include:

Wrapping the score[3][4] was supposed to be fixed, but the fix itself relies on signed integer overflow, which is undefined behaviour.[5]

References

  1. Jump up src/allmain.c in NetHack 3.6.7, line 172
  2. Jump up https://s3.amazonaws.com/altorg/dumplog/Khaos/1291644901.nh343.txt
  3. Jump up NAO game by ctaboir on 2006-10-03 with score -2,147,474,899; dumplog not available
  4. Jump up NAO game by pug on 2007-11-12 with score -2,145,868,906; dumplog not available
  5. Jump up src/end.c in NetHack 3.6.7, line 19: macro nowrap_add