# HG changeset patch # User Bram Moolenaar # Date 1302533795 -7200 # Node ID c5e47b752f07a95534bbfa83f031a58af67054cb # Parent 9d6d058f0ebb3874c9e72372a0d588af7413b429 updated for version 7.3.160 Problem: Unsafe string copying. Solution: Use vim_strncpy() instead of strcpy(). Use vim_strcat() instead of strcat(). diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -3176,7 +3176,7 @@ maketitle() /* format: "fname + (path) (1 of 2) - VIM" */ if (curbuf->b_fname == NULL) - STRCPY(buf, _("[No Name]")); + vim_strncpy(buf, (char_u *)_("[No Name]"), IOSIZE - 100); else { p = transstr(gettail(curbuf->b_fname)); @@ -3232,7 +3232,7 @@ maketitle() if (serverName != NULL) { STRCAT(buf, " - "); - STRCAT(buf, serverName); + vim_strcat(buf, serverName, IOSIZE); } else #endif diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -5096,7 +5096,9 @@ check_more(message, forceit) char_u buff[IOSIZE]; if (n == 1) - STRCPY(buff, _("1 more file to edit. Quit anyway?")); + vim_strncpy(buff, + (char_u *)_("1 more file to edit. Quit anyway?"), + IOSIZE - 1); else vim_snprintf((char *)buff, IOSIZE, _("%d more files to edit. Quit anyway?"), n); diff --git a/src/hardcopy.c b/src/hardcopy.c --- a/src/hardcopy.c +++ b/src/hardcopy.c @@ -1761,12 +1761,12 @@ prt_find_resource(name, resource) { char_u buffer[MAXPATHL + 1]; - STRCPY(resource->name, name); + vim_strncpy(resource->name, (char_u *)name, 63); /* Look for named resource file in runtimepath */ STRCPY(buffer, "print"); add_pathsep(buffer); - STRCAT(buffer, name); - STRCAT(buffer, ".ps"); + vim_strcat(buffer, (char_u *)name, MAXPATHL); + vim_strcat(buffer, (char_u *)".ps", MAXPATHL); resource->filename[0] = NUL; return (do_in_runtimepath(buffer, FALSE, prt_resource_name, resource->filename) diff --git a/src/menu.c b/src/menu.c --- a/src/menu.c +++ b/src/menu.c @@ -1394,7 +1394,8 @@ get_menu_names(xp, idx) int idx; { static vimmenu_T *menu = NULL; - static char_u tbuffer[256]; /*hack*/ +#define TBUFFER_LEN 256 + static char_u tbuffer[TBUFFER_LEN]; /*hack*/ char_u *str; #ifdef FEAT_MULTI_LANG static int should_advance = FALSE; @@ -1428,11 +1429,11 @@ get_menu_names(xp, idx) { #ifdef FEAT_MULTI_LANG if (should_advance) - STRCPY(tbuffer, menu->en_dname); + vim_strncpy(tbuffer, menu->en_dname, TBUFFER_LEN - 2); else { #endif - STRCPY(tbuffer, menu->dname); + vim_strncpy(tbuffer, menu->dname, TBUFFER_LEN - 2); #ifdef FEAT_MULTI_LANG if (menu->en_dname == NULL) should_advance = TRUE; diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -3332,19 +3332,23 @@ msgmore(n) if (pn == 1) { if (n > 0) - STRCPY(msg_buf, _("1 more line")); + vim_strncpy(msg_buf, (char_u *)_("1 more line"), + MSG_BUF_LEN - 1); else - STRCPY(msg_buf, _("1 line less")); + vim_strncpy(msg_buf, (char_u *)_("1 line less"), + MSG_BUF_LEN - 1); } else { if (n > 0) - sprintf((char *)msg_buf, _("%ld more lines"), pn); + vim_snprintf((char *)msg_buf, MSG_BUF_LEN, + _("%ld more lines"), pn); else - sprintf((char *)msg_buf, _("%ld fewer lines"), pn); + vim_snprintf((char *)msg_buf, MSG_BUF_LEN, + _("%ld fewer lines"), pn); } if (got_int) - STRCAT(msg_buf, _(" (Interrupted)")); + vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN); if (msg(msg_buf)) { set_keep_msg(msg_buf, 0); diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -1647,6 +1647,28 @@ vim_strncpy(to, from, len) } /* + * Like strcat(), but make sure the result fits in "tosize" bytes and is + * always NUL terminated. + */ + void +vim_strcat(to, from, tosize) + char_u *to; + char_u *from; + size_t tosize; +{ + size_t tolen = STRLEN(to); + size_t fromlen = STRLEN(from); + + if (tolen + fromlen + 1 > tosize) + { + mch_memmove(to + tolen, from, tosize - tolen - 1); + to[tosize - 1] = NUL; + } + else + STRCPY(to + tolen, from); +} + +/* * Isolate one part of a string option where parts are separated with * "sep_chars". * The part is copied into "buf[maxlen]". diff --git a/src/netbeans.c b/src/netbeans.c --- a/src/netbeans.c +++ b/src/netbeans.c @@ -3914,14 +3914,12 @@ print_save_msg(buf, nchars) } else { - char_u ebuf[BUFSIZ]; - - STRCPY(ebuf, (char_u *)_("E505: ")); - STRCAT(ebuf, IObuff); - STRCAT(ebuf, (char_u *)_("is read-only (add ! to override)")); - STRCPY(IObuff, ebuf); - nbdebug((" %s\n", ebuf )); - emsg(IObuff); + char_u msgbuf[IOSIZE]; + + vim_snprintf((char *)msgbuf, IOSIZE, + _("E505: %s is read-only (add ! to override)"), IObuff); + nbdebug((" %s\n", msgbuf)); + emsg(msgbuf); } } diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5725,6 +5725,7 @@ mch_expand_wildcards(num_pat, pat, num_f if (shell_style == STYLE_PRINT && !did_find_nul) { /* If there is a NUL, set did_find_nul, else set check_spaces */ + buffer[len] = NUL; if (len && (int)STRLEN(buffer) < (int)len - 1) did_find_nul = TRUE; else @@ -6594,7 +6595,7 @@ do_xterm_trace() xterm_hints.x = 2; return TRUE; } - if (mouse_code == NULL) + if (mouse_code == NULL || STRLEN(mouse_code) > 45) { xterm_trace = 0; return FALSE; diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -40,6 +40,7 @@ void copy_spaces __ARGS((char_u *ptr, si void copy_chars __ARGS((char_u *ptr, size_t count, int c)); void del_trailing_spaces __ARGS((char_u *ptr)); void vim_strncpy __ARGS((char_u *to, char_u *from, size_t len)); +void vim_strcat __ARGS((char_u *to, char_u *from, size_t tosize)); int copy_option_part __ARGS((char_u **option, char_u *buf, int maxlen, char *sep_chars)); void vim_free __ARGS((void *x)); int vim_stricmp __ARGS((char *s1, char *s2)); diff --git a/src/spell.c b/src/spell.c --- a/src/spell.c +++ b/src/spell.c @@ -6957,7 +6957,7 @@ store_aff_word(spin, word, afflist, affi if (ae->ae_add == NULL) *newword = NUL; else - STRCPY(newword, ae->ae_add); + vim_strncpy(newword, ae->ae_add, MAXWLEN - 1); p = word; if (ae->ae_chop != NULL) { @@ -6978,7 +6978,7 @@ store_aff_word(spin, word, afflist, affi else { /* suffix: chop/add at the end of the word */ - STRCPY(newword, word); + vim_strncpy(newword, word, MAXWLEN - 1); if (ae->ae_chop != NULL) { /* Remove chop string. */ @@ -8654,7 +8654,7 @@ spell_make_sugfile(spin, wfname) * Write the .sug file. * Make the file name by changing ".spl" to ".sug". */ - STRCPY(fname, wfname); + vim_strncpy(fname, wfname, MAXPATHL - 1); len = (int)STRLEN(fname); fname[len - 2] = 'u'; fname[len - 1] = 'g'; @@ -10261,7 +10261,7 @@ spell_suggest(count) /* The suggested word may replace only part of the bad word, add * the not replaced part. */ - STRCPY(wcopy, stp->st_word); + vim_strncpy(wcopy, stp->st_word, MAXWLEN); if (sug.su_badlen > stp->st_orglen) vim_strncpy(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen, @@ -13162,7 +13162,7 @@ stp_sal_score(stp, su, slang, badsound) pbad = badsound2; } - if (lendiff > 0) + if (lendiff > 0 && stp->st_wordlen + lendiff < MAXWLEN) { /* Add part of the bad word to the good word, so that we soundfold * what replaces the bad word. */ @@ -13875,7 +13875,7 @@ check_suggestions(su, gap) for (i = gap->ga_len - 1; i >= 0; --i) { /* Need to append what follows to check for "the the". */ - STRCPY(longword, stp[i].st_word); + vim_strncpy(longword, stp[i].st_word, MAXWLEN); len = stp[i].st_wordlen; vim_strncpy(longword + len, su->su_badptr + stp[i].st_orglen, MAXWLEN - len); @@ -14221,7 +14221,7 @@ spell_soundfold_sal(slang, inword, res) *t = NUL; } else - STRCPY(word, s); + vim_strncpy(word, s, MAXWLEN - 1); smp = (salitem_T *)slang->sl_sal.ga_data; diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -8576,8 +8576,8 @@ highlight_list_arg(id, didh, type, iarg, if (iarg & hl_attr_table[i]) { if (buf[0] != NUL) - STRCAT(buf, ","); - STRCAT(buf, hl_name_table[i]); + vim_strcat(buf, (char_u *)",", 100); + vim_strcat(buf, (char_u *)hl_name_table[i], 100); iarg &= ~hl_attr_table[i]; /* don't want "inverse" */ } } diff --git a/src/tag.c b/src/tag.c --- a/src/tag.c +++ b/src/tag.c @@ -806,7 +806,7 @@ do_tag(tag, type, count, forceit, verbos p = tag_full_fname(&tagp); if (p == NULL) continue; - STRCPY(fname, p); + vim_strncpy(fname, p, MAXPATHL); vim_free(p); /* diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -715,6 +715,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 160, +/**/ 159, /**/ 158,