Skip to content

Commit 431d9d0

Browse files
author
livecodeali
committed
[[ Bug 17173 ]] Correct fix to bug 17112
It is actually the responsibility of MCStringsMarkTextChunkInRange to restrict its calculated indices to the given range.
1 parent 36c45a2 commit 431d9d0

File tree

5 files changed

+89
-18
lines changed

5 files changed

+89
-18
lines changed

docs/notes/bugfix-17173.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fix processing of force-added chunks

engine/src/exec-strings-chunk.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,17 +475,15 @@ void MCStringsMarkTextChunkInRange(MCExecContext& ctxt, MCStringRef p_string, MC
475475
MCStringMapIndices(*t_string, p_chunk_type == CT_CHARACTER ? kMCCharChunkTypeGrapheme : kMCCharChunkTypeCodepoint, t_cp_range, t_cu_range);
476476

477477
r_start = t_offset + t_cu_range.offset;
478-
r_end = t_offset + t_cu_range.offset + t_cu_range.length;
479-
//r_start = p_first;
480-
//r_end = p_first + p_count;
478+
r_end = MCU_min(t_offset + t_cu_range.offset + t_cu_range.length, t_length);
481479
}
482480
break;
483481
case CT_CODEUNIT:
484482
case CT_BYTE:
485483
if (p_include_chars)
486484
{
487485
r_start = p_first + t_offset;
488-
r_end = MCU_min(p_first + t_offset + p_count, t_offset + t_length);
486+
r_end = MCU_min(p_first + t_offset + p_count, t_length);
489487
}
490488
break;
491489
default:

libfoundation/src/foundation-chunk.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,32 +113,43 @@ uindex_t MCChunkCountChunkChunksInRange(MCStringRef p_string, MCStringRef p_deli
113113
return t_count;
114114
}
115115

116-
// AL-2015-02-10: [[ Bug 14532 ]] Allow chunk extents to be counted in a given range, to prevent substring copying in text chunk resolution.
116+
// AL-2015-02-10: [[ Bug 14532 ]] Allow chunk extents to be counted in a
117+
// given range, to prevent substring copying in text chunk resolution.
118+
119+
// Note the returned r_first and r_chunk count *are* allowed to overrun
120+
// the given range - MCStringsMarkTextChunkInRange does the work of
121+
// ensuring the absolute indices are restricted accordingly.
117122
bool MCChunkGetExtentsByRangeInRange(bool p_strict, bool p_boundary_start, bool p_boundary_end, integer_t p_first, integer_t p_last, MCChunkCountCallback p_callback, void *p_context, MCRange *p_range, uindex_t& r_first, uindex_t& r_chunk_count)
118123
{
119124
int32_t t_chunk_count;
120125
uinteger_t t_count;
121126
bool t_counted;
122127
t_counted = false;
123-
124-
if (p_first < 0 || p_last < 0 || p_range != nil)
128+
129+
// If the first index is negative, count chunks and adjust accordingly.
130+
// Resolved index should be the index *before* the target first chunk.
131+
if (p_first < 0)
125132
{
126133
t_count = p_callback(p_context, p_range);
127134
t_counted = true;
128-
129-
if (p_first < 0)
130-
p_first += t_count;
131-
else
132-
p_first--;
133-
134-
if (p_last < 0)
135-
p_last += t_count + 1;
136-
else
137-
p_last = MCMin(p_last, t_count);
135+
p_first += t_count;
138136
}
139137
else
140138
p_first--;
141139

140+
// If the last index is negative, count chunks and adjust accordingly.
141+
// Resolved index should be the index of the target last chunk.
142+
if (p_last < 0)
143+
{
144+
if (!t_counted)
145+
{
146+
t_count = p_callback(p_context, p_range);
147+
t_counted = true;
148+
}
149+
150+
p_last += t_count + 1;
151+
}
152+
142153
t_chunk_count = p_last - p_first;
143154

144155
if (p_first < 0)

tests/lcs/core/chunks/compound.livecodescript

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,34 @@ on TestBug17112
2020
local tLines
2121
put "a" & return & "b" into tLines
2222
TestAssert "char range of line overrun", char 1 to 100 of line 1 of tLines is "a"
23-
end TestBug17112
23+
end TestBug17112
24+
25+
on TestPutIntoItemOfLineAdd
26+
local tLines
27+
put "a" & return & "1" into tLines
28+
put "b" into item 2 of line 1 of tLines
29+
TestAssert "force item of line addition expression", tLines is ("a,b" & return & "1")
30+
31+
put "a" & return & "1" into tLines
32+
put "b" into item 3 to 4 of line 1 of tLines
33+
TestAssert "force item of line addition range", tLines is ("a,,b" & return & "1")
34+
35+
put "a" & return & "1" into tLines
36+
put "b" into the third item of line 1 of tLines
37+
TestAssert "force item of line addition ordinal", tLines is ("a,,b" & return & "1")
38+
end TestPutIntoItemOfLineAdd
39+
40+
on TestPutIntoItemOfLineReplace
41+
local tLines
42+
put "a,b" & return & "1" into tLines
43+
put "c" into item 2 of line 1 of tLines
44+
TestAssert "item of line replacement expression", tLines is ("a,c" & return & "1")
45+
46+
put "a,b,c,d" & return & "1" into tLines
47+
put "e" into item 3 to 4 of line 1 of tLines
48+
TestAssert "item of line replacement range", tLines is ("a,b,e" & return & "1")
49+
50+
put "a,b,c" & return & "1" into tLines
51+
put "d" into the middle item of line 1 of tLines
52+
TestAssert "item of line replacement ordinal", tLines is ("a,d,c" & return & "1")
53+
end TestPutIntoItemOfLineReplace

tests/lcs/core/chunks/text.livecodescript

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,34 @@ on TestDeleteItemOfLine
2929
delete item 1 of line 2 of tLines
3030
TestAssert "delete item of line comprising item does not delete line", the number of lines in tLines is 3
3131
end TestDeleteItemOfLine
32+
33+
on TestPutIntoItemAdd
34+
local tItems
35+
put "a" into tItems
36+
put "b" into item 2 of tItems
37+
TestAssert "force item addition expression", tItems is "a,b"
38+
39+
put "a" into tItems
40+
put "b" into item 3 to 4 of tItems
41+
TestAssert "force item addition range", tItems is "a,,b"
42+
43+
put "a" into tItems
44+
put "b" into the third item of tItems
45+
TestAssert "force item addition ordinal", tItems is "a,,b"
46+
end TestPutIntoItemAdd
47+
48+
on TestPutIntoItemReplace
49+
local tItems
50+
put "a,b" into tItems
51+
put "c" into item 2 of tItems
52+
TestAssert "item replacement expression", tItems is "a,c"
53+
54+
put "a,b,c,d" into tItems
55+
put "e" into item 3 to 4 of tItems
56+
TestAssert "item replacement range", tItems is "a,b,e"
57+
58+
put "a,b,c" into tItems
59+
put "d" into the middle item of tItems
60+
TestAssert "item replacement ordinal", tItems is "a,d,c"
61+
end TestPutIntoItemReplace
62+

0 commit comments

Comments
 (0)