Skip to content

Commit 13d3b05

Browse files
committed
patch 8.0.1774: reading very long lines can be slow
Problem: Reading very long lines can be slow. Solution: Read up to 1 Mbyte at a time to avoid a lot of copying. Add a check for going over the column limit.
1 parent c36651b commit 13d3b05

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

src/fileio.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,28 +1209,42 @@ readfile(
12091209
* The amount is limited by the fact that read() only can read
12101210
* upto max_unsigned characters (and other things).
12111211
*/
1212-
#if VIM_SIZEOF_INT <= 2
1213-
if (linerest >= 0x7ff0)
1212+
if (!skip_read)
12141213
{
1215-
++split;
1216-
*ptr = NL; /* split line by inserting a NL */
1217-
size = 1;
1218-
}
1219-
else
1220-
#endif
1221-
{
1222-
if (!skip_read)
1223-
{
12241214
#if VIM_SIZEOF_INT > 2
12251215
# if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L)
12261216
size = SSIZE_MAX; /* use max I/O size, 52K */
12271217
# else
1228-
size = 0x10000L; /* use buffer >= 64K */
1218+
/* Use buffer >= 64K. Add linerest to double the size if the
1219+
* line gets very long, to avoid a lot of copying. But don't
1220+
* read more than 1 Mbyte at a time, so we can be interrupted.
1221+
*/
1222+
size = 0x10000L + linerest;
1223+
if (size > 0x100000L)
1224+
size = 0x100000L;
12291225
# endif
12301226
#else
12311227
size = 0x7ff0L - linerest; /* limit buffer to 32K */
12321228
#endif
1229+
}
12331230

1231+
/* Protect against the argument of lalloc() going negative. */
1232+
if (
1233+
#if VIM_SIZEOF_INT <= 2
1234+
linerest >= 0x7ff0
1235+
#else
1236+
size < 0 || size + linerest + 1 < 0 || linerest >= MAXCOL
1237+
#endif
1238+
)
1239+
{
1240+
++split;
1241+
*ptr = NL; /* split line by inserting a NL */
1242+
size = 1;
1243+
}
1244+
else
1245+
{
1246+
if (!skip_read)
1247+
{
12341248
for ( ; size >= 10; size = (long)((long_u)size >> 1))
12351249
{
12361250
if ((new_buffer = lalloc((long_u)(size + linerest + 1),

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1774,
764766
/**/
765767
1773,
766768
/**/

0 commit comments

Comments
 (0)