From: John Marriott Date: Wed, 17 Dec 2025 21:31:59 +0000 (+0100) Subject: patch 9.1.1997: Missing out-of-memory check in vim9class.c X-Git-Tag: v9.1.1997^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de701aee9f67d7c50e8b88c862f55a84de742b15;p=thirdparty%2Fvim.git patch 9.1.1997: Missing out-of-memory check in vim9class.c Problem: Missing out-of-memory check in vim9class.c in calls to vim_strnsave(). Solution: Refactor is_duplicate_variable() and is_duplicate_enum() and make use of string_T struct instead (John Marriott). closes: #18947 Signed-off-by: John Marriott Signed-off-by: Christian Brabandt --- diff --git a/src/version.c b/src/version.c index 1ae59e0fda..a8783de4b1 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1997, /**/ 1996, /**/ diff --git a/src/vim9class.c b/src/vim9class.c index d6a579cadb..315ba46964 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -1024,10 +1024,20 @@ is_duplicate_variable( char_u *varname, char_u *varname_end) { - char_u *name = vim_strnsave(varname, varname_end - varname); - char_u *pstr = (*name == '_') ? name + 1 : name; + string_T pstr = {varname, (size_t)(varname_end - varname)}; // Note: the .string field may + // point to a string longer + // than the .length field. + // So we need to use STRNCMP() + // to compare it. int dup = FALSE; + // Step over a leading '_'. + if (*pstr.string == '_') + { + pstr.string++; + pstr.length--; + } + for (int loop = 1; loop <= 2; loop++) { // loop == 1: class variables, loop == 2: object variables @@ -1037,16 +1047,20 @@ is_duplicate_variable( ocmember_T *m = ((ocmember_T *)vgap->ga_data) + i; char_u *qstr = *m->ocm_name == '_' ? m->ocm_name + 1 : m->ocm_name; - if (STRCMP(pstr, qstr) == 0) + if (STRNCMP(pstr.string, qstr, pstr.length) == 0 + && qstr[pstr.length] == NUL) { - semsg(_(e_duplicate_variable_str), name); + char_u save_c = *varname_end; + + *varname_end = NUL; + semsg(_(e_duplicate_variable_str), varname); + *varname_end = save_c; dup = TRUE; break; } } } - vim_free(name); return dup; } @@ -1627,21 +1641,29 @@ is_duplicate_enum( char_u *varname, char_u *varname_end) { - char_u *name = vim_strnsave(varname, varname_end - varname); + string_T name = {varname, (size_t)(varname_end - varname)}; // Note: the .string field may + // point to a string longer + // than the .length field. + // So we need to use STRNCMP() + // to compare it. int dup = FALSE; for (int i = 0; i < enum_gap->ga_len; ++i) { ocmember_T *m = ((ocmember_T *)enum_gap->ga_data) + i; - if (STRCMP(name, m->ocm_name) == 0) + if (STRNCMP(name.string, m->ocm_name, name.length) == 0 + && m->ocm_name[name.length] == NUL) { - semsg(_(e_duplicate_enum_str), name); + char_u save_c = *varname_end; + + *varname_end = NUL; + semsg(_(e_duplicate_enum_str), varname); + *varname_end = save_c; dup = TRUE; break; } } - vim_free(name); return dup; }