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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions