Summary
In Video Poker (apps_source_code/videopoker), the payout calculation multiplies the bet by the paytable multiplier in plain int arithmetic. At very large bets the product overflows, which (via signed-integer wraparound) makes the score negative and silently ends the game with the "You have run out of money!" screen - i.e. hitting the jackpot is reported as going bankrupt.
This is a pre-existing defect, independent of PR #237 (issue #163); it was surfaced while reviewing that change and is being tracked separately.
Location
apps_source_code/videopoker/poker.c:789-790
poker_player->score +=
poker_player->bet * paytable[recognize(poker_player)];
bet and every paytable entry are int, so bet * paytable[...] is an int * int product.
Trigger
The largest multiplier is a Royal Flush at 800x (paytable[0]). With INT_MAX = 2147483647:
- Royal Flush (x800): overflows once the bet is above ~2,684,355
- Straight Flush (x50): above ~42.9M
- Four of a Kind (x25): above ~85.9M
Because the bet is capped at the bank, this needs a bank of at least ~2.68M, reachable only after an extended winning streak (the starting bank is 1000). So it is an edge case - but it is real signed-integer overflow (undefined behavior), not merely a display glitch.
Impact
When the product overflows to a negative value:
score becomes negative at poker.c:789-790.
clamp_bet() (poker.c:793) then pins bet to that negative score.
- The
if(poker_player->score <= 0) check (poker.c:799) routes the player to GameState = 4, the "You have run out of money!" game-over screen.
Net effect: a winning hand at a large enough bet ends the game as a bankruptcy.
Related note: score, bet and highscore are all int, so the bank can also overflow simply by accumulating winnings past INT_MAX, even without a single large multiply.
Suggested fix
Compute the payout in a wider type and saturate before storing back into the int score, e.g.:
int64_t win = (int64_t)poker_player->bet * paytable[recognize(poker_player)];
int64_t total = (int64_t)poker_player->score + win;
poker_player->score = total > INT32_MAX ? INT32_MAX : (int)total;
Alternatively, widen score/bet/highscore to a 64-bit type (and update the %d format specifiers in the draw callback), or cap the bank at a sane maximum. Since this app is third-party (fap_author="@PixlEmly"), a fix may want to be coordinated upstream.
🤖 Generated with Claude Code
Summary
In Video Poker (
apps_source_code/videopoker), the payout calculation multiplies the bet by the paytable multiplier in plainintarithmetic. At very large bets the product overflows, which (via signed-integer wraparound) makes the score negative and silently ends the game with the "You have run out of money!" screen - i.e. hitting the jackpot is reported as going bankrupt.This is a pre-existing defect, independent of PR #237 (issue #163); it was surfaced while reviewing that change and is being tracked separately.
Location
apps_source_code/videopoker/poker.c:789-790betand everypaytableentry areint, sobet * paytable[...]is anint * intproduct.Trigger
The largest multiplier is a Royal Flush at 800x (
paytable[0]). WithINT_MAX = 2147483647:Because the bet is capped at the bank, this needs a bank of at least ~2.68M, reachable only after an extended winning streak (the starting bank is 1000). So it is an edge case - but it is real signed-integer overflow (undefined behavior), not merely a display glitch.
Impact
When the product overflows to a negative value:
scorebecomes negative atpoker.c:789-790.clamp_bet()(poker.c:793) then pinsbetto that negative score.if(poker_player->score <= 0)check (poker.c:799) routes the player toGameState = 4, the "You have run out of money!" game-over screen.Net effect: a winning hand at a large enough bet ends the game as a bankruptcy.
Related note:
score,betandhighscoreare allint, so the bank can also overflow simply by accumulating winnings pastINT_MAX, even without a single large multiply.Suggested fix
Compute the payout in a wider type and saturate before storing back into the
intscore, e.g.:Alternatively, widen
score/bet/highscoreto a 64-bit type (and update the%dformat specifiers in the draw callback), or cap the bank at a sane maximum. Since this app is third-party (fap_author="@PixlEmly"), a fix may want to be coordinated upstream.🤖 Generated with Claude Code