Skip to content

Commit

Permalink
Support for malformed UTF-16 strings and property keys. Missing Strin…
Browse files Browse the repository at this point in the history
…g methods. (#146)
  • Loading branch information
dop251 authored Apr 11, 2020
1 parent af442b8 commit 5df89c3
Show file tree
Hide file tree
Showing 48 changed files with 2,040 additions and 886 deletions.
36 changes: 19 additions & 17 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"math/bits"
"reflect"
"strconv"

"github.com/dop251/goja/unistring"
)

type arrayIterObject struct {
Expand Down Expand Up @@ -158,7 +160,7 @@ func (a *arrayObject) getIdx(idx valueInt, receiver Value) Value {
return prop
}

func (a *arrayObject) getOwnPropStr(name string) 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]
Expand All @@ -178,7 +180,7 @@ func (a *arrayObject) getOwnPropIdx(idx valueInt) Value {
return nil
}

return a.baseObject.getOwnPropStr(idx.String())
return a.baseObject.getOwnPropStr(idx.string())
}

func (a *arrayObject) sortLen() int64 {
Expand All @@ -197,7 +199,7 @@ func (a *arrayObject) swap(i, j int64) {
a.values[i], a.values[j] = a.values[j], a.values[i]
}

func (a *arrayObject) getStr(name string, receiver Value) Value {
func (a *arrayObject) getStr(name unistring.String, receiver Value) Value {
return a.getStrWithOwnProp(a.getOwnPropStr(name), name, receiver)
}

Expand All @@ -210,7 +212,7 @@ func (a *arrayObject) setOwnIdx(idx valueInt, val Value, throw bool) bool {
if i := toIdx(idx); i != math.MaxUint32 {
return a._setOwnIdx(i, val, throw)
} else {
return a.baseObject.setOwnStr(idx.String(), val, throw)
return a.baseObject.setOwnStr(idx.string(), val, throw)
}
}

Expand Down Expand Up @@ -259,7 +261,7 @@ func (a *arrayObject) _setOwnIdx(idx uint32, val Value, throw bool) bool {
return true
}

func (a *arrayObject) setOwnStr(name string, val Value, throw bool) bool {
func (a *arrayObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._setOwnIdx(idx, val, throw)
} else {
Expand All @@ -275,7 +277,7 @@ func (a *arrayObject) setForeignIdx(idx valueInt, val, receiver Value, throw boo
return a._setForeignIdx(idx, a.getOwnPropIdx(idx), val, receiver, throw)
}

func (a *arrayObject) setForeignStr(name string, val, receiver Value, throw bool) (bool, bool) {
func (a *arrayObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
return a._setForeignStr(name, a.getOwnPropStr(name), val, receiver, throw)
}

Expand All @@ -286,7 +288,7 @@ type arrayPropIter struct {

func (i *arrayPropIter) next() (propIterItem, iterNextFunc) {
for i.idx < len(i.a.values) {
name := strconv.Itoa(i.idx)
name := unistring.String(strconv.Itoa(i.idx))
prop := i.a.values[i.idx]
i.idx++
if prop != nil {
Expand Down Expand Up @@ -318,7 +320,7 @@ func (a *arrayObject) ownKeys(all bool, accum []Value) []Value {
return a.baseObject.ownKeys(all, accum)
}

func (a *arrayObject) hasOwnPropertyStr(name string) bool {
func (a *arrayObject) hasOwnPropertyStr(name unistring.String) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return idx < uint32(len(a.values)) && a.values[idx] != nil
} else {
Expand All @@ -330,7 +332,7 @@ func (a *arrayObject) hasOwnPropertyIdx(idx valueInt) bool {
if idx := toIdx(idx); idx != math.MaxUint32 {
return idx < uint32(len(a.values)) && a.values[idx] != nil
}
return a.baseObject.hasOwnPropertyStr(idx.String())
return a.baseObject.hasOwnPropertyStr(idx.string())
}

func (a *arrayObject) expand(idx uint32) bool {
Expand Down Expand Up @@ -420,7 +422,7 @@ func (a *arrayObject) _defineIdxProperty(idx uint32, desc PropertyDescriptor, th
if idx < uint32(len(a.values)) {
existing = a.values[idx]
}
prop, ok := a.baseObject._defineOwnProperty(strconv.FormatUint(uint64(idx), 10), existing, desc, throw)
prop, ok := a.baseObject._defineOwnProperty(unistring.String(strconv.FormatUint(uint64(idx), 10)), existing, desc, throw)
if ok {
if idx >= a.length {
if !a.setLengthInt(int64(idx)+1, throw) {
Expand All @@ -440,7 +442,7 @@ func (a *arrayObject) _defineIdxProperty(idx uint32, desc PropertyDescriptor, th
return ok
}

func (a *arrayObject) defineOwnPropertyStr(name string, descr PropertyDescriptor, throw bool) bool {
func (a *arrayObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._defineIdxProperty(idx, descr, throw)
}
Expand All @@ -454,7 +456,7 @@ func (a *arrayObject) defineOwnPropertyIdx(idx valueInt, descr PropertyDescripto
if idx := toIdx(idx); idx != math.MaxUint32 {
return a._defineIdxProperty(idx, descr, throw)
}
return a.baseObject.defineOwnPropertyStr(idx.String(), descr, throw)
return a.baseObject.defineOwnPropertyStr(idx.string(), descr, throw)
}

func (a *arrayObject) _deleteIdxProp(idx uint32, throw bool) bool {
Expand All @@ -474,7 +476,7 @@ func (a *arrayObject) _deleteIdxProp(idx uint32, throw bool) bool {
return true
}

func (a *arrayObject) deleteStr(name string, throw bool) bool {
func (a *arrayObject) deleteStr(name unistring.String, throw bool) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._deleteIdxProp(idx, throw)
}
Expand All @@ -485,7 +487,7 @@ func (a *arrayObject) deleteIdx(idx valueInt, throw bool) bool {
if idx := toIdx(idx); idx != math.MaxUint32 {
return a._deleteIdxProp(idx, throw)
}
return a.baseObject.deleteStr(idx.String(), throw)
return a.baseObject.deleteStr(idx.string(), throw)
}

func (a *arrayObject) export() interface{} {
Expand Down Expand Up @@ -518,7 +520,7 @@ func toIdx(v valueInt) uint32 {
return math.MaxUint32
}

func strToIdx64(s string) int64 {
func strToIdx64(s unistring.String) int64 {
if s == "" {
return -1
}
Expand Down Expand Up @@ -567,7 +569,7 @@ func strToIdx64(s string) int64 {
return n1
}

func strToIdx(s string) uint32 {
func strToIdx(s unistring.String) uint32 {
if s == "" {
return math.MaxUint32
}
Expand Down Expand Up @@ -617,7 +619,7 @@ func strToIdx(s string) uint32 {
return n1
}

func strToGoIdx(s string) int {
func strToGoIdx(s unistring.String) int {
if bits.UintSize == 64 {
return int(strToIdx64(s))
}
Expand Down
30 changes: 16 additions & 14 deletions array_sparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"reflect"
"sort"
"strconv"

"github.com/dop251/goja/unistring"
)

type sparseArrayItem struct {
Expand Down Expand Up @@ -109,7 +111,7 @@ func (a *sparseArrayObject) _getIdx(idx uint32) Value {
return nil
}

func (a *sparseArrayObject) getStr(name string, receiver Value) Value {
func (a *sparseArrayObject) getStr(name unistring.String, receiver Value) Value {
return a.getStrWithOwnProp(a.getOwnPropStr(name), name, receiver)
}

Expand Down Expand Up @@ -137,7 +139,7 @@ func (a *sparseArrayObject) getLengthProp() Value {
return &a.lengthProp
}

func (a *sparseArrayObject) getOwnPropStr(name string) Value {
func (a *sparseArrayObject) getOwnPropStr(name unistring.String) Value {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._getIdx(idx)
}
Expand All @@ -151,7 +153,7 @@ func (a *sparseArrayObject) getOwnPropIdx(idx valueInt) Value {
if idx := toIdx(idx); idx != math.MaxUint32 {
return a._getIdx(idx)
}
return a.baseObject.getOwnPropStr(idx.String())
return a.baseObject.getOwnPropStr(idx.string())
}

func (a *sparseArrayObject) add(idx uint32, val Value) {
Expand Down Expand Up @@ -218,7 +220,7 @@ func (a *sparseArrayObject) _setOwnIdx(idx uint32, val Value, throw bool) bool {
return true
}

func (a *sparseArrayObject) setOwnStr(name string, val Value, throw bool) bool {
func (a *sparseArrayObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._setOwnIdx(idx, val, throw)
} else {
Expand All @@ -235,10 +237,10 @@ func (a *sparseArrayObject) setOwnIdx(idx valueInt, val Value, throw bool) bool
return a._setOwnIdx(idx, val, throw)
}

return a.baseObject.setOwnStr(idx.String(), val, throw)
return a.baseObject.setOwnStr(idx.string(), val, throw)
}

func (a *sparseArrayObject) setForeignStr(name string, val, receiver Value, throw bool) (bool, bool) {
func (a *sparseArrayObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
return a._setForeignStr(name, a.getOwnPropStr(name), val, receiver, throw)
}

Expand All @@ -253,7 +255,7 @@ type sparseArrayPropIter struct {

func (i *sparseArrayPropIter) next() (propIterItem, iterNextFunc) {
for i.idx < len(i.a.items) {
name := strconv.Itoa(int(i.a.items[i.idx].idx))
name := unistring.String(strconv.Itoa(int(i.a.items[i.idx].idx)))
prop := i.a.items[i.idx].value
i.idx++
if prop != nil {
Expand Down Expand Up @@ -299,7 +301,7 @@ func (a *sparseArrayObject) setValues(values []Value, objCount int) {
}
}

func (a *sparseArrayObject) hasOwnPropertyStr(name string) bool {
func (a *sparseArrayObject) hasOwnPropertyStr(name unistring.String) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
i := a.findIdx(idx)
return i < len(a.items) && a.items[i].idx == idx
Expand All @@ -314,7 +316,7 @@ func (a *sparseArrayObject) hasOwnPropertyIdx(idx valueInt) bool {
return i < len(a.items) && a.items[i].idx == idx
}

return a.baseObject.hasOwnPropertyStr(idx.String())
return a.baseObject.hasOwnPropertyStr(idx.string())
}

func (a *sparseArrayObject) expand(idx uint32) bool {
Expand Down Expand Up @@ -345,7 +347,7 @@ func (a *sparseArrayObject) _defineIdxProperty(idx uint32, desc PropertyDescript
if i < len(a.items) && a.items[i].idx == idx {
existing = a.items[i].value
}
prop, ok := a.baseObject._defineOwnProperty(strconv.FormatUint(uint64(idx), 10), existing, desc, throw)
prop, ok := a.baseObject._defineOwnProperty(unistring.String(strconv.FormatUint(uint64(idx), 10)), existing, desc, throw)
if ok {
if idx >= a.length {
if !a.setLengthInt(int64(idx)+1, throw) {
Expand Down Expand Up @@ -376,7 +378,7 @@ func (a *sparseArrayObject) _defineIdxProperty(idx uint32, desc PropertyDescript
return ok
}

func (a *sparseArrayObject) defineOwnPropertyStr(name string, descr PropertyDescriptor, throw bool) bool {
func (a *sparseArrayObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._defineIdxProperty(idx, descr, throw)
}
Expand All @@ -390,7 +392,7 @@ func (a *sparseArrayObject) defineOwnPropertyIdx(idx valueInt, descr PropertyDes
if idx := toIdx(idx); idx != math.MaxUint32 {
return a._defineIdxProperty(idx, descr, throw)
}
return a.baseObject.defineOwnPropertyStr(idx.String(), descr, throw)
return a.baseObject.defineOwnPropertyStr(idx.string(), descr, throw)
}

func (a *sparseArrayObject) _deleteIdxProp(idx uint32, throw bool) bool {
Expand All @@ -410,7 +412,7 @@ func (a *sparseArrayObject) _deleteIdxProp(idx uint32, throw bool) bool {
return true
}

func (a *sparseArrayObject) deleteStr(name string, throw bool) bool {
func (a *sparseArrayObject) deleteStr(name unistring.String, throw bool) bool {
if idx := strToIdx(name); idx != math.MaxUint32 {
return a._deleteIdxProp(idx, throw)
}
Expand All @@ -421,7 +423,7 @@ func (a *sparseArrayObject) deleteIdx(idx valueInt, throw bool) bool {
if idx := toIdx(idx); idx != math.MaxUint32 {
return a._deleteIdxProp(idx, throw)
}
return a.baseObject.deleteStr(idx.String(), throw)
return a.baseObject.deleteStr(idx.string(), throw)
}

func (a *sparseArrayObject) sortLen() int64 {
Expand Down
9 changes: 5 additions & 4 deletions ast/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package ast
import (
"github.com/dop251/goja/file"
"github.com/dop251/goja/token"
"github.com/dop251/goja/unistring"
"github.com/go-sourcemap/sourcemap"
)

Expand Down Expand Up @@ -98,7 +99,7 @@ type (
}

Identifier struct {
Name string
Name unistring.String
Idx file.Idx
}

Expand Down Expand Up @@ -134,7 +135,7 @@ type (
}

Property struct {
Key string
Key unistring.String
Kind string
Value Expression
}
Expand All @@ -153,7 +154,7 @@ type (
StringLiteral struct {
Idx file.Idx
Literal string
Value string
Value unistring.String
}

ThisExpression struct {
Expand All @@ -168,7 +169,7 @@ type (
}

VariableExpression struct {
Name string
Name unistring.String
Idx file.Idx
Initializer Expression
}
Expand Down
6 changes: 3 additions & 3 deletions builtin_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ type arraySortCtx struct {
compare func(FunctionCall) Value
}

func (ctx *arraySortCtx) sortCompare(x, y Value) int {
func (a *arraySortCtx) sortCompare(x, y Value) int {
if x == nil && y == nil {
return 0
}
Expand All @@ -1314,8 +1314,8 @@ func (ctx *arraySortCtx) sortCompare(x, y Value) int {
return -1
}

if ctx.compare != nil {
f := ctx.compare(FunctionCall{
if a.compare != nil {
f := a.compare(FunctionCall{
This: _undefined,
Arguments: []Value{x, y},
}).ToFloat()
Expand Down
Loading

0 comments on commit 5df89c3

Please sign in to comment.