Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/hwpx/oxml/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,17 @@ def _serialize_xml(element: ET.Element) -> bytes:

def _paragraph_id() -> str:
"""Generate an identifier for a new paragraph element."""
return str(uuid4().int & 0xFFFFFFFF)
return str(uuid4().int & 0x7FFFFFFF)


def _object_id() -> str:
"""Generate an identifier suitable for table and shape objects."""
return str(uuid4().int & 0xFFFFFFFF)
return str(uuid4().int & 0x7FFFFFFF)


def _memo_id() -> str:
"""Generate a lightweight identifier for memo elements."""
return str(uuid4().int & 0xFFFFFFFF)
return str(uuid4().int & 0x7FFFFFFF)


def _refresh_copied_paragraph_subtree_ids(paragraph: ET.Element) -> None:
Expand Down
32 changes: 32 additions & 0 deletions tests/test_id_generator_range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations

from hwpx.oxml.document import _memo_id, _object_id, _paragraph_id


_GENERATORS = (_paragraph_id, _object_id, _memo_id)


def test_id_generators_stay_within_signed_int32() -> None:
"""Generated IDs must fit in signed int32 so downstream consumers that
parse the ``id`` attribute as ``int`` see a non-negative value."""

for gen in _GENERATORS:
for _ in range(200):
value = int(gen())
assert 0 <= value < 2**31, (
f"{gen.__name__} produced {value} (0x{value:x}); "
"must be in [0, 2^31)"
)


def test_id_generators_use_full_31_bit_range() -> None:
"""The generators should still draw from a wide range so collisions
remain negligible. Sample 4_000 values and require at least one above
2^30 to guard against accidental over-restriction."""

for gen in _GENERATORS:
samples = [int(gen()) for _ in range(4000)]
assert max(samples) >= 2**30, (
f"{gen.__name__} samples capped at {max(samples):#x}; "
"expected the full [0, 2^31) range"
)
Loading