Skip to content

muimaster: answer ARexx commands an application did not define - #1965

Merged
Kalamatee merged 1 commit into
aros-development-team:masterfrom
terminills:muimaster-rexx-unknown-commands
Oct 31, 2026
Merged

Kalamatee merged 1 commit into
aros-development-team:masterfrom
terminills:muimaster-rexx-unknown-commands

Conversation

@terminills

@terminills terminills commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

An application with MUIA_Application_UseRexx but no MUIA_Application_Commands has a NULL command table; an ARexx message to its port dereferenced it. Walk the table only when there is one.

A command the table does not have goes to MUIA_Application_RexxHook, which Zune stored but never called: the hook gets the application and the RexxMsg (A2, A1), its return value is the result code, and a string set through MUIA_Application_RexxString is the secondary result, as for a table command. Without a hook the message is answered with RC_ERROR.

Test: developer/debug/test/Zune/rexxunknown sends such an application a command, once without a hook (RC_ERROR) and once with a RexxHook (called once with the command, its return value and result string come back). pc-x86_64 in QEMU on master 33e67a1: 7 PASS, REXXUNKNOWN PASS.

@Kalamatee

Copy link
Copy Markdown
Member

Thanks - the NULL check is correct and needed. In MUI, MUIA_Application_Commands is optional (every application already has MUI's built-in commands), so a NULL table is a valid state and dereferencing it was a real crash. Setting rm_Result1 = RC_ERROR before the loop, and letting a match overwrite it, fixes that. The test syntax-checks cleanly for pc-x86_64 (only a const-qualifier warning on CreateRexxMsg()); I have not run it.

The unknown-command path should call MUIA_Application_RexxHook

This is the branch MUI uses for MUIA_Application_RexxHook. From the MUI autodoc:

When specified, MUI calls this hook whenever a rexx message arrives and MUI can't map it to a builtin or a programmer specified command. The return code from the hook is used as result code when replying the message, the secondary result can be set with MUIA_Application_RexxString.

Zune stores the hook but never calls it (application.c:153 says "stored; not invoked"). With this PR, an application that handles its commands in a RexxHook gets RC_ERROR for everything on Zune, where MUI would run its hook. Since this PR is changing exactly that fallback, could it also:

  • when no table entry matched and app_RexxHook is set, set data->app_RexxMsg = rmsg and call CallHookPkt(app_RexxHook, obj, rmsg) (hook in A0, application in A2, RexxMsg in A1, as MUI documents);
  • use the hook's return value as rm_Result1, and handle app_RexxString the same way as the command path;
  • reply RC_ERROR only when there is no hook (the autodocs do not say what MUI returns then, so RC_ERROR is a reasonable choice);
  • add a test case with a RexxHook and no command table.

Other differences from MUI in the same code (fine as follow-ups)

  • MUI opens the ARexx port unless MUIA_Application_UseRexx is FALSE. Zune only opens it when UseRexx or Commands is given (application.c:609-618, "MUI by default enables Rexx port. Zune does not."). So even with the hook supported, an application that only sets a RexxHook has no port on Zune.
  • MUI's built-in commands are not implemented. The autodocs mention QUIT / QUIT FORCE (which sets MUIA_Application_ForceQuit). After this PR, QUIT sent to a Zune application without a command table replies RC_ERROR instead of quitting.
  • MC_TEMPLATE_ID is not handled: MUI documents it as "no argument parsing, return the ID from the next MUIM_Application_Input", but Zune passes (STRPTR)~0 to ReadArgs() as a template (application.c:1720-1744).
  • Command names are matched by prefix: Strnicmp(commandstr, mc_Name, len) uses the length of the incoming word, so "Q" runs "QUIT". A command with a leading space, or an empty one, gives len == 0 and runs the first table entry. MUI matches whole names, ignoring case.
  • rm_Result2 gets an argstring whenever RXFF_RESULT is set and app_RexxString exists, even when the hook returned a non-zero rc; ARexx reads rm_Result2 as an error number in that case (application.c:1762-1766). app_RexxString is also never cleared after a reply, so a later command can return an earlier command's string; the autodoc says the string is only "temporarily copied".

I'd be happy to merge the crash fix, but since the PR is about how unknown commands are answered, I'd like the RexxHook fallback included so the behaviour matches MUI.

An application with MUIA_Application_UseRexx but no
MUIA_Application_Commands has a NULL command table; an ARexx message to
its port dereferenced it. Walk the table only when there is one.

A command the table does not have goes to MUIA_Application_RexxHook,
which Zune stored but never called: the hook gets the application and
the RexxMsg, its return value is the result code, and a string set
through MUIA_Application_RexxString is the secondary result, as for a
table command. Without a hook the message is answered with RC_ERROR.

The test developer/debug/test/Zune/rexxunknown sends such an
application a command, once without a hook and once with one, and
checks the replies.
@terminills
terminills force-pushed the muimaster-rexx-unknown-commands branch from 8e46b41 to 61b5605 Compare October 31, 2026 14:00
@terminills

Copy link
Copy Markdown
Contributor Author

Done, rebased on master, still one commit. When no table entry matches and app_RexxHook is set, the hook is called with app_RexxMsg set around the call (CallHookPkt(hook, obj, rmsg)), its return value becomes rm_Result1 and app_RexxString is handled exactly as on the command path; RC_ERROR only without a hook. The attribute table now says RexxHook is done.

The test has the second case: an application with a RexxHook and no table, RXCOMM | RXFF_RESULT; it checks the hook ran once and saw the command, that its return value (7) is the result code, and that the string it set through MUIA_Application_RexxString comes back in rm_Result2. The CreateRexxMsg() const warning is gone too. pc-x86_64 in QEMU: 7 PASS, REXXUNKNOWN PASS.

The other differences from MUI you list (UseRexx default, QUIT, MC_TEMPLATE_ID, whole-name matching, rm_Result2 on a non-zero rc, clearing RexxString) I will take as a follow-up once this is in.

@Kalamatee

Copy link
Copy Markdown
Member
  • The test's hook returns 7 but still expects a result string in rm_Result2. ARexx only treats rm_Result2 as a string when the result code is 0; otherwise it reads it as an error number, and the string is never freed.
  • The PR didn't introduce this: both code paths already behave that way. But the test now treats it as correct, so fixing it later would mean changing the test too.
  • There are two ways to fix it. One is to have the test's hook return 0. The better one is to only set rm_Result2 when the result is 0, in both places, and test both cases. The reply includes the one-line condition for that.

@Kalamatee
Kalamatee merged commit 2f96e83 into aros-development-team:master Oct 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants