11/* Yash: yet another shell */
22/* arith.c: arithmetic expansion */
3- /* (C) 2007-2025 magicant */
3+ /* (C) 2007-2026 magicant */
44
55/* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -287,10 +287,10 @@ bool do_assignment(const word_T *word, const value_T *value)
287287 if (vstr == NULL )
288288 return false;
289289
290- wchar_t name [ word -> length + 1 ] ;
291- wmemcpy (name , word -> contents , word -> length );
292- name [ word -> length ] = L'\0' ;
293- return set_variable ( name , vstr , SCOPE_GLOBAL , false) ;
290+ wchar_t * name = xwcsndup ( word -> contents , word -> length ) ;
291+ bool ok = set_variable (name , vstr , SCOPE_GLOBAL , false );
292+ free ( name ) ;
293+ return ok ;
294294}
295295
296296/* Converts `value' to a newly-malloced wide string.
@@ -306,16 +306,21 @@ wchar_t *value_to_string(const value_T *value)
306306 return malloc_wprintf (L"%.*g" , DBL_DIG , value -> v_double );
307307 case VT_VAR :
308308 {
309- wchar_t name [value -> v_var .length + 1 ];
310- wmemcpy (name , value -> v_var .contents , value -> v_var .length );
311- name [value -> v_var .length ] = L'\0' ;
309+ wchar_t * name = xwcsndup (
310+ value -> v_var .contents , value -> v_var .length );
312311 const wchar_t * var = getvar (name );
313- if (var != NULL )
314- return xwcsdup (var );
315- if (shopt_unset )
316- return malloc_wprintf (L"%ld" , 0L );
317- xerror (0 , Ngt ("arithmetic: parameter `%ls' is not set" ), name );
318- return NULL ;
312+ wchar_t * result ;
313+ if (var != NULL ) {
314+ result = xwcsdup (var );
315+ } else if (shopt_unset ) {
316+ result = malloc_wprintf (L"%ld" , 0L );
317+ } else {
318+ xerror (0 , Ngt ("arithmetic: parameter `%ls' is not set" ),
319+ name );
320+ result = NULL ;
321+ }
322+ free (name );
323+ return result ;
319324 }
320325 }
321326 UNREACHABLE ();
@@ -1097,14 +1102,13 @@ void parse_primary(evalinfo_T *info, value_T *result)
10971102void parse_as_number (evalinfo_T * info , value_T * result )
10981103{
10991104 word_T * word = & info -> atoken .word ;
1100- wchar_t wordstr [word -> length + 1 ];
1101- wcsncpy (wordstr , word -> contents , word -> length );
1102- wordstr [word -> length ] = L'\0' ;
1105+ wchar_t * wordstr = xwcsndup (word -> contents , word -> length );
11031106
11041107 long longresult ;
11051108 if (xwcstol (wordstr , 0 , & longresult )) {
11061109 result -> type = VT_LONG ;
11071110 result -> v_long = longresult ;
1111+ free (wordstr );
11081112 return ;
11091113 }
11101114 if (!posixly_correct ) {
@@ -1118,10 +1122,12 @@ void parse_as_number(evalinfo_T *info, value_T *result)
11181122 if (ok ) {
11191123 result -> type = VT_DOUBLE ;
11201124 result -> v_double = doubleresult ;
1125+ free (wordstr );
11211126 return ;
11221127 }
11231128 }
11241129 xerror (0 , Ngt ("arithmetic: `%ls' is not a valid number" ), wordstr );
1130+ free (wordstr );
11251131 info -> error = true;
11261132 result -> type = VT_INVALID ;
11271133}
@@ -1137,17 +1143,17 @@ void coerce_number(evalinfo_T *info, value_T *value)
11371143 const wchar_t * varvalue ;
11381144 {
11391145 word_T * name = & value -> v_var ;
1140- wchar_t namestr [name -> length + 1 ];
1141- wmemcpy (namestr , name -> contents , name -> length );
1142- namestr [name -> length ] = L'\0' ;
1146+ wchar_t * namestr = xwcsndup (name -> contents , name -> length );
11431147 varvalue = getvar (namestr );
11441148
11451149 if (varvalue == NULL && !shopt_unset ) {
11461150 xerror (0 , Ngt ("arithmetic: parameter `%ls' is not set" ), namestr );
1151+ free (namestr );
11471152 info -> error = true;
11481153 value -> type = VT_INVALID ;
11491154 return ;
11501155 }
1156+ free (namestr );
11511157 }
11521158 if (varvalue == NULL || varvalue [0 ] == L'\0' ) {
11531159 value -> type = VT_LONG ;
0 commit comments