aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/regexp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/regexp.c')
-rw-r--r--src/nvim/regexp.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 8151d2e12a..dc7ff30513 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -7,9 +7,11 @@
// #define REGEXP_DEBUG
#include <assert.h>
+#include <ctype.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
+#include <stddef.h>
#include <string.h>
#include <sys/types.h>
@@ -22,6 +24,7 @@
#include "nvim/garray.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
+#include "nvim/grid_defs.h"
#include "nvim/keycodes.h"
#include "nvim/macros.h"
#include "nvim/mark.h"
@@ -1291,9 +1294,7 @@ static bool reg_match_visual(void)
rex.line = (uint8_t *)reg_getline(rex.lnum);
rex.input = rex.line + col;
- unsigned cols_u = win_linetabsize(wp, rex.reg_firstlnum + rex.lnum, (char *)rex.line, col);
- assert(cols_u <= MAXCOL);
- colnr_T cols = (colnr_T)cols_u;
+ colnr_T cols = win_linetabsize(wp, rex.reg_firstlnum + rex.lnum, (char *)rex.line, col);
if (cols < start || cols > end - (*p_sel == 'e')) {
return false;
}
@@ -1639,41 +1640,46 @@ static void do_lower(int *d, int c)
char *regtilde(char *source, int magic, bool preview)
{
char *newsub = source;
- char *tmpsub;
- char *p;
- int len;
- int prevlen;
- for (p = newsub; *p; p++) {
+ for (char *p = newsub; *p; p++) {
if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic)) {
if (reg_prev_sub != NULL) {
// length = len(newsub) - 1 + len(prev_sub) + 1
- prevlen = (int)strlen(reg_prev_sub);
- tmpsub = xmalloc(strlen(newsub) + (size_t)prevlen);
+ // Avoid making the text longer than MAXCOL, it will cause
+ // trouble at some point.
+ size_t prevsublen = strlen(reg_prev_sub);
+ size_t newsublen = strlen(newsub);
+ if (prevsublen > MAXCOL || newsublen > MAXCOL
+ || newsublen + prevsublen > MAXCOL) {
+ emsg(_(e_resulting_text_too_long));
+ break;
+ }
+
+ char *tmpsub = xmalloc(newsublen + prevsublen);
// copy prefix
- len = (int)(p - newsub); // not including ~
- memmove(tmpsub, newsub, (size_t)len);
+ size_t prefixlen = (size_t)(p - newsub); // not including ~
+ memmove(tmpsub, newsub, prefixlen);
// interpret tilde
- memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
+ memmove(tmpsub + prefixlen, reg_prev_sub, prevsublen);
// copy postfix
if (!magic) {
- p++; // back off backslash
+ p++; // back off backslash
}
- STRCPY(tmpsub + len + prevlen, p + 1);
+ STRCPY(tmpsub + prefixlen + prevsublen, p + 1);
- if (newsub != source) { // already allocated newsub
+ if (newsub != source) { // allocated newsub before
xfree(newsub);
}
newsub = tmpsub;
- p = newsub + len + prevlen;
+ p = newsub + prefixlen + prevsublen;
} else if (magic) {
- STRMOVE(p, p + 1); // remove '~'
+ STRMOVE(p, p + 1); // remove '~'
} else {
- STRMOVE(p, p + 2); // remove '\~'
+ STRMOVE(p, p + 2); // remove '\~'
}
p--;
} else {
- if (*p == '\\' && p[1]) { // skip escaped characters
+ if (*p == '\\' && p[1]) { // skip escaped characters
p++;
}
p += utfc_ptr2len(p) - 1;
@@ -6021,11 +6027,10 @@ static bool regmatch(uint8_t *scan, proftime_T *tm, int *timed_out)
break;
case RE_VCOL:
- if (!re_num_cmp(win_linetabsize(rex.reg_win == NULL
- ? curwin : rex.reg_win,
- rex.reg_firstlnum + rex.lnum,
- (char *)rex.line,
- (colnr_T)(rex.input - rex.line)) + 1,
+ if (!re_num_cmp((unsigned)win_linetabsize(rex.reg_win == NULL ? curwin : rex.reg_win,
+ rex.reg_firstlnum + rex.lnum,
+ (char *)rex.line,
+ (colnr_T)(rex.input - rex.line)) + 1,
scan)) {
status = RA_NOMATCH;
}
@@ -14746,9 +14751,9 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm
result = col > t->state->val * ts;
}
if (!result) {
- uintmax_t lts = win_linetabsize(wp, rex.reg_firstlnum + rex.lnum, (char *)rex.line, col);
+ int lts = win_linetabsize(wp, rex.reg_firstlnum + rex.lnum, (char *)rex.line, col);
assert(t->state->val >= 0);
- result = nfa_re_num_cmp((uintmax_t)t->state->val, op, lts + 1);
+ result = nfa_re_num_cmp((uintmax_t)t->state->val, op, (uintmax_t)lts + 1);
}
if (result) {
add_here = true;