comparison src/memline.c @ 15255:19e79a1ed6b6 v8.1.0636

patch 8.1.0636: line2byte() gives wrong values with text properties commit https://github.com/vim/vim/commit/b413d2e6a8cc7b1611a41bfa9462b986393ca5fe Author: Bram Moolenaar <Bram@vim.org> Date: Tue Dec 25 23:15:46 2018 +0100 patch 8.1.0636: line2byte() gives wrong values with text properties Problem: line2byte() gives wrong values with text properties. (Bjorn Linse) Solution: Compute byte offsets differently when text properties were added. (closes #3718)
author Bram Moolenaar <Bram@vim.org>
date Tue, 25 Dec 2018 23:30:07 +0100
parents 4b2de998ebd6
children 762fccd84b7c
comparison
equal deleted inserted replaced
15254:7790044a7348 15255:19e79a1ed6b6
3177 // another line is buffered, flush it 3177 // another line is buffered, flush it
3178 ml_flush_line(curbuf); 3178 ml_flush_line(curbuf);
3179 curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY; 3179 curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
3180 3180
3181 #ifdef FEAT_TEXT_PROP 3181 #ifdef FEAT_TEXT_PROP
3182 if (has_any_text_properties(curbuf)) 3182 if (curbuf->b_has_textprop)
3183 // Need to fetch the old line to copy over any text properties. 3183 // Need to fetch the old line to copy over any text properties.
3184 ml_get_buf(curbuf, lnum, TRUE); 3184 ml_get_buf(curbuf, lnum, TRUE);
3185 #endif 3185 #endif
3186 } 3186 }
3187 3187
3188 #ifdef FEAT_TEXT_PROP 3188 #ifdef FEAT_TEXT_PROP
3189 if (has_any_text_properties(curbuf)) 3189 if (curbuf->b_has_textprop)
3190 { 3190 {
3191 size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1; 3191 size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1;
3192 3192
3193 if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len) 3193 if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len)
3194 { 3194 {
5129 5129
5130 if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) 5130 if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL)
5131 { 5131 {
5132 int count; /* number of entries in block */ 5132 int count; /* number of entries in block */
5133 int idx; 5133 int idx;
5134 int end_idx;
5134 int text_end; 5135 int text_end;
5135 int linecnt; 5136 int linecnt;
5136 5137
5137 mch_memmove(buf->b_ml.ml_chunksize + curix + 1, 5138 mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
5138 buf->b_ml.ml_chunksize + curix, 5139 buf->b_ml.ml_chunksize + curix,
5152 dp = (DATA_BL *)(hp->bh_data); 5153 dp = (DATA_BL *)(hp->bh_data);
5153 count = (long)(buf->b_ml.ml_locked_high) - 5154 count = (long)(buf->b_ml.ml_locked_high) -
5154 (long)(buf->b_ml.ml_locked_low) + 1; 5155 (long)(buf->b_ml.ml_locked_low) + 1;
5155 idx = curline - buf->b_ml.ml_locked_low; 5156 idx = curline - buf->b_ml.ml_locked_low;
5156 curline = buf->b_ml.ml_locked_high + 1; 5157 curline = buf->b_ml.ml_locked_high + 1;
5157 if (idx == 0)/* first line in block, text at the end */ 5158
5158 text_end = dp->db_txt_end; 5159 // compute index of last line to use in this MEMLINE
5159 else
5160 text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
5161 /* Compute index of last line to use in this MEMLINE */
5162 rest = count - idx; 5160 rest = count - idx;
5163 if (linecnt + rest > MLCS_MINL) 5161 if (linecnt + rest > MLCS_MINL)
5164 { 5162 {
5165 idx += MLCS_MINL - linecnt - 1; 5163 end_idx = idx + MLCS_MINL - linecnt - 1;
5166 linecnt = MLCS_MINL; 5164 linecnt = MLCS_MINL;
5167 } 5165 }
5168 else 5166 else
5169 { 5167 {
5170 idx = count - 1; 5168 end_idx = count - 1;
5171 linecnt += rest; 5169 linecnt += rest;
5172 } 5170 }
5173 size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK); 5171 #ifdef FEAT_TEXT_PROP
5172 if (buf->b_has_textprop)
5173 {
5174 int i;
5175
5176 // We cannot use the text pointers to get the text length,
5177 // the text prop info would also be counted. Go over the
5178 // lines.
5179 for (i = end_idx; i < idx; ++i)
5180 size += STRLEN((char_u *)dp + (dp->db_index[i] & DB_INDEX_MASK)) + 1;
5181 }
5182 else
5183 #endif
5184 {
5185 if (idx == 0)/* first line in block, text at the end */
5186 text_end = dp->db_txt_end;
5187 else
5188 text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
5189 size += text_end - ((dp->db_index[end_idx]) & DB_INDEX_MASK);
5190 }
5174 } 5191 }
5175 buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt; 5192 buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
5176 buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt; 5193 buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
5177 buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size; 5194 buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
5178 buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size; 5195 buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
5358 break; 5375 break;
5359 } 5376 }
5360 idx++; 5377 idx++;
5361 } 5378 }
5362 } 5379 }
5363 len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK); 5380 #ifdef FEAT_TEXT_PROP
5381 if (buf->b_has_textprop)
5382 {
5383 int i;
5384
5385 // cannot use the db_index pointer, need to get the actual text
5386 // lengths.
5387 len = 0;
5388 for (i = start_idx; i <= idx; ++i)
5389 len += STRLEN((char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK)) + 1;
5390 }
5391 else
5392 #endif
5393 len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
5364 size += len; 5394 size += len;
5365 if (offset != 0 && size >= offset) 5395 if (offset != 0 && size >= offset)
5366 { 5396 {
5367 if (size + ffdos == offset) 5397 if (size + ffdos == offset)
5368 *offp = 0; 5398 *offp = 0;