diff options
Diffstat (limited to 'src/nvim/option.c')
-rw-r--r-- | src/nvim/option.c | 73 |
1 files changed, 49 insertions, 24 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c index 278cf7c608..45e2032b35 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1233,7 +1233,7 @@ int do_set(char_u *arg, int opt_flags) } errmsg = set_bool_option(opt_idx, varp, (int)value, - opt_flags); + opt_flags); } else { // Numeric or string. if (vim_strchr((const char_u *)"=:&<", nextchar) == NULL || prefix != 1) { @@ -2315,8 +2315,8 @@ static bool valid_spellfile(const char_u *val) /// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL /// @param value_checked value was checked to be safe, no need to set P_INSECURE static char *did_set_string_option(int opt_idx, char_u **varp, bool new_value_alloced, - char_u *oldval, char *errbuf, size_t errbuflen, - int opt_flags, int *value_checked) + char_u *oldval, char *errbuf, size_t errbuflen, int opt_flags, + int *value_checked) { char *errmsg = NULL; char_u *s, *p; @@ -2625,7 +2625,7 @@ ambw_end: } } } else if (gvarp == &p_com) { // 'comments' - for (s = *varp; *s; ) { + for (s = *varp; *s;) { while (*s && *s != ':') { if (vim_strchr((char_u *)COM_ALL, *s) == NULL && !ascii_isdigit(*s) && *s != '-') { @@ -2704,7 +2704,7 @@ ambw_end: // there would be a disconnect between the check for P_ALLOCED at the start // of the function and the set of P_ALLOCED at the end of the function. free_oldval = (options[opt_idx].flags & P_ALLOCED); - for (s = p_shada; *s; ) { + for (s = p_shada; *s;) { // Check it's a valid character if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL) { errmsg = illegal_char(errbuf, errbuflen, *s); @@ -2749,7 +2749,7 @@ ambw_end: errmsg = N_("E528: Must specify a ' value"); } } else if (gvarp == &p_sbr) { // 'showbreak' - for (s = *varp; *s; ) { + for (s = *varp; *s;) { if (ptr2cells(s) != 1) { errmsg = N_("E595: 'showbreak' contains unprintable or wide character"); } @@ -2893,7 +2893,7 @@ ambw_end: } } else if (gvarp == &p_cpt) { // check if it is a valid value for 'complete' -- Acevedo - for (s = *varp; *s; ) { + for (s = *varp; *s;) { while (*s == ',' || *s == ' ') { s++; } @@ -3369,7 +3369,7 @@ char *check_colorcolumn(win_T *wp) return NULL; // buffer was closed } - for (s = wp->w_p_cc; *s != NUL && count < 255; ) { + for (s = wp->w_p_cc; *s != NUL && count < 255;) { if (*s == '-' || *s == '+') { // -N and +N: add to 'textwidth' col = (*s == '-') ? -1 : 1; @@ -3436,6 +3436,37 @@ void check_blending(win_T *wp) wp->w_p_winbl > 0 || (wp->w_floating && wp->w_float_config.shadow); } +/// Calls mb_cptr2char_adv(p) and returns the character. +/// If "p" starts with "\x", "\u" or "\U" the hex or unicode value is used. +/// Returns 0 for invalid hex or invalid UTF-8 byte. +static int get_encoded_char_adv(char_u **p) +{ + char_u *s = *p; + + if (s[0] == '\\' && (s[1] == 'x' || s[1] == 'u' || s[1] == 'U')) { + int64_t num = 0; + int bytes; + int n; + for (bytes = s[1] == 'x' ? 1 : s[1] == 'u' ? 2 : 4; bytes > 0; bytes--) { + *p += 2; + n = hexhex2nr(*p); + if (n < 0) { + return 0; + } + num = num * 256 + n; + } + *p += 2; + return (int)num; + } + + // TODO(bfredl): use schar_T representation and utfc_ptr2len + int clen = utf_ptr2len(s); + int c = mb_cptr2char_adv((const char_u **)p); + if (clen == 1 && c > 127) { // Invalid UTF-8 byte + return 0; + } + return c; +} /// Handle setting 'listchars' or 'fillchars'. /// Assume monocell characters @@ -3540,26 +3571,21 @@ static char *set_chars_option(win_T *wp, char_u **varp, bool set) && p[len + 1] != NUL) { c2 = c3 = 0; s = p + len + 1; - - // TODO(bfredl): use schar_T representation and utfc_ptr2len - int c1len = utf_ptr2len(s); - c1 = mb_cptr2char_adv((const char_u **)&s); - if (utf_char2cells(c1) > 1 || (c1len == 1 && c1 > 127)) { + c1 = get_encoded_char_adv(&s); + if (c1 == 0 || utf_char2cells(c1) > 1) { return e_invarg; } if (tab[i].cp == &wp->w_p_lcs_chars.tab2) { if (*s == NUL) { return e_invarg; } - int c2len = utf_ptr2len(s); - c2 = mb_cptr2char_adv((const char_u **)&s); - if (utf_char2cells(c2) > 1 || (c2len == 1 && c2 > 127)) { + c2 = get_encoded_char_adv(&s); + if (c2 == 0 || utf_char2cells(c2) > 1) { return e_invarg; } if (!(*s == ',' || *s == NUL)) { - int c3len = utf_ptr2len(s); - c3 = mb_cptr2char_adv((const char_u **)&s); - if (utf_char2cells(c3) > 1 || (c3len == 1 && c3 > 127)) { + c3 = get_encoded_char_adv(&s); + if (c3 == 0 || utf_char2cells(c3) > 1) { return e_invarg; } } @@ -3592,9 +3618,8 @@ static char *set_chars_option(win_T *wp, char_u **varp, bool set) last_multispace = p; multispace_len = 0; while (*s != NUL && *s != ',') { - int c1len = utf_ptr2len(s); - c1 = mb_cptr2char_adv((const char_u **)&s); - if (utf_char2cells(c1) > 1 || (c1len == 1 && c1 > 127)) { + c1 = get_encoded_char_adv(&s); + if (c1 == 0 || utf_char2cells(c1) > 1) { return e_invarg; } multispace_len++; @@ -3607,7 +3632,7 @@ static char *set_chars_option(win_T *wp, char_u **varp, bool set) } else { int multispace_pos = 0; while (*s != NUL && *s != ',') { - c1 = mb_cptr2char_adv((const char_u **)&s); + c1 = get_encoded_char_adv(&s); if (p == last_multispace) { wp->w_p_lcs_chars.multispace[multispace_pos++] = c1; } @@ -6793,7 +6818,7 @@ static void langmap_set(void) ga_clear(&langmap_mapga); // clear the previous map first langmap_init(); // back to one-to-one map - for (p = p_langmap; p[0] != NUL; ) { + for (p = p_langmap; p[0] != NUL;) { for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';'; MB_PTR_ADV(p2)) { if (p2[0] == '\\' && p2[1] != NUL) { |