Jump to content

Classic bug: Planet name limit off by one

From Galactic Empire wiki
Revision as of 19:28, 8 October 2026 by CodexBot (talk | contribs) (Remove source-only line breaks from bug article)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Bug ID GE-BUG-032
Affected versions Classic 3.2e message file and published source
Status Verified in source and message definition
Fixed in Planet name: ge-next 0.02; beacon: ge-next 0.3.3
Primary source Planet name and beacon prompts versus their fixed-size record fields

Summary

Classic GE advertises one more visible character than it can store for two planet administration fields. A planet name is described as allowing 20 characters but stores 19; a beacon is described as allowing 75 characters but stores 74. In both cases, the last advertised character is silently discarded.

These are off-by-one errors in the user-facing limits, not buffer overflows. The source reserves the final array byte for a terminating null; the prompts advertise the complete array sizes as though every byte were available for visible text.

Player-visible behavior

The classic planet administration prompt says:

The Protocol Officer requests an appropriate name for the
planet Sir, (20 characters max) ---

If the player enters a 20-character name, the game accepts the response but stores and subsequently displays only its first 19 characters. There is no warning that the last character was removed.

For example, a submitted name represented as:

12345678901234567890

is stored as:

1234567890123456789

This can also make two intended names that differ only in their twentieth character appear identical after storage.

Cause

The planet record declares:

char name[20];

A C string stored in that array requires one byte for '\0', leaving 19 bytes for visible characters. The naming routine enforces that real limit:

strncpy(plptr->name, margv[0], 19);
plptr->name[19] = 0;

The code is memory-safe for this operation and guarantees termination. The mistake is solely that ADMENU1A describes the array's 20-byte storage size as a 20-character naming limit.

Beacon message limit

Classic's beacon prompt makes the same mistake:

Enter the Beacon Message (75 characters max - enter to erase)

The planet record contains:

char beacon[BEACONMSGSZ];

BEACONMSGSZ is 75. The input routine copies up to 75 bytes but then deliberately replaces byte 74, the last byte in the array, with the terminator:

strncpy(plptr->beacon, margv[0], BEACONMSGSZ);
plptr->beacon[BEACONMSGSZ - 1] = 0;

The effective maximum is therefore 74 visible characters. A 75-character message is accepted, but its final character is removed before the beacon is saved or shown to approaching ships.

An audit of other persistent player-entered text distinguishes this bug from several superficially similar cases:

Field Classic storage Effective input Result
Planet name 20 bytes 19 characters Prompt incorrectly advertises 20
Planet beacon 75 bytes 74 characters Prompt incorrectly advertises 75
Ship name 35 bytes 19 characters Safely truncated; HELP RENAME states no maximum
Planet trade password 10 bytes Intended as 9 characters Terminator is written one byte beyond the field
Team name 31 bytes 30 characters Some strncpy() paths do not explicitly terminate a full-length value
Team public and secret passwords 11 bytes each 10 characters Team creation does not explicitly terminate full-length temporary values

The ship-name limit is conservative rather than falsely advertised. Classic reserves 35 bytes in WARSHP, but cmd_rename() copies only 19 characters and safely terminates at index 19. Since the help text does not promise a larger limit, this is an undocumented implementation limit, not the same user-facing off-by-one defect.

The password and team cases are different and more serious. They involve an out-of-bounds terminator or potentially unterminated strings and should be tracked as string-safety bugs rather than folded into GE-BUG-032.

Correction in ge-next

ge-next 0.01 and 0.02 consisted of revised MSG, help, configuration, and data files used with the original classic 3.2e DLL. ge-next 0.02 corrected the planet naming prompt to present a 19-character input field, matching the limit already enforced by the unchanged executable.

The planet record and copy operation did not need to change. Expanding the true limit to 20 visible characters would require changing the persistent record layout or taking a byte from another field, with database-compatibility consequences. Correcting the advertised limit is the safe compatible fix.

The beacon prompt initially removed the incorrect "75 characters max" wording but continued to draw a 75-character entry area, so entering a message that filled the guide still silently lost its last character. ge-next 0.3.3 corrected this in both the 16-bit and 32-bit MSG files: the prompt explicitly states a 74-character maximum and draws a 74-character entry area. The 75-byte record field and its null-termination logic remain unchanged, preserving database compatibility.