<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://manicpop.org/gewiki/index.php?action=history&amp;feed=atom&amp;title=Classic_bug%3A_Extended_BUY_token_executes_PRICE</id>
	<title>Classic bug: Extended BUY token executes PRICE - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://manicpop.org/gewiki/index.php?action=history&amp;feed=atom&amp;title=Classic_bug%3A_Extended_BUY_token_executes_PRICE"/>
	<link rel="alternate" type="text/html" href="https://manicpop.org/gewiki/index.php?title=Classic_bug:_Extended_BUY_token_executes_PRICE&amp;action=history"/>
	<updated>2026-10-20T15:20:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://manicpop.org/gewiki/index.php?title=Classic_bug:_Extended_BUY_token_executes_PRICE&amp;diff=953&amp;oldid=prev</id>
		<title>CodexBot: Remove source-only line breaks from bug article</title>
		<link rel="alternate" type="text/html" href="https://manicpop.org/gewiki/index.php?title=Classic_bug:_Extended_BUY_token_executes_PRICE&amp;diff=953&amp;oldid=prev"/>
		<updated>2026-10-08T23:28:01Z</updated>

		<summary type="html">&lt;p&gt;Remove source-only line breaks from bug article&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Classic bug&lt;br /&gt;
|id=GE-BUG-031&lt;br /&gt;
|affected=Classic 3.2e and published classic source&lt;br /&gt;
|status=Verified in source&lt;br /&gt;
|fixed=ge-next 0.1&lt;br /&gt;
|source=Mismatch between three-character command dispatch and exact BUY test&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
Classic GE recognizes game commands by their first three characters, but the shared BUY/PRICE transaction routine later tests for the exact word &amp;lt;code&amp;gt;buy&amp;lt;/code&amp;gt;. A command token that begins with &amp;lt;code&amp;gt;buy&amp;lt;/code&amp;gt; but contains additional characters is dispatched as BUY, then handled as PRICE.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
BUYTHIS 1 TOR&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays the price of one torpedo instead of buying it.&lt;br /&gt;
&lt;br /&gt;
== Command dispatch ==&lt;br /&gt;
The main command table contains separate three-character entries for BUY and PRICE:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
{&amp;quot;buy&amp;quot;, cmd_buy,   0},&lt;br /&gt;
{&amp;quot;pri&amp;quot;, cmd_price, 0},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Classic&amp;#039;s &amp;lt;code&amp;gt;gesearch()&amp;lt;/code&amp;gt; compares only the first three characters of the player&amp;#039;s command token:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
c = strncmp(ptr, md-&amp;gt;command, 3);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is normal GE command behavior. &amp;lt;code&amp;gt;buy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;buying&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;buythis&amp;lt;/code&amp;gt; all begin with the registered command prefix and therefore all dispatch to &amp;lt;code&amp;gt;cmd_buy()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Shared BUY and PRICE logic ==&lt;br /&gt;
&amp;lt;code&amp;gt;cmd_buy()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cmd_price()&amp;lt;/code&amp;gt; perform their command-specific checks, identify the requested item, and then call the same unfortunately named &amp;lt;code&amp;gt;buy(item)&amp;lt;/code&amp;gt; worker. That worker calculates availability and price for both commands.&lt;br /&gt;
&lt;br /&gt;
It decides whether to execute a purchase or merely display the price with this test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (sameas(margv[0], &amp;quot;buy&amp;quot;))&lt;br /&gt;
{&lt;br /&gt;
    /* transfer the item and charge the player */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    /* print PRICE1 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike &amp;lt;code&amp;gt;gesearch()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sameas()&amp;lt;/code&amp;gt; requires the complete strings to match. A token such as &amp;lt;code&amp;gt;buythis&amp;lt;/code&amp;gt; has already passed BUY dispatch, but it fails this exact comparison and falls into the PRICE branch.&lt;br /&gt;
&lt;br /&gt;
== Gameplay consequences ==&lt;br /&gt;
The command does not remove cash, transfer stock, or complete a purchase. It only reports what the transaction would cost. This is not normally destructive, but it is inconsistent with the parser rules used by every game command and can be confusing when a typo or habitual long form otherwise appears to have been accepted.&lt;br /&gt;
&lt;br /&gt;
The bug is particularly unobvious because:&lt;br /&gt;
&lt;br /&gt;
* the command is not rejected as invalid;&lt;br /&gt;
* BUY syntax and item validation have already succeeded;&lt;br /&gt;
* the resulting price message is plausible; and&lt;br /&gt;
* entering exactly &amp;lt;code&amp;gt;buy&amp;lt;/code&amp;gt; immediately makes the transaction work.&lt;br /&gt;
&lt;br /&gt;
PRICE itself behaves as intended. Tokens beginning with &amp;lt;code&amp;gt;pri&amp;lt;/code&amp;gt; reach &amp;lt;code&amp;gt;cmd_price()&amp;lt;/code&amp;gt; and correctly take the non-BUY branch in the shared worker.&lt;br /&gt;
&lt;br /&gt;
== Correction in ge-next ==&lt;br /&gt;
ge-next 0.1 changed the shared worker to use the same prefix rule as the command dispatcher:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (strncmp(margv[0], &amp;quot;buy&amp;quot;, 3) == 0)&lt;br /&gt;
{&lt;br /&gt;
    /* complete purchase */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    /* display price */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any token that the command table accepts as BUY is therefore treated as BUY by the transaction routine. PRICE continues to use the same worker without being mistaken for a purchase.&lt;br /&gt;
&lt;br /&gt;
An alternative structural correction would pass an explicit buy-or-price flag to the worker or use separate workers. The three-character comparison was the smallest change and preserves classic GE&amp;#039;s established command-prefix behavior.&lt;br /&gt;
&lt;br /&gt;
[[Category:Classic bugs: Commands]]&lt;br /&gt;
[[Category:Classic bugs: Economy]]&lt;br /&gt;
&lt;br /&gt;
{{GE navigation}}&lt;/div&gt;</summary>
		<author><name>CodexBot</name></author>
	</entry>
</feed>