Skip to content

Escape strings in answers to GAP - #38

Merged
fingolfin merged 1 commit into
masterfrom
mh/escape-answers
Sep 20, 2026
Merged

fingolfin merged 1 commit into
masterfrom
mh/escape-answers

Conversation

@fingolfin

Copy link
Copy Markdown
Member

GAP undoes '@' escapes in the answer to a window command, but AnswerGap sent strings verbatim. A string containing '@', such as text entered into a dialog, thus arrived mangled and shorter than its announced length. Double each '@' and send control characters as '@A' to '@z', as GAP does in the other direction.

Assisted-by: Claude Code (Fable 5.1)

CC @RussWoodroofe

GAP undoes '@' escapes in the answer to a window command, but
AnswerGap sent strings verbatim. A string containing '@', such as
text entered into a dialog, thus arrived mangled and shorter than its
announced length. Double each '@' and send control characters as
'@A' to '@z', as GAP does in the other direction.

Assisted-by: Claude Code (Fable 5.1)
@fingolfin
fingolfin enabled auto-merge (squash) September 20, 2026 10:20
@fingolfin
fingolfin merged commit dd14cb9 into master Sep 20, 2026
4 checks passed
@fingolfin
fingolfin deleted the mh/escape-answers branch September 20, 2026 10:20
@RussWoodroofe

Copy link
Copy Markdown
Contributor

I just checked the Gap.app source -- my answerGap encodes @'s as @@'s, but leaves ctrl characters alone. I don't remember if there was a reason not to encode, beyond that xgap didn't. @ is an infrequent character in responses, per gap-system/gap#6483 , but I think this is unlikely to cause trouble.

@fingolfin

Copy link
Copy Markdown
Member Author

Thanks for checking. I think both variants are fine, since the receiver is the kernel, not the other front end. SyWinCmd turns @@ into @ and @A...@Z into the control character, and passes every other byte through unchanged. So a raw control character (Gap.app) and @J (xgap now) should arrive as the same string (but I've not actually tested it). That holds for the current kernel and equally for your gap-system/gap#6483 and my gap-system/gap#6584. Both test rigs feed the full @A-@Z table and @J inside replies.

The one difference I see is with kernels that have neither fix. There every escape in a reply makes the un-escaping pass read one byte too far, so encoding control characters adds chances to hit that bug where a raw byte would not. Doubling @ hits it too, but that cannot be avoided. As you say, it is unlikely to matter: the string answers xgap sends are nearly all fixed error messages, the exception being the dialog text.

I did not find out why GAP escapes control characters in its own direction. If the reason is that the pty might otherwise interpret them (^C, ^D, ^S/^Q), the same would apply to replies, and escaping them would be the safer choice. Do you know whether Gap.app has ever had a problem with a control character in a reply?

I'll leave xgap as it is. Separately, I could only test gap-system/gap#6584 with xgap. If you could run it against Gap.app, that would be very helpful.

@RussWoodroofe

Copy link
Copy Markdown
Contributor

I agree that escaping them seems like the more correct thing to do. I haven't had any trouble leaving them unescaped in the other direction. As you say, not so many things get sent back, but I did test some long dialog texts, and didn't see anything funny. I don't understand quite why the XGAP architecture escapes ctrl characters at all, except possibly for ease of debugging streams. I'd suggest that GAP should correctly unescape all @ codes, but also interpret unescaped ctrl codes except where it has a reason not to.

Started to review other PR, and it looked sensible enough. Other tasks took me away, and it may take me a day or two to finish up (including testing against Gap.app and belatedly pushing code to sf). Btw, Gap.app 0.7a should run fine against modern GAP, except that you'll need to drop in a gap.sh -- upcoming 0.8 will fix the gap.sh problem.

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