Skip to content

wrong buffer parsed after environment lookup #544

@pmetzger

Description

@pmetzger

This bug report was generated by Codex during the course of refactoring and testing on my fork of SIMH. Unlike other reports, I haven't hand checked very this carefully because my test harness indicates the patch is good for me, but I am passing it upstream anyway because it seems pro-social to do so.

Summary

In scp.c, SCP expression evaluation can parse the wrong string after _sim_get_env_special() returns a value.

The failure occurs when:

  • the expression element is not a register name
  • _sim_get_env_special() finds a numeric value
  • the returned pointer is not the local string buffer passed by the
    caller, but some other backing storage, such as a host environment string

In that case, sim_eval_expression() incorrectly parses string instead of
the pointer returned by _sim_get_env_special().

User-visible effect

A numeric expression that refers to a host environment variable can evaluate
incorrectly.

Example:

SIMH_TEST_EXPR_VALUE=41
expression: SIMH_TEST_EXPR_VALUE + 1
expected: 42
actual:   1

The + 1 still works, but the left-hand variable is parsed from the wrong
buffer, so it contributes 0.

Root cause

In the affected code:

gptr = _sim_get_env_special (data, string, string_size - 1);
if (NULL != gptr) {
    *svalue = strtotsv(string, &gptr, 0);
    ...
    return ((*gptr == '\0') && (*string));
}

_sim_get_env_special() may return:

  • string, when it formats a built-in or SCP-owned variable into the caller
    buffer
  • some other pointer, such as a host environment value returned through
    getenv()

The code above always parses string, even when the actual value is in the
returned pointer. That is the bug.

Correct behavior

sim_eval_expression() should parse the string referenced by the pointer
returned from _sim_get_env_special(), and should use a separate end pointer
when checking whether the numeric parse consumed the whole string.

Patch against the older monolithic scp.c

This patch applies to the pre-src/core/ split code layout, such as commit
4d38373206cd7c0ce8b94f5e16bd4429cb96430f from April 7, 2026.

diff --git a/scp.c b/scp.c
--- a/scp.c
+++ b/scp.c
@@ -15874,10 +15874,12 @@
         return TRUE;
         }
     gptr = _sim_get_env_special (data, string, string_size - 1);
     if (NULL != gptr) {
-        *svalue = strtotsv(string, &gptr, 0);
+        const char *eptr;
+
+        *svalue = strtotsv(gptr, &eptr, 0);
         sprint_val (string, *svalue, 10, string_size - 1, PV_LEFTSIGN);
         sim_debug (SIM_DBG_EXP_EVAL, &sim_scp_dev, "[Value: %s=%s]\n", data, string);
-        return ((*gptr == '\0') && (*string));
+        return ((*eptr == '\0') && (*string));
         }
     else {
         data = "";

Notes

  • This bug was turned up during refactoring and test construction

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions