소스 검색

Made sure the array property iterator does not look beyond the initial length. Other cosmetic changes.

Dmitry Panov 4 년 전
부모
커밋
2e2e51465d
1개의 변경된 파일12개의 추가작업 그리고 22개의 파일을 삭제
  1. 12 22
      array.go

+ 12 - 22
array.go

@@ -161,9 +161,11 @@ func (a *arrayObject) getIdx(idx valueInt, receiver Value) Value {
 }
 
 func (a *arrayObject) getOwnPropStr(name unistring.String) Value {
-	if i := strToIdx(name); i != math.MaxUint32 {
-		if i < uint32(len(a.values)) {
-			return a.values[i]
+	if len(a.values) > 0 {
+		if i := strToIdx(name); i != math.MaxUint32 {
+			if i < uint32(len(a.values)) {
+				return a.values[i]
+			}
 		}
 	}
 	if name == "length" {
@@ -282,12 +284,13 @@ func (a *arrayObject) setForeignStr(name unistring.String, val, receiver Value,
 }
 
 type arrayPropIter struct {
-	a   *arrayObject
-	idx int
+	a     *arrayObject
+	limit int
+	idx   int
 }
 
 func (i *arrayPropIter) next() (propIterItem, iterNextFunc) {
-	for i.idx < len(i.a.values) {
+	for i.idx < len(i.a.values) && i.idx < i.limit {
 		name := unistring.String(strconv.Itoa(i.idx))
 		prop := i.a.values[i.idx]
 		i.idx++
@@ -301,7 +304,8 @@ func (i *arrayPropIter) next() (propIterItem, iterNextFunc) {
 
 func (a *arrayObject) enumerateOwnKeys() iterNextFunc {
 	return (&arrayPropIter{
-		a: a,
+		a:     a,
+		limit: len(a.values),
 	}).next
 }
 
@@ -360,21 +364,7 @@ func (a *arrayObject) expand(idx uint32) bool {
 					}
 				}
 				tl := int(targetLen)
-				// Use the same algorithm as in runtime.growSlice
-				newcap := cap(a.values)
-				doublecap := newcap + newcap
-				if tl > doublecap {
-					newcap = tl
-				} else {
-					if len(a.values) < 1024 {
-						newcap = doublecap
-					} else {
-						for newcap < tl {
-							newcap += newcap / 4
-						}
-					}
-				}
-				newValues := make([]Value, tl, newcap)
+				newValues := make([]Value, tl, growCap(tl, len(a.values), cap(a.values)))
 				copy(newValues, a.values)
 				a.values = newValues
 			}