Skip to content

Commit 807d71a

Browse files
authored
Merge pull request #94 from DTW-Thalion/fix/cfcharacterset-range
CFCharacterSet: fix off-by-one in character range operations
2 parents eb20602 + e891d06 commit 807d71a

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

‎Source/CFCharacterSet.c‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ CFCharacterSetCreateWithCharactersInRange (CFAllocatorRef alloc,
140140
_kCFCharacterSetTypeID, CFCHARACTERSET_SIZE, 0);
141141
if (new)
142142
{
143-
new->_uset = uset_open ((UChar32)range.location,
144-
(UChar32)(range.location + range.length));
143+
if (range.length <= 0)
144+
new->_uset = uset_openEmpty ();
145+
else
146+
new->_uset = uset_open ((UChar32)range.location,
147+
(UChar32)(range.location + range.length - 1));
145148
uset_freeze (new->_uset);
146149
}
147150

@@ -378,8 +381,10 @@ void
378381
CFCharacterSetAddCharactersInRange (CFMutableCharacterSetRef set,
379382
CFRange range)
380383
{
384+
if (range.length <= 0)
385+
return;
381386
uset_addRange (set->_uset, (UChar32)range.location,
382-
(UChar32)(range.location + range.length));
387+
(UChar32)(range.location + range.length - 1));
383388
}
384389

385390
void
@@ -393,8 +398,10 @@ void
393398
CFCharacterSetRemoveCharactersInRange (CFMutableCharacterSetRef set,
394399
CFRange range)
395400
{
401+
if (range.length <= 0)
402+
return;
396403
uset_removeRange (set->_uset, (UChar32)range.location,
397-
(UChar32)(range.location + range.length));
404+
(UChar32)(range.location + range.length - 1));
398405
}
399406

400407
void

‎Tests/CFCharacterSet/range.m‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "CoreFoundation/CFCharacterSet.h"
2+
#include "../CFTesting.h"
3+
4+
int main (void)
5+
{
6+
CFCharacterSetRef s;
7+
CFMutableCharacterSetRef m;
8+
9+
s = CFCharacterSetCreateWithCharactersInRange (NULL, CFRangeMake ('A', 3));
10+
PASS_CF(CFCharacterSetIsCharacterMember (s, 'A')
11+
&& CFCharacterSetIsCharacterMember (s, 'C')
12+
&& !CFCharacterSetIsCharacterMember (s, 'D'),
13+
"CFCharacterSetCreateWithCharactersInRange includes exactly the range.");
14+
CFRelease (s);
15+
16+
s = CFCharacterSetCreateWithCharactersInRange (NULL, CFRangeMake ('A', 0));
17+
PASS_CF(!CFCharacterSetIsCharacterMember (s, 'A'),
18+
"CFCharacterSetCreateWithCharactersInRange of an empty range is empty.");
19+
CFRelease (s);
20+
21+
s = CFCharacterSetCreateWithCharactersInRange (NULL, CFRangeMake (0x1F600, 1));
22+
PASS_CF(CFCharacterSetIsLongCharacterMember (s, 0x1F600)
23+
&& !CFCharacterSetIsLongCharacterMember (s, 0x1F601),
24+
"CFCharacterSetIsLongCharacterMember matches exactly a one-character range.");
25+
CFRelease (s);
26+
27+
m = CFCharacterSetCreateMutable (NULL);
28+
CFCharacterSetAddCharactersInRange (m, CFRangeMake ('0', 2));
29+
PASS_CF(CFCharacterSetIsCharacterMember (m, '0')
30+
&& CFCharacterSetIsCharacterMember (m, '1')
31+
&& !CFCharacterSetIsCharacterMember (m, '2'),
32+
"CFCharacterSetAddCharactersInRange adds exactly the range.");
33+
34+
CFCharacterSetAddCharactersInString (m, CFSTR("xy"));
35+
CFCharacterSetRemoveCharactersInRange (m, CFRangeMake ('x', 1));
36+
PASS_CF(!CFCharacterSetIsCharacterMember (m, 'x')
37+
&& CFCharacterSetIsCharacterMember (m, 'y'),
38+
"CFCharacterSetRemoveCharactersInRange removes exactly the range.");
39+
CFRelease (m);
40+
41+
return 0;
42+
}

0 commit comments

Comments
 (0)