@@ -863,21 +863,12 @@ <h1>_flatten.js</h1>
863863 < div class ="pilwrap ">
864864 < a class ="pilcrow " href ="#section-2 "> ¶</ a >
865865 </ div >
866- < p > Internal implementation of a recursive < code > flatten</ code > function.</ p >
866+ < p > Internal implementation of a < code > flatten</ code > function.</ p >
867867
868868 </ div >
869869
870- < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> export</ span > < span class ="hljs-keyword "> default</ span > < span class ="hljs-keyword "> function</ span > < span class ="hljs-title function_ "> flatten</ span > (< span class ="hljs-params "> input, depth, strict, output</ span > ) {
871- output = output || [];
872- < span class ="hljs-keyword "> if</ span > (!depth && depth !== < span class ="hljs-number "> 0</ span > ) {
873- depth = < span class ="hljs-title class_ "> Infinity</ span > ;
874- } < span class ="hljs-keyword "> else</ span > < span class ="hljs-keyword "> if</ span > (depth <= < span class ="hljs-number "> 0</ span > ) {
875- < span class ="hljs-keyword "> return</ span > output.< span class ="hljs-title function_ "> concat</ span > (input);
876- }
877- < span class ="hljs-keyword "> var</ span > idx = output.< span class ="hljs-property "> length</ span > ;
878- < span class ="hljs-keyword "> for</ span > (< span class ="hljs-keyword "> var</ span > i = < span class ="hljs-number "> 0</ span > , length = < span class ="hljs-title function_ "> getLength</ span > (input); i < length; i++) {
879- < span class ="hljs-keyword "> var</ span > value = input[i];
880- < span class ="hljs-keyword "> if</ span > (< span class ="hljs-title function_ "> isArrayLike</ span > (value) && (< span class ="hljs-title function_ "> isArray</ span > (value) || < span class ="hljs-title function_ "> isArguments</ span > (value))) {</ pre > </ div > </ div >
870+ < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> export</ span > < span class ="hljs-keyword "> default</ span > < span class ="hljs-keyword "> function</ span > < span class ="hljs-title function_ "> flatten</ span > (< span class ="hljs-params "> input, depth, strict</ span > ) {
871+ < span class ="hljs-keyword "> if</ span > (!depth && depth !== < span class ="hljs-number "> 0</ span > ) depth = < span class ="hljs-title class_ "> Infinity</ span > ;</ pre > </ div > </ div >
881872
882873 </ li >
883874
@@ -888,17 +879,44 @@ <h1>_flatten.js</h1>
888879 < div class ="pilwrap ">
889880 < a class ="pilcrow " href ="#section-3 "> ¶</ a >
890881 </ div >
882+ < p > We will be avoiding recursive calls because this could be exploited to
883+ cause a stack overflow (CVE-2026-27601). Instead, we “trampoline” on an
884+ explicit stack.</ p >
885+
886+ </ div >
887+
888+ < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> var</ span > output = [], idx = < span class ="hljs-number "> 0</ span > , i = < span class ="hljs-number "> 0</ span > , length = < span class ="hljs-title function_ "> getLength</ span > (input) || < span class ="hljs-number "> 0</ span > , stack = [];
889+ < span class ="hljs-keyword "> while</ span > (< span class ="hljs-literal "> true</ span > ) {
890+ < span class ="hljs-keyword "> if</ span > (i >= length) {
891+ < span class ="hljs-keyword "> if</ span > (!stack.< span class ="hljs-property "> length</ span > ) < span class ="hljs-keyword "> break</ span > ;
892+ < span class ="hljs-keyword "> var</ span > frame = stack.< span class ="hljs-title function_ "> pop</ span > ();
893+ i = frame.< span class ="hljs-property "> i</ span > ;
894+ input = frame.< span class ="hljs-property "> v</ span > ;
895+ length = < span class ="hljs-title function_ "> getLength</ span > (input);
896+ < span class ="hljs-keyword "> continue</ span > ;
897+ }
898+ < span class ="hljs-keyword "> var</ span > value = input[i++];
899+ < span class ="hljs-keyword "> if</ span > (stack.< span class ="hljs-property "> length</ span > >= depth) {
900+ output[idx++] = value;
901+ } < span class ="hljs-keyword "> else</ span > < span class ="hljs-keyword "> if</ span > (< span class ="hljs-title function_ "> isArrayLike</ span > (value) && (< span class ="hljs-title function_ "> isArray</ span > (value) || < span class ="hljs-title function_ "> isArguments</ span > (value))) {</ pre > </ div > </ div >
902+
903+ </ li >
904+
905+
906+ < li id ="section-4 ">
907+ < div class ="annotation ">
908+
909+ < div class ="pilwrap ">
910+ < a class ="pilcrow " href ="#section-4 "> ¶</ a >
911+ </ div >
891912 < p > Flatten current level of array or arguments object.</ p >
892913
893914 </ div >
894915
895- < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> if</ span > (depth > < span class ="hljs-number "> 1</ span > ) {
896- < span class ="hljs-title function_ "> flatten</ span > (value, depth - < span class ="hljs-number "> 1</ span > , strict, output);
897- idx = output.< span class ="hljs-property "> length</ span > ;
898- } < span class ="hljs-keyword "> else</ span > {
899- < span class ="hljs-keyword "> var</ span > j = < span class ="hljs-number "> 0</ span > , len = value.< span class ="hljs-property "> length</ span > ;
900- < span class ="hljs-keyword "> while</ span > (j < len) output[idx++] = value[j++];
901- }
916+ < div class ="content "> < div class ='highlight '> < pre > stack.< span class ="hljs-title function_ "> push</ span > ({< span class ="hljs-attr "> i</ span > : i, < span class ="hljs-attr "> v</ span > : input});
917+ i = < span class ="hljs-number "> 0</ span > ;
918+ input = value;
919+ length = < span class ="hljs-title function_ "> getLength</ span > (input);
902920 } < span class ="hljs-keyword "> else</ span > < span class ="hljs-keyword "> if</ span > (!strict) {
903921 output[idx++] = value;
904922 }
0 commit comments