Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Added compile-time warning for GUIX deprecated string API - #167

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations
Aug 7, 2026
Merged

Added compile-time warning for GUIX deprecated string API#167
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fdesbiens/flag-deprecations

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

When GX_DISABLE_DEPRECATED_STRING_API is not defined, gx_api.h now emits a #pragma message compile-time warning directing developers to define GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based (_ext) replacement functions.

The pre-5.6 GX_CHAR * API omits string lengths and cannot safely handle non-NUL-terminated strings or prevent buffer overruns. All new applications should use the replacement variants.

Changes

  • common/inc/gx_api.h: added #pragma message inside the #ifndef GX_DISABLE_DEPRECATED_STRING_API block.

Companion

Docs: eclipse-threadx/rtos-docs-asciidoc#33 (pending)

When GX_DISABLE_DEPRECATED_STRING_API is not defined (i.e., the
pre-5.6 GX_CHAR* API is still enabled), gx_api.h now emits a
#pragma message directing developers to define
GX_DISABLE_DEPRECATED_STRING_API and migrate to the GX_STRING-based
replacement functions.
The deprecated functions omit a string length and cannot safely handle
non-NUL-terminated strings or prevent buffer overruns. All new
applications should use the _ext() replacement variants.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit d5c9df4 into eclipse-threadx:devAug 7, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fdesbiens/flag-deprecations branch August 7, 2026 15:58
fdesbiens added a commit that referenced this pull request Aug 27, 2026
)
_gx_multi_line_text_view_display_info_get() decided whether a line terminator
was "\r" or "\r\n" by examining ch.gx_string_ptr[1], the byte after the current
character, without checking that a byte remained. When the carriage return is
the last byte of the range, that access is outside the caller's buffer.
A GX_STRING carries its own length and need not be NUL terminated -- that is
why the _ext string API exists, and it is what the deprecation warning added in
#167 says about the older char * API. _gx_multi_line_text_view_text_set_ext()
stores the caller's GX_STRING verbatim unless GX_STYLE_TEXT_COPY is set, and
callers of this function pass end_index = gx_string_length, so in the default
configuration the read lands one byte past what the application supplied.
The consequence is not only the read. If that byte happens to be 0x0A, the
function reports a two-byte terminator for a one-byte remainder, so every
caller advances its index by one more than the string holds. In
_gx_multi_line_text_view_string_total_rows_compute() the loop then exits with
index == gx_string_length + 1 and evaluates string.gx_string_ptr[index - 1],
one byte past the end as well, and can add a row that is not in the text. The
same over-advance reaches the line index cache in
gx_multi_line_text_view_line_cache_update.c and the cursor arithmetic in
gx_multi_line_text_input_cursor_pos_update.c.
Both reads now go through string rather than ch. string has already been
advanced past the current character and its length is exactly the number of
bytes still readable there, so guarding on it bounds the access to what the
caller supplied.
The same idiom in _gx_multi_line_text_input_new_line_character_get() is
corrected as well. That one is not currently reachable as a read past the end:
its only caller, _gx_multi_line_text_input_text_set_ext(), writes a NUL
immediately after the copied text. It is fixed anyway because it depends on an
invariant established in a different function and documented nowhere, and
because the byte it reads decides whether the widget inserts a one- or two-byte
terminator on every subsequent Enter.
The rest of the codebase was audited for the same shape. Five other sites
handle a carriage return followed by a possible line feed; all five are already
correct. gx_rich_text_view_line_info_get.c, gx_multi_line_text_input_char_insert.c
and gx_utility_bidi_paragraph_reorder.c guard on the remaining length, the
preprocessed-line-break branch at the top of the changed function guards on it
too, and gx_multi_line_text_button_line_pointers_set.c walks a NUL-terminated
char * buffer where the byte after a carriage return is at worst the
terminator.
guix_ml_text_line_terminator_bounds_no_output covers this. It places a line
feed immediately after the string under test but outside the length the widget
is given, so the over-read is observable without a sanitizer: the unfixed code
counts the out-of-bounds byte and reports a 4-byte row for a 3-byte string,
which the test catches as "Expected: 3, Got: 4". Two controls pin the cases
that must not change -- a "\r\n" pair genuinely inside the string still counts
as two bytes, and a carriage return followed by ordinary text still counts as
one.
The test also asserts the terminator a multi-line text input adopts from its
text, for a lone carriage return and for a "\r\n" pair. Those two cases pass
both before and after the change, for the reason given above; they are there to
pin the behaviour, not to reproduce a fault.
Verified on Linux across all eighteen build configurations, no failures.
No documentation change is required: no public API or behaviour contract
changes, and the corrected behaviour is what the documented terminator handling
already describes.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@fdesbiens