github.com/bytedance/go-tagexpr/v2@v2.9.8/binding/tidwall_gjson/gjson.go (about)

     1  // Package gjson provides searching for json strings, github.com/tidwall/gjson v1.9.3
     2  package tidwall_gjson
     3  
     4  import (
     5  	"encoding/json"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  	"unicode/utf16"
    10  	"unicode/utf8"
    11  	"unsafe"
    12  
    13  	"github.com/tidwall/match"
    14  	"github.com/tidwall/pretty"
    15  )
    16  
    17  // Type is Result type
    18  type Type int
    19  
    20  const (
    21  	// Null is a null json value
    22  	Null Type = iota
    23  	// False is a json false boolean
    24  	False
    25  	// Number is json number
    26  	Number
    27  	// String is a json string
    28  	String
    29  	// True is a json true boolean
    30  	True
    31  	// JSON is a raw block of JSON
    32  	JSON
    33  )
    34  
    35  // String returns a string representation of the type.
    36  func (t Type) String() string {
    37  	switch t {
    38  	default:
    39  		return ""
    40  	case Null:
    41  		return "Null"
    42  	case False:
    43  		return "False"
    44  	case Number:
    45  		return "Number"
    46  	case String:
    47  		return "String"
    48  	case True:
    49  		return "True"
    50  	case JSON:
    51  		return "JSON"
    52  	}
    53  }
    54  
    55  // Result represents a json value that is returned from Get().
    56  type Result struct {
    57  	// Type is the json type
    58  	Type Type
    59  	// Raw is the raw json
    60  	Raw string
    61  	// Str is the json string
    62  	Str string
    63  	// Num is the json number
    64  	Num float64
    65  	// Index of raw value in original json, zero means index unknown
    66  	Index int
    67  	// Indexes of all the elements that match on a path containing the '#'
    68  	// query character.
    69  	Indexes []int
    70  }
    71  
    72  // String returns a string representation of the value.
    73  func (t Result) String() string {
    74  	switch t.Type {
    75  	default:
    76  		return ""
    77  	case False:
    78  		return "false"
    79  	case Number:
    80  		if len(t.Raw) == 0 {
    81  			// calculated result
    82  			return strconv.FormatFloat(t.Num, 'f', -1, 64)
    83  		}
    84  		var i int
    85  		if t.Raw[0] == '-' {
    86  			i++
    87  		}
    88  		for ; i < len(t.Raw); i++ {
    89  			if t.Raw[i] < '0' || t.Raw[i] > '9' {
    90  				return strconv.FormatFloat(t.Num, 'f', -1, 64)
    91  			}
    92  		}
    93  		return t.Raw
    94  	case String:
    95  		return t.Str
    96  	case JSON:
    97  		return t.Raw
    98  	case True:
    99  		return "true"
   100  	}
   101  }
   102  
   103  // Bool returns an boolean representation.
   104  func (t Result) Bool() bool {
   105  	switch t.Type {
   106  	default:
   107  		return false
   108  	case True:
   109  		return true
   110  	case String:
   111  		b, _ := strconv.ParseBool(strings.ToLower(t.Str))
   112  		return b
   113  	case Number:
   114  		return t.Num != 0
   115  	}
   116  }
   117  
   118  // Int returns an integer representation.
   119  func (t Result) Int() int64 {
   120  	switch t.Type {
   121  	default:
   122  		return 0
   123  	case True:
   124  		return 1
   125  	case String:
   126  		n, _ := parseInt(t.Str)
   127  		return n
   128  	case Number:
   129  		// try to directly convert the float64 to int64
   130  		i, ok := safeInt(t.Num)
   131  		if ok {
   132  			return i
   133  		}
   134  		// now try to parse the raw string
   135  		i, ok = parseInt(t.Raw)
   136  		if ok {
   137  			return i
   138  		}
   139  		// fallback to a standard conversion
   140  		return int64(t.Num)
   141  	}
   142  }
   143  
   144  // Uint returns an unsigned integer representation.
   145  func (t Result) Uint() uint64 {
   146  	switch t.Type {
   147  	default:
   148  		return 0
   149  	case True:
   150  		return 1
   151  	case String:
   152  		n, _ := parseUint(t.Str)
   153  		return n
   154  	case Number:
   155  		// try to directly convert the float64 to uint64
   156  		i, ok := safeInt(t.Num)
   157  		if ok && i >= 0 {
   158  			return uint64(i)
   159  		}
   160  		// now try to parse the raw string
   161  		u, ok := parseUint(t.Raw)
   162  		if ok {
   163  			return u
   164  		}
   165  		// fallback to a standard conversion
   166  		return uint64(t.Num)
   167  	}
   168  }
   169  
   170  // Float returns an float64 representation.
   171  func (t Result) Float() float64 {
   172  	switch t.Type {
   173  	default:
   174  		return 0
   175  	case True:
   176  		return 1
   177  	case String:
   178  		n, _ := strconv.ParseFloat(t.Str, 64)
   179  		return n
   180  	case Number:
   181  		return t.Num
   182  	}
   183  }
   184  
   185  // Time returns a time.Time representation.
   186  func (t Result) Time() time.Time {
   187  	res, _ := time.Parse(time.RFC3339, t.String())
   188  	return res
   189  }
   190  
   191  // Array returns back an array of values.
   192  // If the result represents a non-existent value, then an empty array will be
   193  // returned. If the result is not a JSON array, the return value will be an
   194  // array containing one result.
   195  func (t Result) Array() []Result {
   196  	if t.Type == Null {
   197  		return []Result{}
   198  	}
   199  	if t.Type != JSON {
   200  		return []Result{t}
   201  	}
   202  	r := t.arrayOrMap('[', false)
   203  	return r.a
   204  }
   205  
   206  // IsObject returns true if the result value is a JSON object.
   207  func (t Result) IsObject() bool {
   208  	return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '{'
   209  }
   210  
   211  // IsArray returns true if the result value is a JSON array.
   212  func (t Result) IsArray() bool {
   213  	return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '['
   214  }
   215  
   216  // ForEach iterates through values.
   217  // If the result represents a non-existent value, then no values will be
   218  // iterated. If the result is an Object, the iterator will pass the key and
   219  // value of each item. If the result is an Array, the iterator will only pass
   220  // the value of each item. If the result is not a JSON array or object, the
   221  // iterator will pass back one value equal to the result.
   222  func (t Result) ForEach(iterator func(key, value Result) bool) {
   223  	if !t.Exists() {
   224  		return
   225  	}
   226  	if t.Type != JSON {
   227  		iterator(Result{}, t)
   228  		return
   229  	}
   230  	json := t.Raw
   231  	var keys bool
   232  	var i int
   233  	var key, value Result
   234  	for ; i < len(json); i++ {
   235  		if json[i] == '{' {
   236  			i++
   237  			key.Type = String
   238  			keys = true
   239  			break
   240  		} else if json[i] == '[' {
   241  			i++
   242  			break
   243  		}
   244  		if json[i] > ' ' {
   245  			return
   246  		}
   247  	}
   248  	var str string
   249  	var vesc bool
   250  	var ok bool
   251  	for ; i < len(json); i++ {
   252  		if keys {
   253  			if json[i] != '"' {
   254  				continue
   255  			}
   256  			s := i
   257  			i, str, vesc, ok = parseString(json, i+1)
   258  			if !ok {
   259  				return
   260  			}
   261  			if vesc {
   262  				key.Str = unescape(str[1 : len(str)-1])
   263  			} else {
   264  				key.Str = str[1 : len(str)-1]
   265  			}
   266  			key.Raw = str
   267  			key.Index = s
   268  		}
   269  		for ; i < len(json); i++ {
   270  			if json[i] <= ' ' || json[i] == ',' || json[i] == ':' {
   271  				continue
   272  			}
   273  			break
   274  		}
   275  		s := i
   276  		i, value, ok = parseAny(json, i, true)
   277  		if !ok {
   278  			return
   279  		}
   280  		value.Index = s
   281  		if !iterator(key, value) {
   282  			return
   283  		}
   284  	}
   285  }
   286  
   287  // Map returns back a map of values. The result should be a JSON object.
   288  // If the result is not a JSON object, the return value will be an empty map.
   289  func (t Result) Map() map[string]Result {
   290  	if t.Type != JSON {
   291  		return map[string]Result{}
   292  	}
   293  	r := t.arrayOrMap('{', false)
   294  	return r.o
   295  }
   296  
   297  // Get searches result for the specified path.
   298  // The result should be a JSON array or object.
   299  func (t Result) Get(path string) Result {
   300  	return Get(t.Raw, path)
   301  }
   302  
   303  type arrayOrMapResult struct {
   304  	a  []Result
   305  	ai []interface{}
   306  	o  map[string]Result
   307  	oi map[string]interface{}
   308  	vc byte
   309  }
   310  
   311  func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) {
   312  	var json = t.Raw
   313  	var i int
   314  	var value Result
   315  	var count int
   316  	var key Result
   317  	if vc == 0 {
   318  		for ; i < len(json); i++ {
   319  			if json[i] == '{' || json[i] == '[' {
   320  				r.vc = json[i]
   321  				i++
   322  				break
   323  			}
   324  			if json[i] > ' ' {
   325  				goto end
   326  			}
   327  		}
   328  	} else {
   329  		for ; i < len(json); i++ {
   330  			if json[i] == vc {
   331  				i++
   332  				break
   333  			}
   334  			if json[i] > ' ' {
   335  				goto end
   336  			}
   337  		}
   338  		r.vc = vc
   339  	}
   340  	if r.vc == '{' {
   341  		if valueize {
   342  			r.oi = make(map[string]interface{})
   343  		} else {
   344  			r.o = make(map[string]Result)
   345  		}
   346  	} else {
   347  		if valueize {
   348  			r.ai = make([]interface{}, 0)
   349  		} else {
   350  			r.a = make([]Result, 0)
   351  		}
   352  	}
   353  	for ; i < len(json); i++ {
   354  		if json[i] <= ' ' {
   355  			continue
   356  		}
   357  		// get next value
   358  		if json[i] == ']' || json[i] == '}' {
   359  			break
   360  		}
   361  		switch json[i] {
   362  		default:
   363  			if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' {
   364  				value.Type = Number
   365  				value.Raw, value.Num = tonum(json[i:])
   366  				value.Str = ""
   367  			} else {
   368  				continue
   369  			}
   370  		case '{', '[':
   371  			value.Type = JSON
   372  			value.Raw = squash(json[i:])
   373  			value.Str, value.Num = "", 0
   374  		case 'n':
   375  			value.Type = Null
   376  			value.Raw = tolit(json[i:])
   377  			value.Str, value.Num = "", 0
   378  		case 't':
   379  			value.Type = True
   380  			value.Raw = tolit(json[i:])
   381  			value.Str, value.Num = "", 0
   382  		case 'f':
   383  			value.Type = False
   384  			value.Raw = tolit(json[i:])
   385  			value.Str, value.Num = "", 0
   386  		case '"':
   387  			value.Type = String
   388  			value.Raw, value.Str = tostr(json[i:])
   389  			value.Num = 0
   390  		}
   391  		i += len(value.Raw) - 1
   392  
   393  		if r.vc == '{' {
   394  			if count%2 == 0 {
   395  				key = value
   396  			} else {
   397  				if valueize {
   398  					if _, ok := r.oi[key.Str]; !ok {
   399  						r.oi[key.Str] = value.Value()
   400  					}
   401  				} else {
   402  					if _, ok := r.o[key.Str]; !ok {
   403  						r.o[key.Str] = value
   404  					}
   405  				}
   406  			}
   407  			count++
   408  		} else {
   409  			if valueize {
   410  				r.ai = append(r.ai, value.Value())
   411  			} else {
   412  				r.a = append(r.a, value)
   413  			}
   414  		}
   415  	}
   416  end:
   417  	return
   418  }
   419  
   420  // Parse parses the json and returns a result.
   421  //
   422  // This function expects that the json is well-formed, and does not validate.
   423  // Invalid json will not panic, but it may return back unexpected results.
   424  // If you are consuming JSON from an unpredictable source then you may want to
   425  // use the Valid function first.
   426  func Parse(json string) Result {
   427  	var value Result
   428  	for i := 0; i < len(json); i++ {
   429  		if json[i] == '{' || json[i] == '[' {
   430  			value.Type = JSON
   431  			value.Raw = json[i:] // just take the entire raw
   432  			break
   433  		}
   434  		if json[i] <= ' ' {
   435  			continue
   436  		}
   437  		switch json[i] {
   438  		default:
   439  			if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' {
   440  				value.Type = Number
   441  				value.Raw, value.Num = tonum(json[i:])
   442  			} else {
   443  				return Result{}
   444  			}
   445  		case 'n':
   446  			value.Type = Null
   447  			value.Raw = tolit(json[i:])
   448  		case 't':
   449  			value.Type = True
   450  			value.Raw = tolit(json[i:])
   451  		case 'f':
   452  			value.Type = False
   453  			value.Raw = tolit(json[i:])
   454  		case '"':
   455  			value.Type = String
   456  			value.Raw, value.Str = tostr(json[i:])
   457  		}
   458  		break
   459  	}
   460  	return value
   461  }
   462  
   463  // ParseBytes parses the json and returns a result.
   464  // If working with bytes, this method preferred over Parse(string(data))
   465  func ParseBytes(json []byte) Result {
   466  	return Parse(string(json))
   467  }
   468  
   469  func squash(json string) string {
   470  	// expects that the lead character is a '[' or '{' or '(' or '"'
   471  	// squash the value, ignoring all nested arrays and objects.
   472  	var i, depth int
   473  	if json[0] != '"' {
   474  		i, depth = 1, 1
   475  	}
   476  	for ; i < len(json); i++ {
   477  		if json[i] >= '"' && json[i] <= '}' {
   478  			switch json[i] {
   479  			case '"':
   480  				i++
   481  				s2 := i
   482  				for ; i < len(json); i++ {
   483  					if json[i] > '\\' {
   484  						continue
   485  					}
   486  					if json[i] == '"' {
   487  						// look for an escaped slash
   488  						if json[i-1] == '\\' {
   489  							n := 0
   490  							for j := i - 2; j > s2-1; j-- {
   491  								if json[j] != '\\' {
   492  									break
   493  								}
   494  								n++
   495  							}
   496  							if n%2 == 0 {
   497  								continue
   498  							}
   499  						}
   500  						break
   501  					}
   502  				}
   503  				if depth == 0 {
   504  					if i >= len(json) {
   505  						return json
   506  					}
   507  					return json[:i+1]
   508  				}
   509  			case '{', '[', '(':
   510  				depth++
   511  			case '}', ']', ')':
   512  				depth--
   513  				if depth == 0 {
   514  					return json[:i+1]
   515  				}
   516  			}
   517  		}
   518  	}
   519  	return json
   520  }
   521  
   522  func tonum(json string) (raw string, num float64) {
   523  	for i := 1; i < len(json); i++ {
   524  		// less than dash might have valid characters
   525  		if json[i] <= '-' {
   526  			if json[i] <= ' ' || json[i] == ',' {
   527  				// break on whitespace and comma
   528  				raw = json[:i]
   529  				num, _ = strconv.ParseFloat(raw, 64)
   530  				return
   531  			}
   532  			// could be a '+' or '-'. let's assume so.
   533  			continue
   534  		}
   535  		if json[i] < ']' {
   536  			// probably a valid number
   537  			continue
   538  		}
   539  		if json[i] == 'e' || json[i] == 'E' {
   540  			// allow for exponential numbers
   541  			continue
   542  		}
   543  		// likely a ']' or '}'
   544  		raw = json[:i]
   545  		num, _ = strconv.ParseFloat(raw, 64)
   546  		return
   547  	}
   548  	raw = json
   549  	num, _ = strconv.ParseFloat(raw, 64)
   550  	return
   551  }
   552  
   553  func tolit(json string) (raw string) {
   554  	for i := 1; i < len(json); i++ {
   555  		if json[i] < 'a' || json[i] > 'z' {
   556  			return json[:i]
   557  		}
   558  	}
   559  	return json
   560  }
   561  
   562  func tostr(json string) (raw string, str string) {
   563  	// expects that the lead character is a '"'
   564  	for i := 1; i < len(json); i++ {
   565  		if json[i] > '\\' {
   566  			continue
   567  		}
   568  		if json[i] == '"' {
   569  			return json[:i+1], json[1:i]
   570  		}
   571  		if json[i] == '\\' {
   572  			i++
   573  			for ; i < len(json); i++ {
   574  				if json[i] > '\\' {
   575  					continue
   576  				}
   577  				if json[i] == '"' {
   578  					// look for an escaped slash
   579  					if json[i-1] == '\\' {
   580  						n := 0
   581  						for j := i - 2; j > 0; j-- {
   582  							if json[j] != '\\' {
   583  								break
   584  							}
   585  							n++
   586  						}
   587  						if n%2 == 0 {
   588  							continue
   589  						}
   590  					}
   591  					return json[:i+1], unescape(json[1:i])
   592  				}
   593  			}
   594  			var ret string
   595  			if i+1 < len(json) {
   596  				ret = json[:i+1]
   597  			} else {
   598  				ret = json[:i]
   599  			}
   600  			return ret, unescape(json[1:i])
   601  		}
   602  	}
   603  	return json, json[1:]
   604  }
   605  
   606  // Exists returns true if value exists.
   607  //
   608  //	 if gjson.Get(json, "name.last").Exists(){
   609  //			println("value exists")
   610  //	 }
   611  func (t Result) Exists() bool {
   612  	return t.Type != Null || len(t.Raw) != 0
   613  }
   614  
   615  // Value returns one of these types:
   616  //
   617  //	bool, for JSON booleans
   618  //	float64, for JSON numbers
   619  //	Number, for JSON numbers
   620  //	string, for JSON string literals
   621  //	nil, for JSON null
   622  //	map[string]interface{}, for JSON objects
   623  //	[]interface{}, for JSON arrays
   624  func (t Result) Value() interface{} {
   625  	if t.Type == String {
   626  		return t.Str
   627  	}
   628  	switch t.Type {
   629  	default:
   630  		return nil
   631  	case False:
   632  		return false
   633  	case Number:
   634  		return t.Num
   635  	case JSON:
   636  		r := t.arrayOrMap(0, true)
   637  		if r.vc == '{' {
   638  			return r.oi
   639  		} else if r.vc == '[' {
   640  			return r.ai
   641  		}
   642  		return nil
   643  	case True:
   644  		return true
   645  	}
   646  }
   647  
   648  func parseString(json string, i int) (int, string, bool, bool) {
   649  	var s = i
   650  	for ; i < len(json); i++ {
   651  		if json[i] > '\\' {
   652  			continue
   653  		}
   654  		if json[i] == '"' {
   655  			return i + 1, json[s-1 : i+1], false, true
   656  		}
   657  		if json[i] == '\\' {
   658  			i++
   659  			for ; i < len(json); i++ {
   660  				if json[i] > '\\' {
   661  					continue
   662  				}
   663  				if json[i] == '"' {
   664  					// look for an escaped slash
   665  					if json[i-1] == '\\' {
   666  						n := 0
   667  						for j := i - 2; j > 0; j-- {
   668  							if json[j] != '\\' {
   669  								break
   670  							}
   671  							n++
   672  						}
   673  						if n%2 == 0 {
   674  							continue
   675  						}
   676  					}
   677  					return i + 1, json[s-1 : i+1], true, true
   678  				}
   679  			}
   680  			break
   681  		}
   682  	}
   683  	return i, json[s-1:], false, false
   684  }
   685  
   686  func parseNumber(json string, i int) (int, string) {
   687  	var s = i
   688  	i++
   689  	for ; i < len(json); i++ {
   690  		if json[i] <= ' ' || json[i] == ',' || json[i] == ']' ||
   691  			json[i] == '}' {
   692  			return i, json[s:i]
   693  		}
   694  	}
   695  	return i, json[s:]
   696  }
   697  
   698  func parseLiteral(json string, i int) (int, string) {
   699  	var s = i
   700  	i++
   701  	for ; i < len(json); i++ {
   702  		if json[i] < 'a' || json[i] > 'z' {
   703  			return i, json[s:i]
   704  		}
   705  	}
   706  	return i, json[s:]
   707  }
   708  
   709  type arrayPathResult struct {
   710  	part    string
   711  	path    string
   712  	pipe    string
   713  	piped   bool
   714  	more    bool
   715  	alogok  bool
   716  	arrch   bool
   717  	alogkey string
   718  	query   struct {
   719  		on    bool
   720  		all   bool
   721  		path  string
   722  		op    string
   723  		value string
   724  	}
   725  }
   726  
   727  func parseArrayPath(path string) (r arrayPathResult) {
   728  	for i := 0; i < len(path); i++ {
   729  		if path[i] == '|' {
   730  			r.part = path[:i]
   731  			r.pipe = path[i+1:]
   732  			r.piped = true
   733  			return
   734  		}
   735  		if path[i] == '.' {
   736  			r.part = path[:i]
   737  			if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1]) {
   738  				r.pipe = path[i+1:]
   739  				r.piped = true
   740  			} else {
   741  				r.path = path[i+1:]
   742  				r.more = true
   743  			}
   744  			return
   745  		}
   746  		if path[i] == '#' {
   747  			r.arrch = true
   748  			if i == 0 && len(path) > 1 {
   749  				if path[1] == '.' {
   750  					r.alogok = true
   751  					r.alogkey = path[2:]
   752  					r.path = path[:1]
   753  				} else if path[1] == '[' || path[1] == '(' {
   754  					// query
   755  					r.query.on = true
   756  					qpath, op, value, _, fi, vesc, ok :=
   757  						parseQuery(path[i:])
   758  					if !ok {
   759  						// bad query, end now
   760  						break
   761  					}
   762  					if len(value) > 2 && value[0] == '"' &&
   763  						value[len(value)-1] == '"' {
   764  						value = value[1 : len(value)-1]
   765  						if vesc {
   766  							value = unescape(value)
   767  						}
   768  					}
   769  					r.query.path = qpath
   770  					r.query.op = op
   771  					r.query.value = value
   772  
   773  					i = fi - 1
   774  					if i+1 < len(path) && path[i+1] == '#' {
   775  						r.query.all = true
   776  					}
   777  				}
   778  			}
   779  			continue
   780  		}
   781  	}
   782  	r.part = path
   783  	r.path = ""
   784  	return
   785  }
   786  
   787  // splitQuery takes a query and splits it into three parts:
   788  //
   789  //	path, op, middle, and right.
   790  //
   791  // So for this query:
   792  //
   793  //	#(first_name=="Murphy").last
   794  //
   795  // Becomes
   796  //
   797  //	first_name   # path
   798  //	=="Murphy"   # middle
   799  //	.last        # right
   800  //
   801  // Or,
   802  //
   803  //	#(service_roles.#(=="one")).cap
   804  //
   805  // Becomes
   806  //
   807  //	service_roles.#(=="one")   # path
   808  //	                           # middle
   809  //	.cap                       # right
   810  func parseQuery(query string) (
   811  	path, op, value, remain string, i int, vesc, ok bool,
   812  ) {
   813  	if len(query) < 2 || query[0] != '#' ||
   814  		(query[1] != '(' && query[1] != '[') {
   815  		return "", "", "", "", i, false, false
   816  	}
   817  	i = 2
   818  	j := 0 // start of value part
   819  	depth := 1
   820  	for ; i < len(query); i++ {
   821  		if depth == 1 && j == 0 {
   822  			switch query[i] {
   823  			case '!', '=', '<', '>', '%':
   824  				// start of the value part
   825  				j = i
   826  				continue
   827  			}
   828  		}
   829  		if query[i] == '\\' {
   830  			i++
   831  		} else if query[i] == '[' || query[i] == '(' {
   832  			depth++
   833  		} else if query[i] == ']' || query[i] == ')' {
   834  			depth--
   835  			if depth == 0 {
   836  				break
   837  			}
   838  		} else if query[i] == '"' {
   839  			// inside selector string, balance quotes
   840  			i++
   841  			for ; i < len(query); i++ {
   842  				if query[i] == '\\' {
   843  					vesc = true
   844  					i++
   845  				} else if query[i] == '"' {
   846  					break
   847  				}
   848  			}
   849  		}
   850  	}
   851  	if depth > 0 {
   852  		return "", "", "", "", i, false, false
   853  	}
   854  	if j > 0 {
   855  		path = trim(query[2:j])
   856  		value = trim(query[j:i])
   857  		remain = query[i+1:]
   858  		// parse the compare op from the value
   859  		var opsz int
   860  		switch {
   861  		case len(value) == 1:
   862  			opsz = 1
   863  		case value[0] == '!' && value[1] == '=':
   864  			opsz = 2
   865  		case value[0] == '!' && value[1] == '%':
   866  			opsz = 2
   867  		case value[0] == '<' && value[1] == '=':
   868  			opsz = 2
   869  		case value[0] == '>' && value[1] == '=':
   870  			opsz = 2
   871  		case value[0] == '=' && value[1] == '=':
   872  			value = value[1:]
   873  			opsz = 1
   874  		case value[0] == '<':
   875  			opsz = 1
   876  		case value[0] == '>':
   877  			opsz = 1
   878  		case value[0] == '=':
   879  			opsz = 1
   880  		case value[0] == '%':
   881  			opsz = 1
   882  		}
   883  		op = value[:opsz]
   884  		value = trim(value[opsz:])
   885  	} else {
   886  		path = trim(query[2:i])
   887  		remain = query[i+1:]
   888  	}
   889  	return path, op, value, remain, i + 1, vesc, true
   890  }
   891  
   892  func trim(s string) string {
   893  left:
   894  	if len(s) > 0 && s[0] <= ' ' {
   895  		s = s[1:]
   896  		goto left
   897  	}
   898  right:
   899  	if len(s) > 0 && s[len(s)-1] <= ' ' {
   900  		s = s[:len(s)-1]
   901  		goto right
   902  	}
   903  	return s
   904  }
   905  
   906  // peek at the next byte and see if it's a '@', '[', or '{'.
   907  func isDotPiperChar(c byte) bool {
   908  	return !DisableModifiers && (c == '@' || c == '[' || c == '{')
   909  }
   910  
   911  type objectPathResult struct {
   912  	part  string
   913  	path  string
   914  	pipe  string
   915  	piped bool
   916  	wild  bool
   917  	more  bool
   918  }
   919  
   920  func parseObjectPath(path string) (r objectPathResult) {
   921  	for i := 0; i < len(path); i++ {
   922  		if path[i] == '|' {
   923  			r.part = path[:i]
   924  			r.pipe = path[i+1:]
   925  			r.piped = true
   926  			return
   927  		}
   928  		if path[i] == '.' {
   929  			r.part = path[:i]
   930  			if i < len(path)-1 && isDotPiperChar(path[i+1]) {
   931  				r.pipe = path[i+1:]
   932  				r.piped = true
   933  			} else {
   934  				r.path = path[i+1:]
   935  				r.more = true
   936  			}
   937  			return
   938  		}
   939  		if path[i] == '*' || path[i] == '?' {
   940  			r.wild = true
   941  			continue
   942  		}
   943  		if path[i] == '\\' {
   944  			// go into escape mode. this is a slower path that
   945  			// strips off the escape character from the part.
   946  			epart := []byte(path[:i])
   947  			i++
   948  			if i < len(path) {
   949  				epart = append(epart, path[i])
   950  				i++
   951  				for ; i < len(path); i++ {
   952  					if path[i] == '\\' {
   953  						i++
   954  						if i < len(path) {
   955  							epart = append(epart, path[i])
   956  						}
   957  						continue
   958  					} else if path[i] == '.' {
   959  						r.part = string(epart)
   960  						if i < len(path)-1 && isDotPiperChar(path[i+1]) {
   961  							r.pipe = path[i+1:]
   962  							r.piped = true
   963  						} else {
   964  							r.path = path[i+1:]
   965  						}
   966  						r.more = true
   967  						return
   968  					} else if path[i] == '|' {
   969  						r.part = string(epart)
   970  						r.pipe = path[i+1:]
   971  						r.piped = true
   972  						return
   973  					} else if path[i] == '*' || path[i] == '?' {
   974  						r.wild = true
   975  					}
   976  					epart = append(epart, path[i])
   977  				}
   978  			}
   979  			// append the last part
   980  			r.part = string(epart)
   981  			return
   982  		}
   983  	}
   984  	r.part = path
   985  	return
   986  }
   987  
   988  func parseSquash(json string, i int) (int, string) {
   989  	// expects that the lead character is a '[' or '{' or '('
   990  	// squash the value, ignoring all nested arrays and objects.
   991  	// the first '[' or '{' or '(' has already been read
   992  	s := i
   993  	i++
   994  	depth := 1
   995  	for ; i < len(json); i++ {
   996  		if json[i] >= '"' && json[i] <= '}' {
   997  			switch json[i] {
   998  			case '"':
   999  				i++
  1000  				s2 := i
  1001  				for ; i < len(json); i++ {
  1002  					if json[i] > '\\' {
  1003  						continue
  1004  					}
  1005  					if json[i] == '"' {
  1006  						// look for an escaped slash
  1007  						if json[i-1] == '\\' {
  1008  							n := 0
  1009  							for j := i - 2; j > s2-1; j-- {
  1010  								if json[j] != '\\' {
  1011  									break
  1012  								}
  1013  								n++
  1014  							}
  1015  							if n%2 == 0 {
  1016  								continue
  1017  							}
  1018  						}
  1019  						break
  1020  					}
  1021  				}
  1022  			case '{', '[', '(':
  1023  				depth++
  1024  			case '}', ']', ')':
  1025  				depth--
  1026  				if depth == 0 {
  1027  					i++
  1028  					return i, json[s:i]
  1029  				}
  1030  			}
  1031  		}
  1032  	}
  1033  	return i, json[s:]
  1034  }
  1035  
  1036  func parseObject(c *parseContext, i int, path string) (int, bool) {
  1037  	var pmatch, kesc, vesc, ok, hit bool
  1038  	var key, val string
  1039  	rp := parseObjectPath(path)
  1040  	if !rp.more && rp.piped {
  1041  		c.pipe = rp.pipe
  1042  		c.piped = true
  1043  	}
  1044  	for i < len(c.json) {
  1045  		for ; i < len(c.json); i++ {
  1046  			if c.json[i] == '"' {
  1047  				// parse_key_string
  1048  				// this is slightly different from getting s string value
  1049  				// because we don't need the outer quotes.
  1050  				i++
  1051  				var s = i
  1052  				for ; i < len(c.json); i++ {
  1053  					if c.json[i] > '\\' {
  1054  						continue
  1055  					}
  1056  					if c.json[i] == '"' {
  1057  						i, key, kesc, ok = i+1, c.json[s:i], false, true
  1058  						goto parse_key_string_done
  1059  					}
  1060  					if c.json[i] == '\\' {
  1061  						i++
  1062  						for ; i < len(c.json); i++ {
  1063  							if c.json[i] > '\\' {
  1064  								continue
  1065  							}
  1066  							if c.json[i] == '"' {
  1067  								// look for an escaped slash
  1068  								if c.json[i-1] == '\\' {
  1069  									n := 0
  1070  									for j := i - 2; j > 0; j-- {
  1071  										if c.json[j] != '\\' {
  1072  											break
  1073  										}
  1074  										n++
  1075  									}
  1076  									if n%2 == 0 {
  1077  										continue
  1078  									}
  1079  								}
  1080  								i, key, kesc, ok = i+1, c.json[s:i], true, true
  1081  								goto parse_key_string_done
  1082  							}
  1083  						}
  1084  						break
  1085  					}
  1086  				}
  1087  				key, kesc, ok = c.json[s:], false, false
  1088  			parse_key_string_done:
  1089  				break
  1090  			}
  1091  			if c.json[i] == '}' {
  1092  				return i + 1, false
  1093  			}
  1094  		}
  1095  		if !ok {
  1096  			return i, false
  1097  		}
  1098  		if rp.wild {
  1099  			if kesc {
  1100  				pmatch = matchLimit(unescape(key), rp.part)
  1101  			} else {
  1102  				pmatch = matchLimit(key, rp.part)
  1103  			}
  1104  		} else {
  1105  			if kesc {
  1106  				pmatch = rp.part == unescape(key)
  1107  			} else {
  1108  				pmatch = rp.part == key
  1109  			}
  1110  		}
  1111  		hit = pmatch && !rp.more
  1112  		for ; i < len(c.json); i++ {
  1113  			switch c.json[i] {
  1114  			default:
  1115  				continue
  1116  			case '"':
  1117  				i++
  1118  				i, val, vesc, ok = parseString(c.json, i)
  1119  				if !ok {
  1120  					return i, false
  1121  				}
  1122  				if hit {
  1123  					if vesc {
  1124  						c.value.Str = unescape(val[1 : len(val)-1])
  1125  					} else {
  1126  						c.value.Str = val[1 : len(val)-1]
  1127  					}
  1128  					c.value.Raw = val
  1129  					c.value.Type = String
  1130  					return i, true
  1131  				}
  1132  			case '{':
  1133  				if pmatch && !hit {
  1134  					i, hit = parseObject(c, i+1, rp.path)
  1135  					if hit {
  1136  						return i, true
  1137  					}
  1138  				} else {
  1139  					i, val = parseSquash(c.json, i)
  1140  					if hit {
  1141  						c.value.Raw = val
  1142  						c.value.Type = JSON
  1143  						return i, true
  1144  					}
  1145  				}
  1146  			case '[':
  1147  				if pmatch && !hit {
  1148  					i, hit = parseArray(c, i+1, rp.path)
  1149  					if hit {
  1150  						return i, true
  1151  					}
  1152  				} else {
  1153  					i, val = parseSquash(c.json, i)
  1154  					if hit {
  1155  						c.value.Raw = val
  1156  						c.value.Type = JSON
  1157  						return i, true
  1158  					}
  1159  				}
  1160  			case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  1161  				i, val = parseNumber(c.json, i)
  1162  				if hit {
  1163  					c.value.Raw = val
  1164  					c.value.Type = Number
  1165  					c.value.Num, _ = strconv.ParseFloat(val, 64)
  1166  					return i, true
  1167  				}
  1168  			case 't', 'f', 'n':
  1169  				vc := c.json[i]
  1170  				i, val = parseLiteral(c.json, i)
  1171  				if hit {
  1172  					c.value.Raw = val
  1173  					switch vc {
  1174  					case 't':
  1175  						c.value.Type = True
  1176  					case 'f':
  1177  						c.value.Type = False
  1178  					}
  1179  					return i, true
  1180  				}
  1181  			}
  1182  			break
  1183  		}
  1184  	}
  1185  	return i, false
  1186  }
  1187  
  1188  // matchLimit will limit the complexity of the match operation to avoid ReDos
  1189  // attacks from arbritary inputs.
  1190  // See the github.com/tidwall/match.MatchLimit function for more information.
  1191  func matchLimit(str, pattern string) bool {
  1192  	matched, _ := match.MatchLimit(str, pattern, 10000)
  1193  	return matched
  1194  }
  1195  
  1196  func queryMatches(rp *arrayPathResult, value Result) bool {
  1197  	rpv := rp.query.value
  1198  	if len(rpv) > 0 && rpv[0] == '~' {
  1199  		// convert to bool
  1200  		rpv = rpv[1:]
  1201  		if value.Bool() {
  1202  			value = Result{Type: True}
  1203  		} else {
  1204  			value = Result{Type: False}
  1205  		}
  1206  	}
  1207  	if !value.Exists() {
  1208  		return false
  1209  	}
  1210  	if rp.query.op == "" {
  1211  		// the query is only looking for existence, such as:
  1212  		//   friends.#(name)
  1213  		// which makes sure that the array "friends" has an element of
  1214  		// "name" that exists
  1215  		return true
  1216  	}
  1217  	switch value.Type {
  1218  	case String:
  1219  		switch rp.query.op {
  1220  		case "=":
  1221  			return value.Str == rpv
  1222  		case "!=":
  1223  			return value.Str != rpv
  1224  		case "<":
  1225  			return value.Str < rpv
  1226  		case "<=":
  1227  			return value.Str <= rpv
  1228  		case ">":
  1229  			return value.Str > rpv
  1230  		case ">=":
  1231  			return value.Str >= rpv
  1232  		case "%":
  1233  			return matchLimit(value.Str, rpv)
  1234  		case "!%":
  1235  			return !matchLimit(value.Str, rpv)
  1236  		}
  1237  	case Number:
  1238  		rpvn, _ := strconv.ParseFloat(rpv, 64)
  1239  		switch rp.query.op {
  1240  		case "=":
  1241  			return value.Num == rpvn
  1242  		case "!=":
  1243  			return value.Num != rpvn
  1244  		case "<":
  1245  			return value.Num < rpvn
  1246  		case "<=":
  1247  			return value.Num <= rpvn
  1248  		case ">":
  1249  			return value.Num > rpvn
  1250  		case ">=":
  1251  			return value.Num >= rpvn
  1252  		}
  1253  	case True:
  1254  		switch rp.query.op {
  1255  		case "=":
  1256  			return rpv == "true"
  1257  		case "!=":
  1258  			return rpv != "true"
  1259  		case ">":
  1260  			return rpv == "false"
  1261  		case ">=":
  1262  			return true
  1263  		}
  1264  	case False:
  1265  		switch rp.query.op {
  1266  		case "=":
  1267  			return rpv == "false"
  1268  		case "!=":
  1269  			return rpv != "false"
  1270  		case "<":
  1271  			return rpv == "true"
  1272  		case "<=":
  1273  			return true
  1274  		}
  1275  	}
  1276  	return false
  1277  }
  1278  func parseArray(c *parseContext, i int, path string) (int, bool) {
  1279  	var pmatch, vesc, ok, hit bool
  1280  	var val string
  1281  	var h int
  1282  	var alog []int
  1283  	var partidx int
  1284  	var multires []byte
  1285  	var queryIndexes []int
  1286  	rp := parseArrayPath(path)
  1287  	if !rp.arrch {
  1288  		n, ok := parseUint(rp.part)
  1289  		if !ok {
  1290  			partidx = -1
  1291  		} else {
  1292  			partidx = int(n)
  1293  		}
  1294  	}
  1295  	if !rp.more && rp.piped {
  1296  		c.pipe = rp.pipe
  1297  		c.piped = true
  1298  	}
  1299  
  1300  	procQuery := func(qval Result) bool {
  1301  		if rp.query.all {
  1302  			if len(multires) == 0 {
  1303  				multires = append(multires, '[')
  1304  			}
  1305  		}
  1306  		var tmp parseContext
  1307  		tmp.value = qval
  1308  		fillIndex(c.json, &tmp)
  1309  		parentIndex := tmp.value.Index
  1310  		var res Result
  1311  		if qval.Type == JSON {
  1312  			res = qval.Get(rp.query.path)
  1313  		} else {
  1314  			if rp.query.path != "" {
  1315  				return false
  1316  			}
  1317  			res = qval
  1318  		}
  1319  		if queryMatches(&rp, res) {
  1320  			if rp.more {
  1321  				left, right, ok := splitPossiblePipe(rp.path)
  1322  				if ok {
  1323  					rp.path = left
  1324  					c.pipe = right
  1325  					c.piped = true
  1326  				}
  1327  				res = qval.Get(rp.path)
  1328  			} else {
  1329  				res = qval
  1330  			}
  1331  			if rp.query.all {
  1332  				raw := res.Raw
  1333  				if len(raw) == 0 {
  1334  					raw = res.String()
  1335  				}
  1336  				if raw != "" {
  1337  					if len(multires) > 1 {
  1338  						multires = append(multires, ',')
  1339  					}
  1340  					multires = append(multires, raw...)
  1341  					queryIndexes = append(queryIndexes, res.Index+parentIndex)
  1342  				}
  1343  			} else {
  1344  				c.value = res
  1345  				return true
  1346  			}
  1347  		}
  1348  		return false
  1349  	}
  1350  	for i < len(c.json)+1 {
  1351  		if !rp.arrch {
  1352  			pmatch = partidx == h
  1353  			hit = pmatch && !rp.more
  1354  		}
  1355  		h++
  1356  		if rp.alogok {
  1357  			alog = append(alog, i)
  1358  		}
  1359  		for ; ; i++ {
  1360  			var ch byte
  1361  			if i > len(c.json) {
  1362  				break
  1363  			} else if i == len(c.json) {
  1364  				ch = ']'
  1365  			} else {
  1366  				ch = c.json[i]
  1367  			}
  1368  			switch ch {
  1369  			default:
  1370  				continue
  1371  			case '"':
  1372  				i++
  1373  				i, val, vesc, ok = parseString(c.json, i)
  1374  				if !ok {
  1375  					return i, false
  1376  				}
  1377  				if rp.query.on {
  1378  					var qval Result
  1379  					if vesc {
  1380  						qval.Str = unescape(val[1 : len(val)-1])
  1381  					} else {
  1382  						qval.Str = val[1 : len(val)-1]
  1383  					}
  1384  					qval.Raw = val
  1385  					qval.Type = String
  1386  					if procQuery(qval) {
  1387  						return i, true
  1388  					}
  1389  				} else if hit {
  1390  					if rp.alogok {
  1391  						break
  1392  					}
  1393  					if vesc {
  1394  						c.value.Str = unescape(val[1 : len(val)-1])
  1395  					} else {
  1396  						c.value.Str = val[1 : len(val)-1]
  1397  					}
  1398  					c.value.Raw = val
  1399  					c.value.Type = String
  1400  					return i, true
  1401  				}
  1402  			case '{':
  1403  				if pmatch && !hit {
  1404  					i, hit = parseObject(c, i+1, rp.path)
  1405  					if hit {
  1406  						if rp.alogok {
  1407  							break
  1408  						}
  1409  						return i, true
  1410  					}
  1411  				} else {
  1412  					i, val = parseSquash(c.json, i)
  1413  					if rp.query.on {
  1414  						if procQuery(Result{Raw: val, Type: JSON}) {
  1415  							return i, true
  1416  						}
  1417  					} else if hit {
  1418  						if rp.alogok {
  1419  							break
  1420  						}
  1421  						c.value.Raw = val
  1422  						c.value.Type = JSON
  1423  						return i, true
  1424  					}
  1425  				}
  1426  			case '[':
  1427  				if pmatch && !hit {
  1428  					i, hit = parseArray(c, i+1, rp.path)
  1429  					if hit {
  1430  						if rp.alogok {
  1431  							break
  1432  						}
  1433  						return i, true
  1434  					}
  1435  				} else {
  1436  					i, val = parseSquash(c.json, i)
  1437  					if rp.query.on {
  1438  						if procQuery(Result{Raw: val, Type: JSON}) {
  1439  							return i, true
  1440  						}
  1441  					} else if hit {
  1442  						if rp.alogok {
  1443  							break
  1444  						}
  1445  						c.value.Raw = val
  1446  						c.value.Type = JSON
  1447  						return i, true
  1448  					}
  1449  				}
  1450  			case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  1451  				i, val = parseNumber(c.json, i)
  1452  				if rp.query.on {
  1453  					var qval Result
  1454  					qval.Raw = val
  1455  					qval.Type = Number
  1456  					qval.Num, _ = strconv.ParseFloat(val, 64)
  1457  					if procQuery(qval) {
  1458  						return i, true
  1459  					}
  1460  				} else if hit {
  1461  					if rp.alogok {
  1462  						break
  1463  					}
  1464  					c.value.Raw = val
  1465  					c.value.Type = Number
  1466  					c.value.Num, _ = strconv.ParseFloat(val, 64)
  1467  					return i, true
  1468  				}
  1469  			case 't', 'f', 'n':
  1470  				vc := c.json[i]
  1471  				i, val = parseLiteral(c.json, i)
  1472  				if rp.query.on {
  1473  					var qval Result
  1474  					qval.Raw = val
  1475  					switch vc {
  1476  					case 't':
  1477  						qval.Type = True
  1478  					case 'f':
  1479  						qval.Type = False
  1480  					}
  1481  					if procQuery(qval) {
  1482  						return i, true
  1483  					}
  1484  				} else if hit {
  1485  					if rp.alogok {
  1486  						break
  1487  					}
  1488  					c.value.Raw = val
  1489  					switch vc {
  1490  					case 't':
  1491  						c.value.Type = True
  1492  					case 'f':
  1493  						c.value.Type = False
  1494  					}
  1495  					return i, true
  1496  				}
  1497  			case ']':
  1498  				if rp.arrch && rp.part == "#" {
  1499  					if rp.alogok {
  1500  						left, right, ok := splitPossiblePipe(rp.alogkey)
  1501  						if ok {
  1502  							rp.alogkey = left
  1503  							c.pipe = right
  1504  							c.piped = true
  1505  						}
  1506  						var indexes = make([]int, 0, 64)
  1507  						var jsons = make([]byte, 0, 64)
  1508  						jsons = append(jsons, '[')
  1509  						for j, k := 0, 0; j < len(alog); j++ {
  1510  							idx := alog[j]
  1511  							for idx < len(c.json) {
  1512  								switch c.json[idx] {
  1513  								case ' ', '\t', '\r', '\n':
  1514  									idx++
  1515  									continue
  1516  								}
  1517  								break
  1518  							}
  1519  							if idx < len(c.json) && c.json[idx] != ']' {
  1520  								_, res, ok := parseAny(c.json, idx, true)
  1521  								parentIndex := res.Index
  1522  								if ok {
  1523  									res := res.Get(rp.alogkey)
  1524  									if res.Exists() {
  1525  										if k > 0 {
  1526  											jsons = append(jsons, ',')
  1527  										}
  1528  										raw := res.Raw
  1529  										if len(raw) == 0 {
  1530  											raw = res.String()
  1531  										}
  1532  										jsons = append(jsons, []byte(raw)...)
  1533  										indexes = append(indexes,
  1534  											res.Index+parentIndex)
  1535  										k++
  1536  									}
  1537  								}
  1538  							}
  1539  						}
  1540  						jsons = append(jsons, ']')
  1541  						c.value.Type = JSON
  1542  						c.value.Raw = string(jsons)
  1543  						c.value.Indexes = indexes
  1544  						return i + 1, true
  1545  					}
  1546  					if rp.alogok {
  1547  						break
  1548  					}
  1549  
  1550  					c.value.Type = Number
  1551  					c.value.Num = float64(h - 1)
  1552  					c.value.Raw = strconv.Itoa(h - 1)
  1553  					c.calcd = true
  1554  					return i + 1, true
  1555  				}
  1556  				if !c.value.Exists() {
  1557  					if len(multires) > 0 {
  1558  						c.value = Result{
  1559  							Raw:     string(append(multires, ']')),
  1560  							Type:    JSON,
  1561  							Indexes: queryIndexes,
  1562  						}
  1563  					} else if rp.query.all {
  1564  						c.value = Result{
  1565  							Raw:  "[]",
  1566  							Type: JSON,
  1567  						}
  1568  					}
  1569  				}
  1570  				return i + 1, false
  1571  			}
  1572  			break
  1573  		}
  1574  	}
  1575  	return i, false
  1576  }
  1577  
  1578  func splitPossiblePipe(path string) (left, right string, ok bool) {
  1579  	// take a quick peek for the pipe character. If found we'll split the piped
  1580  	// part of the path into the c.pipe field and shorten the rp.
  1581  	var possible bool
  1582  	for i := 0; i < len(path); i++ {
  1583  		if path[i] == '|' {
  1584  			possible = true
  1585  			break
  1586  		}
  1587  	}
  1588  	if !possible {
  1589  		return
  1590  	}
  1591  
  1592  	if len(path) > 0 && path[0] == '{' {
  1593  		squashed := squash(path[1:])
  1594  		if len(squashed) < len(path)-1 {
  1595  			squashed = path[:len(squashed)+1]
  1596  			remain := path[len(squashed):]
  1597  			if remain[0] == '|' {
  1598  				return squashed, remain[1:], true
  1599  			}
  1600  		}
  1601  		return
  1602  	}
  1603  
  1604  	// split the left and right side of the path with the pipe character as
  1605  	// the delimiter. This is a little tricky because we'll need to basically
  1606  	// parse the entire path.
  1607  	for i := 0; i < len(path); i++ {
  1608  		if path[i] == '\\' {
  1609  			i++
  1610  		} else if path[i] == '.' {
  1611  			if i == len(path)-1 {
  1612  				return
  1613  			}
  1614  			if path[i+1] == '#' {
  1615  				i += 2
  1616  				if i == len(path) {
  1617  					return
  1618  				}
  1619  				if path[i] == '[' || path[i] == '(' {
  1620  					var start, end byte
  1621  					if path[i] == '[' {
  1622  						start, end = '[', ']'
  1623  					} else {
  1624  						start, end = '(', ')'
  1625  					}
  1626  					// inside selector, balance brackets
  1627  					i++
  1628  					depth := 1
  1629  					for ; i < len(path); i++ {
  1630  						if path[i] == '\\' {
  1631  							i++
  1632  						} else if path[i] == start {
  1633  							depth++
  1634  						} else if path[i] == end {
  1635  							depth--
  1636  							if depth == 0 {
  1637  								break
  1638  							}
  1639  						} else if path[i] == '"' {
  1640  							// inside selector string, balance quotes
  1641  							i++
  1642  							for ; i < len(path); i++ {
  1643  								if path[i] == '\\' {
  1644  									i++
  1645  								} else if path[i] == '"' {
  1646  									break
  1647  								}
  1648  							}
  1649  						}
  1650  					}
  1651  				}
  1652  			}
  1653  		} else if path[i] == '|' {
  1654  			return path[:i], path[i+1:], true
  1655  		}
  1656  	}
  1657  	return
  1658  }
  1659  
  1660  // ForEachLine iterates through lines of JSON as specified by the JSON Lines
  1661  // format (http://jsonlines.org/).
  1662  // Each line is returned as a GJSON Result.
  1663  func ForEachLine(json string, iterator func(line Result) bool) {
  1664  	var res Result
  1665  	var i int
  1666  	for {
  1667  		i, res, _ = parseAny(json, i, true)
  1668  		if !res.Exists() {
  1669  			break
  1670  		}
  1671  		if !iterator(res) {
  1672  			return
  1673  		}
  1674  	}
  1675  }
  1676  
  1677  type subSelector struct {
  1678  	name string
  1679  	path string
  1680  }
  1681  
  1682  // parseSubSelectors returns the subselectors belonging to a '[path1,path2]' or
  1683  // '{"field1":path1,"field2":path2}' type subSelection. It's expected that the
  1684  // first character in path is either '[' or '{', and has already been checked
  1685  // prior to calling this function.
  1686  func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) {
  1687  	modifer := 0
  1688  	depth := 1
  1689  	colon := 0
  1690  	start := 1
  1691  	i := 1
  1692  	pushSel := func() {
  1693  		var sel subSelector
  1694  		if colon == 0 {
  1695  			sel.path = path[start:i]
  1696  		} else {
  1697  			sel.name = path[start:colon]
  1698  			sel.path = path[colon+1 : i]
  1699  		}
  1700  		sels = append(sels, sel)
  1701  		colon = 0
  1702  		start = i + 1
  1703  	}
  1704  	for ; i < len(path); i++ {
  1705  		switch path[i] {
  1706  		case '\\':
  1707  			i++
  1708  		case '@':
  1709  			if modifer == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') {
  1710  				modifer = i
  1711  			}
  1712  		case ':':
  1713  			if modifer == 0 && colon == 0 && depth == 1 {
  1714  				colon = i
  1715  			}
  1716  		case ',':
  1717  			if depth == 1 {
  1718  				pushSel()
  1719  			}
  1720  		case '"':
  1721  			i++
  1722  		loop:
  1723  			for ; i < len(path); i++ {
  1724  				switch path[i] {
  1725  				case '\\':
  1726  					i++
  1727  				case '"':
  1728  					break loop
  1729  				}
  1730  			}
  1731  		case '[', '(', '{':
  1732  			depth++
  1733  		case ']', ')', '}':
  1734  			depth--
  1735  			if depth == 0 {
  1736  				pushSel()
  1737  				path = path[i+1:]
  1738  				return sels, path, true
  1739  			}
  1740  		}
  1741  	}
  1742  	return
  1743  }
  1744  
  1745  // nameOfLast returns the name of the last component
  1746  func nameOfLast(path string) string {
  1747  	for i := len(path) - 1; i >= 0; i-- {
  1748  		if path[i] == '|' || path[i] == '.' {
  1749  			if i > 0 {
  1750  				if path[i-1] == '\\' {
  1751  					continue
  1752  				}
  1753  			}
  1754  			return path[i+1:]
  1755  		}
  1756  	}
  1757  	return path
  1758  }
  1759  
  1760  func isSimpleName(component string) bool {
  1761  	for i := 0; i < len(component); i++ {
  1762  		if component[i] < ' ' {
  1763  			return false
  1764  		}
  1765  		switch component[i] {
  1766  		case '[', ']', '{', '}', '(', ')', '#', '|':
  1767  			return false
  1768  		}
  1769  	}
  1770  	return true
  1771  }
  1772  
  1773  func appendJSONString(dst []byte, s string) []byte {
  1774  	for i := 0; i < len(s); i++ {
  1775  		if s[i] < ' ' || s[i] == '\\' || s[i] == '"' || s[i] > 126 {
  1776  			d, _ := json.Marshal(s)
  1777  			return append(dst, string(d)...)
  1778  		}
  1779  	}
  1780  	dst = append(dst, '"')
  1781  	dst = append(dst, s...)
  1782  	dst = append(dst, '"')
  1783  	return dst
  1784  }
  1785  
  1786  type parseContext struct {
  1787  	json  string
  1788  	value Result
  1789  	pipe  string
  1790  	piped bool
  1791  	calcd bool
  1792  	lines bool
  1793  }
  1794  
  1795  // Get searches json for the specified path.
  1796  // A path is in dot syntax, such as "name.last" or "age".
  1797  // When the value is found it's returned immediately.
  1798  //
  1799  // A path is a series of keys separated by a dot.
  1800  // A key may contain special wildcard characters '*' and '?'.
  1801  // To access an array value use the index as the key.
  1802  // To get the number of elements in an array or to access a child path, use
  1803  // the '#' character.
  1804  // The dot and wildcard character can be escaped with '\'.
  1805  //
  1806  //	{
  1807  //	  "name": {"first": "Tom", "last": "Anderson"},
  1808  //	  "age":37,
  1809  //	  "children": ["Sara","Alex","Jack"],
  1810  //	  "friends": [
  1811  //	    {"first": "James", "last": "Murphy"},
  1812  //	    {"first": "Roger", "last": "Craig"}
  1813  //	  ]
  1814  //	}
  1815  //	"name.last"          >> "Anderson"
  1816  //	"age"                >> 37
  1817  //	"children"           >> ["Sara","Alex","Jack"]
  1818  //	"children.#"         >> 3
  1819  //	"children.1"         >> "Alex"
  1820  //	"child*.2"           >> "Jack"
  1821  //	"c?ildren.0"         >> "Sara"
  1822  //	"friends.#.first"    >> ["James","Roger"]
  1823  //
  1824  // This function expects that the json is well-formed, and does not validate.
  1825  // Invalid json will not panic, but it may return back unexpected results.
  1826  // If you are consuming JSON from an unpredictable source then you may want to
  1827  // use the Valid function first.
  1828  func Get(json, path string) Result {
  1829  	if len(path) > 1 {
  1830  		if !DisableModifiers {
  1831  			if path[0] == '@' {
  1832  				// possible modifier
  1833  				var ok bool
  1834  				var npath string
  1835  				var rjson string
  1836  				npath, rjson, ok = execModifier(json, path)
  1837  				if ok {
  1838  					path = npath
  1839  					if len(path) > 0 && (path[0] == '|' || path[0] == '.') {
  1840  						res := Get(rjson, path[1:])
  1841  						res.Index = 0
  1842  						res.Indexes = nil
  1843  						return res
  1844  					}
  1845  					return Parse(rjson)
  1846  				}
  1847  			}
  1848  		}
  1849  		if path[0] == '[' || path[0] == '{' {
  1850  			// using a subselector path
  1851  			kind := path[0]
  1852  			var ok bool
  1853  			var subs []subSelector
  1854  			subs, path, ok = parseSubSelectors(path)
  1855  			if ok {
  1856  				if len(path) == 0 || (path[0] == '|' || path[0] == '.') {
  1857  					var b []byte
  1858  					b = append(b, kind)
  1859  					var i int
  1860  					for _, sub := range subs {
  1861  						res := Get(json, sub.path)
  1862  						if res.Exists() {
  1863  							if i > 0 {
  1864  								b = append(b, ',')
  1865  							}
  1866  							if kind == '{' {
  1867  								if len(sub.name) > 0 {
  1868  									if sub.name[0] == '"' && Valid(sub.name) {
  1869  										b = append(b, sub.name...)
  1870  									} else {
  1871  										b = appendJSONString(b, sub.name)
  1872  									}
  1873  								} else {
  1874  									last := nameOfLast(sub.path)
  1875  									if isSimpleName(last) {
  1876  										b = appendJSONString(b, last)
  1877  									} else {
  1878  										b = appendJSONString(b, "_")
  1879  									}
  1880  								}
  1881  								b = append(b, ':')
  1882  							}
  1883  							var raw string
  1884  							if len(res.Raw) == 0 {
  1885  								raw = res.String()
  1886  								if len(raw) == 0 {
  1887  									raw = "null"
  1888  								}
  1889  							} else {
  1890  								raw = res.Raw
  1891  							}
  1892  							b = append(b, raw...)
  1893  							i++
  1894  						}
  1895  					}
  1896  					b = append(b, kind+2)
  1897  					var res Result
  1898  					res.Raw = string(b)
  1899  					res.Type = JSON
  1900  					if len(path) > 0 {
  1901  						res = res.Get(path[1:])
  1902  					}
  1903  					res.Index = 0
  1904  					return res
  1905  				}
  1906  			}
  1907  		}
  1908  	}
  1909  	var i int
  1910  	var c = &parseContext{json: json}
  1911  	if len(path) >= 2 && path[0] == '.' && path[1] == '.' {
  1912  		c.lines = true
  1913  		parseArray(c, 0, path[2:])
  1914  	} else {
  1915  		for ; i < len(c.json); i++ {
  1916  			if c.json[i] == '{' {
  1917  				i++
  1918  				parseObject(c, i, path)
  1919  				break
  1920  			}
  1921  			if c.json[i] == '[' {
  1922  				i++
  1923  				parseArray(c, i, path)
  1924  				break
  1925  			}
  1926  		}
  1927  	}
  1928  	if c.piped {
  1929  		res := c.value.Get(c.pipe)
  1930  		res.Index = 0
  1931  		return res
  1932  	}
  1933  	fillIndex(json, c)
  1934  	return c.value
  1935  }
  1936  
  1937  // GetBytes searches json for the specified path.
  1938  // If working with bytes, this method preferred over Get(string(data), path)
  1939  func GetBytes(json []byte, path string) Result {
  1940  	return getBytes(json, path)
  1941  }
  1942  
  1943  // runeit returns the rune from the the \uXXXX
  1944  func runeit(json string) rune {
  1945  	n, _ := strconv.ParseUint(json[:4], 16, 64)
  1946  	return rune(n)
  1947  }
  1948  
  1949  // unescape unescapes a string
  1950  func unescape(json string) string {
  1951  	var str = make([]byte, 0, len(json))
  1952  	for i := 0; i < len(json); i++ {
  1953  		switch {
  1954  		default:
  1955  			str = append(str, json[i])
  1956  		case json[i] < ' ':
  1957  			return string(str)
  1958  		case json[i] == '\\':
  1959  			i++
  1960  			if i >= len(json) {
  1961  				return string(str)
  1962  			}
  1963  			switch json[i] {
  1964  			default:
  1965  				return string(str)
  1966  			case '\\':
  1967  				str = append(str, '\\')
  1968  			case '/':
  1969  				str = append(str, '/')
  1970  			case 'b':
  1971  				str = append(str, '\b')
  1972  			case 'f':
  1973  				str = append(str, '\f')
  1974  			case 'n':
  1975  				str = append(str, '\n')
  1976  			case 'r':
  1977  				str = append(str, '\r')
  1978  			case 't':
  1979  				str = append(str, '\t')
  1980  			case '"':
  1981  				str = append(str, '"')
  1982  			case 'u':
  1983  				if i+5 > len(json) {
  1984  					return string(str)
  1985  				}
  1986  				r := runeit(json[i+1:])
  1987  				i += 5
  1988  				if utf16.IsSurrogate(r) {
  1989  					// need another code
  1990  					if len(json[i:]) >= 6 && json[i] == '\\' &&
  1991  						json[i+1] == 'u' {
  1992  						// we expect it to be correct so just consume it
  1993  						r = utf16.DecodeRune(r, runeit(json[i+2:]))
  1994  						i += 6
  1995  					}
  1996  				}
  1997  				// provide enough space to encode the largest utf8 possible
  1998  				str = append(str, 0, 0, 0, 0, 0, 0, 0, 0)
  1999  				n := utf8.EncodeRune(str[len(str)-8:], r)
  2000  				str = str[:len(str)-8+n]
  2001  				i-- // backtrack index by one
  2002  			}
  2003  		}
  2004  	}
  2005  	return string(str)
  2006  }
  2007  
  2008  // Less return true if a token is less than another token.
  2009  // The caseSensitive paramater is used when the tokens are Strings.
  2010  // The order when comparing two different type is:
  2011  //
  2012  //	Null < False < Number < String < True < JSON
  2013  func (t Result) Less(token Result, caseSensitive bool) bool {
  2014  	if t.Type < token.Type {
  2015  		return true
  2016  	}
  2017  	if t.Type > token.Type {
  2018  		return false
  2019  	}
  2020  	if t.Type == String {
  2021  		if caseSensitive {
  2022  			return t.Str < token.Str
  2023  		}
  2024  		return stringLessInsensitive(t.Str, token.Str)
  2025  	}
  2026  	if t.Type == Number {
  2027  		return t.Num < token.Num
  2028  	}
  2029  	return t.Raw < token.Raw
  2030  }
  2031  
  2032  func stringLessInsensitive(a, b string) bool {
  2033  	for i := 0; i < len(a) && i < len(b); i++ {
  2034  		if a[i] >= 'A' && a[i] <= 'Z' {
  2035  			if b[i] >= 'A' && b[i] <= 'Z' {
  2036  				// both are uppercase, do nothing
  2037  				if a[i] < b[i] {
  2038  					return true
  2039  				} else if a[i] > b[i] {
  2040  					return false
  2041  				}
  2042  			} else {
  2043  				// a is uppercase, convert a to lowercase
  2044  				if a[i]+32 < b[i] {
  2045  					return true
  2046  				} else if a[i]+32 > b[i] {
  2047  					return false
  2048  				}
  2049  			}
  2050  		} else if b[i] >= 'A' && b[i] <= 'Z' {
  2051  			// b is uppercase, convert b to lowercase
  2052  			if a[i] < b[i]+32 {
  2053  				return true
  2054  			} else if a[i] > b[i]+32 {
  2055  				return false
  2056  			}
  2057  		} else {
  2058  			// neither are uppercase
  2059  			if a[i] < b[i] {
  2060  				return true
  2061  			} else if a[i] > b[i] {
  2062  				return false
  2063  			}
  2064  		}
  2065  	}
  2066  	return len(a) < len(b)
  2067  }
  2068  
  2069  // parseAny parses the next value from a json string.
  2070  // A Result is returned when the hit param is set.
  2071  // The return values are (i int, res Result, ok bool)
  2072  func parseAny(json string, i int, hit bool) (int, Result, bool) {
  2073  	var res Result
  2074  	var val string
  2075  	for ; i < len(json); i++ {
  2076  		if json[i] == '{' || json[i] == '[' {
  2077  			i, val = parseSquash(json, i)
  2078  			if hit {
  2079  				res.Raw = val
  2080  				res.Type = JSON
  2081  			}
  2082  			var tmp parseContext
  2083  			tmp.value = res
  2084  			fillIndex(json, &tmp)
  2085  			return i, tmp.value, true
  2086  		}
  2087  		if json[i] <= ' ' {
  2088  			continue
  2089  		}
  2090  		switch json[i] {
  2091  		case '"':
  2092  			i++
  2093  			var vesc bool
  2094  			var ok bool
  2095  			i, val, vesc, ok = parseString(json, i)
  2096  			if !ok {
  2097  				return i, res, false
  2098  			}
  2099  			if hit {
  2100  				res.Type = String
  2101  				res.Raw = val
  2102  				if vesc {
  2103  					res.Str = unescape(val[1 : len(val)-1])
  2104  				} else {
  2105  					res.Str = val[1 : len(val)-1]
  2106  				}
  2107  			}
  2108  			return i, res, true
  2109  		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  2110  			i, val = parseNumber(json, i)
  2111  			if hit {
  2112  				res.Raw = val
  2113  				res.Type = Number
  2114  				res.Num, _ = strconv.ParseFloat(val, 64)
  2115  			}
  2116  			return i, res, true
  2117  		case 't', 'f', 'n':
  2118  			vc := json[i]
  2119  			i, val = parseLiteral(json, i)
  2120  			if hit {
  2121  				res.Raw = val
  2122  				switch vc {
  2123  				case 't':
  2124  					res.Type = True
  2125  				case 'f':
  2126  					res.Type = False
  2127  				}
  2128  				return i, res, true
  2129  			}
  2130  		}
  2131  	}
  2132  	return i, res, false
  2133  }
  2134  
  2135  // GetMany searches json for the multiple paths.
  2136  // The return value is a Result array where the number of items
  2137  // will be equal to the number of input paths.
  2138  func GetMany(json string, path ...string) []Result {
  2139  	res := make([]Result, len(path))
  2140  	for i, path := range path {
  2141  		res[i] = Get(json, path)
  2142  	}
  2143  	return res
  2144  }
  2145  
  2146  // GetManyBytes searches json for the multiple paths.
  2147  // The return value is a Result array where the number of items
  2148  // will be equal to the number of input paths.
  2149  func GetManyBytes(json []byte, path ...string) []Result {
  2150  	res := make([]Result, len(path))
  2151  	for i, path := range path {
  2152  		res[i] = GetBytes(json, path)
  2153  	}
  2154  	return res
  2155  }
  2156  
  2157  func validpayload(data []byte, i int) (outi int, ok bool) {
  2158  	for ; i < len(data); i++ {
  2159  		switch data[i] {
  2160  		default:
  2161  			i, ok = validany(data, i)
  2162  			if !ok {
  2163  				return i, false
  2164  			}
  2165  			for ; i < len(data); i++ {
  2166  				switch data[i] {
  2167  				default:
  2168  					return i, false
  2169  				case ' ', '\t', '\n', '\r':
  2170  					continue
  2171  				}
  2172  			}
  2173  			return i, true
  2174  		case ' ', '\t', '\n', '\r':
  2175  			continue
  2176  		}
  2177  	}
  2178  	return i, false
  2179  }
  2180  func validany(data []byte, i int) (outi int, ok bool) {
  2181  	for ; i < len(data); i++ {
  2182  		switch data[i] {
  2183  		default:
  2184  			return i, false
  2185  		case ' ', '\t', '\n', '\r':
  2186  			continue
  2187  		case '{':
  2188  			return validobject(data, i+1)
  2189  		case '[':
  2190  			return validarray(data, i+1)
  2191  		case '"':
  2192  			return validstring(data, i+1)
  2193  		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  2194  			return validnumber(data, i+1)
  2195  		case 't':
  2196  			return validtrue(data, i+1)
  2197  		case 'f':
  2198  			return validfalse(data, i+1)
  2199  		case 'n':
  2200  			return validnull(data, i+1)
  2201  		}
  2202  	}
  2203  	return i, false
  2204  }
  2205  func validobject(data []byte, i int) (outi int, ok bool) {
  2206  	for ; i < len(data); i++ {
  2207  		switch data[i] {
  2208  		default:
  2209  			return i, false
  2210  		case ' ', '\t', '\n', '\r':
  2211  			continue
  2212  		case '}':
  2213  			return i + 1, true
  2214  		case '"':
  2215  		key:
  2216  			if i, ok = validstring(data, i+1); !ok {
  2217  				return i, false
  2218  			}
  2219  			if i, ok = validcolon(data, i); !ok {
  2220  				return i, false
  2221  			}
  2222  			if i, ok = validany(data, i); !ok {
  2223  				return i, false
  2224  			}
  2225  			if i, ok = validcomma(data, i, '}'); !ok {
  2226  				return i, false
  2227  			}
  2228  			if data[i] == '}' {
  2229  				return i + 1, true
  2230  			}
  2231  			i++
  2232  			for ; i < len(data); i++ {
  2233  				switch data[i] {
  2234  				default:
  2235  					return i, false
  2236  				case ' ', '\t', '\n', '\r':
  2237  					continue
  2238  				case '"':
  2239  					goto key
  2240  				}
  2241  			}
  2242  			return i, false
  2243  		}
  2244  	}
  2245  	return i, false
  2246  }
  2247  func validcolon(data []byte, i int) (outi int, ok bool) {
  2248  	for ; i < len(data); i++ {
  2249  		switch data[i] {
  2250  		default:
  2251  			return i, false
  2252  		case ' ', '\t', '\n', '\r':
  2253  			continue
  2254  		case ':':
  2255  			return i + 1, true
  2256  		}
  2257  	}
  2258  	return i, false
  2259  }
  2260  func validcomma(data []byte, i int, end byte) (outi int, ok bool) {
  2261  	for ; i < len(data); i++ {
  2262  		switch data[i] {
  2263  		default:
  2264  			return i, false
  2265  		case ' ', '\t', '\n', '\r':
  2266  			continue
  2267  		case ',':
  2268  			return i, true
  2269  		case end:
  2270  			return i, true
  2271  		}
  2272  	}
  2273  	return i, false
  2274  }
  2275  func validarray(data []byte, i int) (outi int, ok bool) {
  2276  	for ; i < len(data); i++ {
  2277  		switch data[i] {
  2278  		default:
  2279  			for ; i < len(data); i++ {
  2280  				if i, ok = validany(data, i); !ok {
  2281  					return i, false
  2282  				}
  2283  				if i, ok = validcomma(data, i, ']'); !ok {
  2284  					return i, false
  2285  				}
  2286  				if data[i] == ']' {
  2287  					return i + 1, true
  2288  				}
  2289  			}
  2290  		case ' ', '\t', '\n', '\r':
  2291  			continue
  2292  		case ']':
  2293  			return i + 1, true
  2294  		}
  2295  	}
  2296  	return i, false
  2297  }
  2298  func validstring(data []byte, i int) (outi int, ok bool) {
  2299  	for ; i < len(data); i++ {
  2300  		if data[i] < ' ' {
  2301  			return i, false
  2302  		} else if data[i] == '\\' {
  2303  			i++
  2304  			if i == len(data) {
  2305  				return i, false
  2306  			}
  2307  			switch data[i] {
  2308  			default:
  2309  				return i, false
  2310  			case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
  2311  			case 'u':
  2312  				for j := 0; j < 4; j++ {
  2313  					i++
  2314  					if i >= len(data) {
  2315  						return i, false
  2316  					}
  2317  					if !((data[i] >= '0' && data[i] <= '9') ||
  2318  						(data[i] >= 'a' && data[i] <= 'f') ||
  2319  						(data[i] >= 'A' && data[i] <= 'F')) {
  2320  						return i, false
  2321  					}
  2322  				}
  2323  			}
  2324  		} else if data[i] == '"' {
  2325  			return i + 1, true
  2326  		}
  2327  	}
  2328  	return i, false
  2329  }
  2330  func validnumber(data []byte, i int) (outi int, ok bool) {
  2331  	i--
  2332  	// sign
  2333  	if data[i] == '-' {
  2334  		i++
  2335  		if i == len(data) {
  2336  			return i, false
  2337  		}
  2338  		if data[i] < '0' || data[i] > '9' {
  2339  			return i, false
  2340  		}
  2341  	}
  2342  	// int
  2343  	if i == len(data) {
  2344  		return i, false
  2345  	}
  2346  	if data[i] == '0' {
  2347  		i++
  2348  	} else {
  2349  		for ; i < len(data); i++ {
  2350  			if data[i] >= '0' && data[i] <= '9' {
  2351  				continue
  2352  			}
  2353  			break
  2354  		}
  2355  	}
  2356  	// frac
  2357  	if i == len(data) {
  2358  		return i, true
  2359  	}
  2360  	if data[i] == '.' {
  2361  		i++
  2362  		if i == len(data) {
  2363  			return i, false
  2364  		}
  2365  		if data[i] < '0' || data[i] > '9' {
  2366  			return i, false
  2367  		}
  2368  		i++
  2369  		for ; i < len(data); i++ {
  2370  			if data[i] >= '0' && data[i] <= '9' {
  2371  				continue
  2372  			}
  2373  			break
  2374  		}
  2375  	}
  2376  	// exp
  2377  	if i == len(data) {
  2378  		return i, true
  2379  	}
  2380  	if data[i] == 'e' || data[i] == 'E' {
  2381  		i++
  2382  		if i == len(data) {
  2383  			return i, false
  2384  		}
  2385  		if data[i] == '+' || data[i] == '-' {
  2386  			i++
  2387  		}
  2388  		if i == len(data) {
  2389  			return i, false
  2390  		}
  2391  		if data[i] < '0' || data[i] > '9' {
  2392  			return i, false
  2393  		}
  2394  		i++
  2395  		for ; i < len(data); i++ {
  2396  			if data[i] >= '0' && data[i] <= '9' {
  2397  				continue
  2398  			}
  2399  			break
  2400  		}
  2401  	}
  2402  	return i, true
  2403  }
  2404  
  2405  func validtrue(data []byte, i int) (outi int, ok bool) {
  2406  	if i+3 <= len(data) && data[i] == 'r' && data[i+1] == 'u' &&
  2407  		data[i+2] == 'e' {
  2408  		return i + 3, true
  2409  	}
  2410  	return i, false
  2411  }
  2412  func validfalse(data []byte, i int) (outi int, ok bool) {
  2413  	if i+4 <= len(data) && data[i] == 'a' && data[i+1] == 'l' &&
  2414  		data[i+2] == 's' && data[i+3] == 'e' {
  2415  		return i + 4, true
  2416  	}
  2417  	return i, false
  2418  }
  2419  func validnull(data []byte, i int) (outi int, ok bool) {
  2420  	if i+3 <= len(data) && data[i] == 'u' && data[i+1] == 'l' &&
  2421  		data[i+2] == 'l' {
  2422  		return i + 3, true
  2423  	}
  2424  	return i, false
  2425  }
  2426  
  2427  // Valid returns true if the input is valid json.
  2428  //
  2429  //	if !gjson.Valid(json) {
  2430  //		return errors.New("invalid json")
  2431  //	}
  2432  //	value := gjson.Get(json, "name.last")
  2433  func Valid(json string) bool {
  2434  	_, ok := validpayload(stringBytes(json), 0)
  2435  	return ok
  2436  }
  2437  
  2438  // ValidBytes returns true if the input is valid json.
  2439  //
  2440  //	if !gjson.Valid(json) {
  2441  //		return errors.New("invalid json")
  2442  //	}
  2443  //	value := gjson.Get(json, "name.last")
  2444  //
  2445  // If working with bytes, this method preferred over ValidBytes(string(data))
  2446  func ValidBytes(json []byte) bool {
  2447  	_, ok := validpayload(json, 0)
  2448  	return ok
  2449  }
  2450  
  2451  func parseUint(s string) (n uint64, ok bool) {
  2452  	var i int
  2453  	if i == len(s) {
  2454  		return 0, false
  2455  	}
  2456  	for ; i < len(s); i++ {
  2457  		if s[i] >= '0' && s[i] <= '9' {
  2458  			n = n*10 + uint64(s[i]-'0')
  2459  		} else {
  2460  			return 0, false
  2461  		}
  2462  	}
  2463  	return n, true
  2464  }
  2465  
  2466  func parseInt(s string) (n int64, ok bool) {
  2467  	var i int
  2468  	var sign bool
  2469  	if len(s) > 0 && s[0] == '-' {
  2470  		sign = true
  2471  		i++
  2472  	}
  2473  	if i == len(s) {
  2474  		return 0, false
  2475  	}
  2476  	for ; i < len(s); i++ {
  2477  		if s[i] >= '0' && s[i] <= '9' {
  2478  			n = n*10 + int64(s[i]-'0')
  2479  		} else {
  2480  			return 0, false
  2481  		}
  2482  	}
  2483  	if sign {
  2484  		return n * -1, true
  2485  	}
  2486  	return n, true
  2487  }
  2488  
  2489  // safeInt validates a given JSON number
  2490  // ensures it lies within the minimum and maximum representable JSON numbers
  2491  func safeInt(f float64) (n int64, ok bool) {
  2492  	// https://tc39.es/ecma262/#sec-number.min_safe_integer
  2493  	// https://tc39.es/ecma262/#sec-number.max_safe_integer
  2494  	if f < -9007199254740991 || f > 9007199254740991 {
  2495  		return 0, false
  2496  	}
  2497  	return int64(f), true
  2498  }
  2499  
  2500  // execModifier parses the path to find a matching modifier function.
  2501  // then input expects that the path already starts with a '@'
  2502  func execModifier(json, path string) (pathOut, res string, ok bool) {
  2503  	name := path[1:]
  2504  	var hasArgs bool
  2505  	for i := 1; i < len(path); i++ {
  2506  		if path[i] == ':' {
  2507  			pathOut = path[i+1:]
  2508  			name = path[1:i]
  2509  			hasArgs = len(pathOut) > 0
  2510  			break
  2511  		}
  2512  		if path[i] == '|' {
  2513  			pathOut = path[i:]
  2514  			name = path[1:i]
  2515  			break
  2516  		}
  2517  		if path[i] == '.' {
  2518  			pathOut = path[i:]
  2519  			name = path[1:i]
  2520  			break
  2521  		}
  2522  	}
  2523  	if fn, ok := modifiers[name]; ok {
  2524  		var args string
  2525  		if hasArgs {
  2526  			var parsedArgs bool
  2527  			switch pathOut[0] {
  2528  			case '{', '[', '"':
  2529  				res := Parse(pathOut)
  2530  				if res.Exists() {
  2531  					args = squash(pathOut)
  2532  					pathOut = pathOut[len(args):]
  2533  					parsedArgs = true
  2534  				}
  2535  			}
  2536  			if !parsedArgs {
  2537  				idx := strings.IndexByte(pathOut, '|')
  2538  				if idx == -1 {
  2539  					args = pathOut
  2540  					pathOut = ""
  2541  				} else {
  2542  					args = pathOut[:idx]
  2543  					pathOut = pathOut[idx:]
  2544  				}
  2545  			}
  2546  		}
  2547  		return pathOut, fn(json, args), true
  2548  	}
  2549  	return pathOut, res, false
  2550  }
  2551  
  2552  // unwrap removes the '[]' or '{}' characters around json
  2553  func unwrap(json string) string {
  2554  	json = trim(json)
  2555  	if len(json) >= 2 && (json[0] == '[' || json[0] == '{') {
  2556  		json = json[1 : len(json)-1]
  2557  	}
  2558  	return json
  2559  }
  2560  
  2561  // DisableModifiers will disable the modifier syntax
  2562  var DisableModifiers = false
  2563  
  2564  var modifiers = map[string]func(json, arg string) string{
  2565  	"pretty":  modPretty,
  2566  	"ugly":    modUgly,
  2567  	"reverse": modReverse,
  2568  	"this":    modThis,
  2569  	"flatten": modFlatten,
  2570  	"join":    modJoin,
  2571  	"valid":   modValid,
  2572  }
  2573  
  2574  // AddModifier binds a custom modifier command to the GJSON syntax.
  2575  // This operation is not thread safe and should be executed prior to
  2576  // using all other gjson function.
  2577  func AddModifier(name string, fn func(json, arg string) string) {
  2578  	modifiers[name] = fn
  2579  }
  2580  
  2581  // ModifierExists returns true when the specified modifier exists.
  2582  func ModifierExists(name string, fn func(json, arg string) string) bool {
  2583  	_, ok := modifiers[name]
  2584  	return ok
  2585  }
  2586  
  2587  // cleanWS remove any non-whitespace from string
  2588  func cleanWS(s string) string {
  2589  	for i := 0; i < len(s); i++ {
  2590  		switch s[i] {
  2591  		case ' ', '\t', '\n', '\r':
  2592  			continue
  2593  		default:
  2594  			var s2 []byte
  2595  			for i := 0; i < len(s); i++ {
  2596  				switch s[i] {
  2597  				case ' ', '\t', '\n', '\r':
  2598  					s2 = append(s2, s[i])
  2599  				}
  2600  			}
  2601  			return string(s2)
  2602  		}
  2603  	}
  2604  	return s
  2605  }
  2606  
  2607  // @pretty modifier makes the json look nice.
  2608  func modPretty(json, arg string) string {
  2609  	if len(arg) > 0 {
  2610  		opts := *pretty.DefaultOptions
  2611  		Parse(arg).ForEach(func(key, value Result) bool {
  2612  			switch key.String() {
  2613  			case "sortKeys":
  2614  				opts.SortKeys = value.Bool()
  2615  			case "indent":
  2616  				opts.Indent = cleanWS(value.String())
  2617  			case "prefix":
  2618  				opts.Prefix = cleanWS(value.String())
  2619  			case "width":
  2620  				opts.Width = int(value.Int())
  2621  			}
  2622  			return true
  2623  		})
  2624  		return bytesString(pretty.PrettyOptions(stringBytes(json), &opts))
  2625  	}
  2626  	return bytesString(pretty.Pretty(stringBytes(json)))
  2627  }
  2628  
  2629  // @this returns the current element. Can be used to retrieve the root element.
  2630  func modThis(json, arg string) string {
  2631  	return json
  2632  }
  2633  
  2634  // @ugly modifier removes all whitespace.
  2635  func modUgly(json, arg string) string {
  2636  	return bytesString(pretty.Ugly(stringBytes(json)))
  2637  }
  2638  
  2639  // @reverse reverses array elements or root object members.
  2640  func modReverse(json, arg string) string {
  2641  	res := Parse(json)
  2642  	if res.IsArray() {
  2643  		var values []Result
  2644  		res.ForEach(func(_, value Result) bool {
  2645  			values = append(values, value)
  2646  			return true
  2647  		})
  2648  		out := make([]byte, 0, len(json))
  2649  		out = append(out, '[')
  2650  		for i, j := len(values)-1, 0; i >= 0; i, j = i-1, j+1 {
  2651  			if j > 0 {
  2652  				out = append(out, ',')
  2653  			}
  2654  			out = append(out, values[i].Raw...)
  2655  		}
  2656  		out = append(out, ']')
  2657  		return bytesString(out)
  2658  	}
  2659  	if res.IsObject() {
  2660  		var keyValues []Result
  2661  		res.ForEach(func(key, value Result) bool {
  2662  			keyValues = append(keyValues, key, value)
  2663  			return true
  2664  		})
  2665  		out := make([]byte, 0, len(json))
  2666  		out = append(out, '{')
  2667  		for i, j := len(keyValues)-2, 0; i >= 0; i, j = i-2, j+1 {
  2668  			if j > 0 {
  2669  				out = append(out, ',')
  2670  			}
  2671  			out = append(out, keyValues[i+0].Raw...)
  2672  			out = append(out, ':')
  2673  			out = append(out, keyValues[i+1].Raw...)
  2674  		}
  2675  		out = append(out, '}')
  2676  		return bytesString(out)
  2677  	}
  2678  	return json
  2679  }
  2680  
  2681  // @flatten an array with child arrays.
  2682  //
  2683  //	[1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]]
  2684  //
  2685  // The {"deep":true} arg can be provide for deep flattening.
  2686  //
  2687  //	[1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7]
  2688  //
  2689  // The original json is returned when the json is not an array.
  2690  func modFlatten(json, arg string) string {
  2691  	res := Parse(json)
  2692  	if !res.IsArray() {
  2693  		return json
  2694  	}
  2695  	var deep bool
  2696  	if arg != "" {
  2697  		Parse(arg).ForEach(func(key, value Result) bool {
  2698  			if key.String() == "deep" {
  2699  				deep = value.Bool()
  2700  			}
  2701  			return true
  2702  		})
  2703  	}
  2704  	var out []byte
  2705  	out = append(out, '[')
  2706  	var idx int
  2707  	res.ForEach(func(_, value Result) bool {
  2708  		var raw string
  2709  		if value.IsArray() {
  2710  			if deep {
  2711  				raw = unwrap(modFlatten(value.Raw, arg))
  2712  			} else {
  2713  				raw = unwrap(value.Raw)
  2714  			}
  2715  		} else {
  2716  			raw = value.Raw
  2717  		}
  2718  		raw = strings.TrimSpace(raw)
  2719  		if len(raw) > 0 {
  2720  			if idx > 0 {
  2721  				out = append(out, ',')
  2722  			}
  2723  			out = append(out, raw...)
  2724  			idx++
  2725  		}
  2726  		return true
  2727  	})
  2728  	out = append(out, ']')
  2729  	return bytesString(out)
  2730  }
  2731  
  2732  // @join multiple objects into a single object.
  2733  //
  2734  //	[{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"}
  2735  //
  2736  // The arg can be "true" to specify that duplicate keys should be preserved.
  2737  //
  2738  //	[{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41}
  2739  //
  2740  // Without preserved keys:
  2741  //
  2742  //	[{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41}
  2743  //
  2744  // The original json is returned when the json is not an object.
  2745  func modJoin(json, arg string) string {
  2746  	res := Parse(json)
  2747  	if !res.IsArray() {
  2748  		return json
  2749  	}
  2750  	var preserve bool
  2751  	if arg != "" {
  2752  		Parse(arg).ForEach(func(key, value Result) bool {
  2753  			if key.String() == "preserve" {
  2754  				preserve = value.Bool()
  2755  			}
  2756  			return true
  2757  		})
  2758  	}
  2759  	var out []byte
  2760  	out = append(out, '{')
  2761  	if preserve {
  2762  		// Preserve duplicate keys.
  2763  		var idx int
  2764  		res.ForEach(func(_, value Result) bool {
  2765  			if !value.IsObject() {
  2766  				return true
  2767  			}
  2768  			if idx > 0 {
  2769  				out = append(out, ',')
  2770  			}
  2771  			out = append(out, unwrap(value.Raw)...)
  2772  			idx++
  2773  			return true
  2774  		})
  2775  	} else {
  2776  		// Deduplicate keys and generate an object with stable ordering.
  2777  		var keys []Result
  2778  		kvals := make(map[string]Result)
  2779  		res.ForEach(func(_, value Result) bool {
  2780  			if !value.IsObject() {
  2781  				return true
  2782  			}
  2783  			value.ForEach(func(key, value Result) bool {
  2784  				k := key.String()
  2785  				if _, ok := kvals[k]; !ok {
  2786  					keys = append(keys, key)
  2787  				}
  2788  				kvals[k] = value
  2789  				return true
  2790  			})
  2791  			return true
  2792  		})
  2793  		for i := 0; i < len(keys); i++ {
  2794  			if i > 0 {
  2795  				out = append(out, ',')
  2796  			}
  2797  			out = append(out, keys[i].Raw...)
  2798  			out = append(out, ':')
  2799  			out = append(out, kvals[keys[i].String()].Raw...)
  2800  		}
  2801  	}
  2802  	out = append(out, '}')
  2803  	return bytesString(out)
  2804  }
  2805  
  2806  // @valid ensures that the json is valid before moving on. An empty string is
  2807  // returned when the json is not valid, otherwise it returns the original json.
  2808  func modValid(json, arg string) string {
  2809  	if !Valid(json) {
  2810  		return ""
  2811  	}
  2812  	return json
  2813  }
  2814  
  2815  // stringHeader instead of reflect.StringHeader
  2816  type stringHeader struct {
  2817  	data unsafe.Pointer
  2818  	len  int
  2819  }
  2820  
  2821  // sliceHeader instead of reflect.SliceHeader
  2822  type sliceHeader struct {
  2823  	data unsafe.Pointer
  2824  	len  int
  2825  	cap  int
  2826  }
  2827  
  2828  // getBytes casts the input json bytes to a string and safely returns the
  2829  // results as uniquely allocated data. This operation is intended to minimize
  2830  // copies and allocations for the large json string->[]byte.
  2831  func getBytes(json []byte, path string) Result {
  2832  	var result Result
  2833  	if json != nil {
  2834  		// unsafe cast to string
  2835  		result = Get(*(*string)(unsafe.Pointer(&json)), path)
  2836  		// safely get the string headers
  2837  		rawhi := *(*stringHeader)(unsafe.Pointer(&result.Raw))
  2838  		strhi := *(*stringHeader)(unsafe.Pointer(&result.Str))
  2839  		// create byte slice headers
  2840  		rawh := sliceHeader{data: rawhi.data, len: rawhi.len, cap: rawhi.len}
  2841  		strh := sliceHeader{data: strhi.data, len: strhi.len, cap: rawhi.len}
  2842  		if strh.data == nil {
  2843  			// str is nil
  2844  			if rawh.data == nil {
  2845  				// raw is nil
  2846  				result.Raw = ""
  2847  			} else {
  2848  				// raw has data, safely copy the slice header to a string
  2849  				result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh)))
  2850  			}
  2851  			result.Str = ""
  2852  		} else if rawh.data == nil {
  2853  			// raw is nil
  2854  			result.Raw = ""
  2855  			// str has data, safely copy the slice header to a string
  2856  			result.Str = string(*(*[]byte)(unsafe.Pointer(&strh)))
  2857  		} else if uintptr(strh.data) >= uintptr(rawh.data) &&
  2858  			uintptr(strh.data)+uintptr(strh.len) <=
  2859  				uintptr(rawh.data)+uintptr(rawh.len) {
  2860  			// Str is a substring of Raw.
  2861  			start := uintptr(strh.data) - uintptr(rawh.data)
  2862  			// safely copy the raw slice header
  2863  			result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh)))
  2864  			// substring the raw
  2865  			result.Str = result.Raw[start : start+uintptr(strh.len)]
  2866  		} else {
  2867  			// safely copy both the raw and str slice headers to strings
  2868  			result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh)))
  2869  			result.Str = string(*(*[]byte)(unsafe.Pointer(&strh)))
  2870  		}
  2871  	}
  2872  	return result
  2873  }
  2874  
  2875  // fillIndex finds the position of Raw data and assigns it to the Index field
  2876  // of the resulting value. If the position cannot be found then Index zero is
  2877  // used instead.
  2878  func fillIndex(json string, c *parseContext) {
  2879  	if len(c.value.Raw) > 0 && !c.calcd {
  2880  		jhdr := *(*stringHeader)(unsafe.Pointer(&json))
  2881  		rhdr := *(*stringHeader)(unsafe.Pointer(&(c.value.Raw)))
  2882  		c.value.Index = int(uintptr(rhdr.data) - uintptr(jhdr.data))
  2883  		if c.value.Index < 0 || c.value.Index >= len(json) {
  2884  			c.value.Index = 0
  2885  		}
  2886  	}
  2887  }
  2888  
  2889  func stringBytes(s string) []byte {
  2890  	return *(*[]byte)(unsafe.Pointer(&sliceHeader{
  2891  		data: (*stringHeader)(unsafe.Pointer(&s)).data,
  2892  		len:  len(s),
  2893  		cap:  len(s),
  2894  	}))
  2895  }
  2896  
  2897  func bytesString(b []byte) string {
  2898  	return *(*string)(unsafe.Pointer(&b))
  2899  }