@@ -465,19 +465,43 @@ func (r *StateStore) registerSchemas(ctx context.Context) error {
465
465
return nil
466
466
}
467
467
468
- func (r * StateStore ) getKeyVersion (vals []interface {}) (data string , version * string , err error ) {
469
- seenData := false
470
- seenVersion := false
471
- for i := 0 ; i < len (vals ); i += 2 {
472
- field , _ := strconv .Unquote (fmt .Sprintf ("%q" , vals [i ]))
473
- switch field {
474
- case "data" :
475
- data , _ = strconv .Unquote (fmt .Sprintf ("%q" , vals [i + 1 ]))
476
- seenData = true
477
- case "version" :
478
- versionVal , _ := strconv .Unquote (fmt .Sprintf ("%q" , vals [i + 1 ]))
479
- version = ptr .Of (versionVal )
480
- seenVersion = true
468
+ func (r * StateStore ) getKeyVersion (vals []any ) (data string , version * string , err error ) {
469
+ var seenData , seenVersion bool
470
+
471
+ // step by 2: key, value. we only expect string or byte slice
472
+ for i := 0 ; i + 1 < len (vals ); i += 2 {
473
+ switch key := vals [i ].(type ) {
474
+ case string :
475
+ switch key {
476
+ case "data" :
477
+ if s , ok := toString (vals [i + 1 ]); ok {
478
+ data = s
479
+ seenData = true
480
+ }
481
+ case "version" :
482
+ if s , ok := toString (vals [i + 1 ]); ok {
483
+ version = & s
484
+ seenVersion = true
485
+ }
486
+ }
487
+ case []byte :
488
+ switch string (key ) {
489
+ case "data" :
490
+ if s , ok := toString (vals [i + 1 ]); ok {
491
+ data = s
492
+ seenData = true
493
+ }
494
+ case "version" :
495
+ if s , ok := toString (vals [i + 1 ]); ok {
496
+ version = & s
497
+ seenVersion = true
498
+ }
499
+ }
500
+ }
501
+
502
+ // Early exit once both values have been found
503
+ if seenData && seenVersion {
504
+ break
481
505
}
482
506
}
483
507
if ! seenData || ! seenVersion {
@@ -487,6 +511,17 @@ func (r *StateStore) getKeyVersion(vals []interface{}) (data string, version *st
487
511
return data , version , nil
488
512
}
489
513
514
+ func toString (v any ) (string , bool ) {
515
+ switch x := v .(type ) {
516
+ case string :
517
+ return x , true
518
+ case []byte :
519
+ return string (x ), true // some allocation here unless we go to unsafe: return unsafe.String(unsafe.SliceData(x), len(x)), true
520
+ default :
521
+ return "" , false
522
+ }
523
+ }
524
+
490
525
func (r * StateStore ) parseETag (req * state.SetRequest ) (int , error ) {
491
526
if req .Options .Concurrency == state .LastWrite || req .ETag == nil || * req .ETag == "" {
492
527
return 0 , nil
0 commit comments