Skip to content

automation.VARIANT._set_value assumes c_char.value has length 1 #935

@douglasnovy

Description

@douglasnovy

Environment data

  • OS: Windows Server 2022 / Windows 10
  • Python version: 3.13.12
  • comtypes version: 1.4.16
  • COM type libraries involved in the real-world trigger: UI Automation (IUIAutomation)

Code snippet

This synthetic reproducer exercises the exact failing branch in comtypes/automation.py:

from ctypes import c_char
from comtypes.automation import VARIANT


class WeirdChar(c_char):
    @property
    def value(self):
        return b"hello"


VARIANT(WeirdChar(b"h"))

Traceback on comtypes 1.4.16:

Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
  File "...\site-packages\comtypes\automation.py", line 199, in __init__
    self.value = args[0]
  File "...\site-packages\comtypes\automation.py", line 347, in _set_value
    self._.VT_UI1 = ord(value.value)
TypeError: ord() expected a character, but string of length 5 found

The current branch is:

elif isinstance(value, c_char):
    self._.VT_UI1 = ord(value.value)
    self.vt = VT_UI1

Situation reproducing steps

  1. Import VARIANT from comtypes.automation
  2. Pass a c_char instance whose .value is longer than one byte to VARIANT(...)
  3. automation.py calls ord(value.value)
  4. ord() raises TypeError because the input length is greater than 1

In a real application, I hit this through COM/UI Automation property marshaling. During tree traversal, a COM property eventually reached VARIANT._set_value as a c_char whose .value was unexpectedly multi-byte, which caused the same traceback above.

Expected behavior

comtypes should not assume that c_char.value is always length 1 before calling ord().

At minimum, this branch should validate the length explicitly and raise a more direct error with context. If treating the underlying data as a byte is the intended behavior, raw[0] after validation would also avoid the current ord() failure path.

Actual behavior

comtypes raises a generic TypeError from ord():

TypeError: ord() expected a character, but string of length 5 found

When this happens in COM-driven code, the error bubbles out of a deep marshaling path and is difficult for downstream callers to diagnose or handle precisely.

Additional context

I do not yet have a minimal pure-COM reproducer outside the larger application, so the code snippet above is synthetic. I am filing this because it demonstrates the exact failing branch and matches the traceback seen in the real COM/UI Automation scenario.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions