Skip to content

Fix: CFAttributedString substring, attribute removal and replacement - #152

Open
DTW-Thalion wants to merge 2 commits into
gnustep:masterfrom
DTW-Thalion:fix-cfattributedstring-backlog
Open

Fix: CFAttributedString substring, attribute removal and replacement#152
DTW-Thalion wants to merge 2 commits into
gnustep:masterfrom
DTW-Thalion:fix-cfattributedstring-backlog

Conversation

@DTW-Thalion

Copy link
Copy Markdown
Contributor

CFAttributedStringCreateWithSubstring built its result by replacing the
copy's characters with the source's whole string and then applying the
source effective ranges directly, which reached past the end of the
shorter copy. It now seeds the copy from the substring over range and
shifts each source run into the copy's coordinates.

CFAttributedStringRemoveAttribute and CFAttributedStringReplaceAttributedString
were empty. The first removes the named attribute from every run
overlapping the range and leaves the other attributes in place. The
second replaces the characters in the range and applies the replacement
string's own attributes over them.

CFAttributedStringCreateInlined recorded a run count of one and numbered
the runs from zero, so CFAttributedStringCreateCopy collapsed any string
with more than one run onto its first run. It now stores the real run
count and each run's own start index.

Tests/CFAttributedString/backlog.m covers the three functions against
values taken from Apple CoreFoundation.

Dependencies and merge order

This builds on two other open pull requests and cannot stand alone. The
substring and removal paths go through the clearing branch of
CFAttributedStringSetAttributes (fixed in #150) and the multi-run run
storage (fixed in #151).

Merge order: #150 and #151 first (either order), then this one.

The branch is stacked on #151, so this diff currently also contains
#151's commit and the single ReplaceAttributesAtIndex line from #150.
Once #150 and #151 land I will rebase this onto master, after which it
reduces to the four changes above plus backlog.m. Please do not merge
this before #150 and #151.

Setting an attribute across a string that holds two or more runs
crashed.  GSBSearch set its upper bound to mid - 1, skipping index 0
and returning -1 for any key below the first entry, and the callers
indexed the run array with that value.  Restore the usual binary
search bound.

The mutable and immutable instance sizes subtracted the struct size
from CFRuntimeClass instead of subtracting CFRuntimeBase from the
struct.  Instances were allocated too small and _isEditing held
garbage.  Correct both size macros and initialise _isEditing.

The attribute cache is a bag keyed on the set pointer.  Reusing a
cached set left its count unchanged, so releasing one run freed a set
that another run still referenced.  Count cached references through a
new GSHashTableAddValueCounted, and give CFBag the same counting so a
repeated value raises its multiplicity.

Growing and shrinking the run array used the wrong element count and
left the capacity stale, and coalescing adjacent equal runs read past
the start of the array.  Correct the reallocation sizes and the
coalesce bounds.

Implement CFAttributedStringGetAttributeAndLongestEffectiveRange and
CFAttributedStringGetAttributesAndLongestEffectiveRange, which
returned NULL.
…ment

CFAttributedStringCreateWithSubstring built its result by replacing the
copy's characters with the source's whole string and then applying the
source effective ranges directly, which reached past the end of the
shorter copy.  Seed the copy from the substring over range and shift each
source run into the copy's coordinates.

CFAttributedStringRemoveAttribute and CFAttributedStringReplaceAttributedString
were empty.  Remove the named attribute from every run overlapping the
range, and splice the replacement string's characters and its own
attributes into the range.

CFAttributedStringCreateInlined stored a run count of one and numbered the
runs from zero, so copying a string that held more than one run collapsed
it onto the first run.  Store the real run count and each run's own start
index.
@DTW-Thalion
DTW-Thalion force-pushed the fix-cfattributedstring-backlog branch from 4cbb9bb to 2de51ed Compare July 24, 2026 15:22
@DTW-Thalion DTW-Thalion reopened this Jul 24, 2026
@DTW-Thalion DTW-Thalion reopened this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant