enthought / enthought/comtypes

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

Open
#935 9 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
Python
Stars
345
Forks
105
PR merge metrics
No merged PRs in 30d

Description

## 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`:

```python
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`:

```text
Traceback (most recent call last):
File "", line 10, in
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:

```python
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.