Skip to content

PowerPoint: fix errors when reading text formatting and hyperlinks - #21007

Closed
ChristosBouronikos wants to merge 1 commit into
nvaccess:masterfrom
ChristosBouronikos:powerpointFormattingCrashes
Closed

ChristosBouronikos wants to merge 1 commit into
nvaccess:masterfrom
ChristosBouronikos:powerpointFormattingCrashes

Conversation

@ChristosBouronikos

@ChristosBouronikos ChristosBouronikos commented Oct 16, 2026 •

Copy link
Copy Markdown

Link to issue number:

None. These are coding errors in appModules/powerpnt.py, found while reviewing the PowerPoint app module.

Summary of the issue:

Several code paths in the PowerPoint text frame text info cannot work as written:

  • _getFormatFieldAndOffsets calls _getCurrentRun(self), passing the text info where a character offset is expected. Finding the formatting run for a position therefore raises a TypeError instead of returning a run.
  • When no run is found, the fallback characters(offset + 1) has no length, so it covers the rest of the story instead of the single character at the offset.
  • _getPptTextRange raises ValueError(..., stack_info=True). ValueError does not accept keyword arguments, so the intended ValueError is replaced by a TypeError.
  • _getLinkDataAtCaretPosition builds the result with textInfos._LinkData, which does not exist (the class is imported from utils.urlUtils), and it dereferences the formatting run without checking whether one was found.

Description of user facing changes:

In Microsoft PowerPoint, formatting information and the link at the caret can be reported without NVDA raising an error.

Description of developer facing changes:

None.

Description of development approach:

  • Pass the offset to _getCurrentRun, and request a single character when falling back to characters().
  • Raise a plain ValueError. The message already contains the start and end values.
  • Use the imported _LinkData and return None when there is no formatting run at the caret.

Testing strategy:

  • Added tests/unit/test_appModules/test_powerpnt_textFrame.py. The tests cover finding the run from an offset, the single-character fallback, the ValueError, a link lookup without a run, and a link lookup that returns the shared _LinkData type. Without the change, every test fails.
  • The new tests and the lint checks (ruff, add-trailing-comma) pass locally using stand-ins for the Windows modules. The complete unit test suite also passes on Windows (Python 3.13, x64), run on a build of this branch in a private repository.
  • Manual testing in Microsoft PowerPoint is still outstanding. This PR is a draft until it has been done.

Known issues with pull request:

None known. The change log entry is deliberately generic because there is no issue to reference.

Code Review Checklist:

  • Documentation:
    • Change log entry
    • User Documentation
    • Developer / Technical Documentation
    • Context sensitive help for GUI changes
  • Testing:
    • Unit tests
    • System (end to end) tests
    • Manual testing
  • UX of all users considered:
    • Speech
    • Braille
    • Low Vision
    • Different web browsers
    • Localization in other languages / culture than English
  • API is compatible with existing add-ons.
  • Security precautions taken.

_getFormatFieldAndOffsets passed the text info itself to _getCurrentRun instead of the character offset, so looking up the formatting run failed with a TypeError. The fallback range for a missing run covered the rest of the story rather than one character, _getPptTextRange built a ValueError with an unsupported keyword argument, and the hyperlink lookup referenced _LinkData through textInfos, where it does not exist, and did not handle a missing run.
@ChristosBouronikos
ChristosBouronikos marked this pull request as ready for review October 16, 2026 08:30
@ChristosBouronikos
ChristosBouronikos requested a review from a team as a code owner October 16, 2026 08:30
@ChristosBouronikos
ChristosBouronikos requested review from seanbudd and a balanced review from Copilot October 16, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

3 participants