Skip to content

espeak: escape XML-special characters in single-character mode - #68

Open
donovanmalisch23-alt wants to merge 1 commit into
linux-speakup:masterfrom
donovanmalisch23-alt:fix-ssml-char-escaping
Open

espeak: escape XML-special characters in single-character mode#68
donovanmalisch23-alt wants to merge 1 commit into
linux-speakup:masterfrom
donovanmalisch23-alt:fix-ssml-char-escaping

Conversation

@donovanmalisch23-alt

Copy link
Copy Markdown

Problem

When speakup echoes a single character, speak_text() wraps it in SSML:

```
%c
```

If the character is one of XML's five special characters (`< > & ' "`), the raw
byte is injected straight into the markup, producing ill-formed SSML. espeak-ng
then misparses the `` element, which surfaces audibly as a spurious
high-pitched "ringing" whenever one of these characters is spoken character-by-character.

Fix

Escape each XML-special character to its entity (`< > & ' "`)
using a new `%s` variant of the existing wrapper, so the markup stays well-formed.
Non-printable characters (`< 0x20` or `> 0x7e`) are no longer wrapped in SSML
either; they set `n = -1` and fall through to the existing raw-synthesis
fallback, so they cannot corrupt the surrounding element. The space and
ordinary-printable-character paths are unchanged.

Verification

The change was reconstructed from a shipped binary that contains this fix and
reproduced byte-for-byte: compiling this patch with the project's build flags
yields a binary whose `.text` and `.rodata` sections are identical to the
shipped package (only the build-id / section-table offset differ, as expected).
The instruction stream is identical.

No behavioural change for spaces, letters, digits, or punctuation other than
the five XML-special characters; non-printables now take the same fallback path
used for allocation failure.

When speakup echoes a single character, espeakup wraps it in SSML:

    <say-as interpret-as="characters">%c</say-as>

If the character is one of XML's five special characters (< > & ' "),
the raw byte is injected straight into the markup, producing ill-formed
SSML.  espeak-ng then misparses the <say-as> element, which surfaces as
a spurious high-pitched "ringing" whenever one of these characters is
spoken.

Escape each special character to its corresponding XML entity
(&lt; &gt; &amp; &apos; &quot;) so the markup stays well-formed.
Non-printable characters (< 0x20 or > 0x7e) are no longer wrapped in
SSML either; they fall through to the existing raw-synthesis fallback
so they cannot corrupt the surrounding element either.

The space and ordinary-printable-character paths are unchanged.
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.

1 participant