Skip to content

Commit

Permalink
remove some usage of unsafe
Browse files Browse the repository at this point in the history
  • Loading branch information
trim21 committed Jul 15, 2024
1 parent da2a1f7 commit 5d12f8a
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 30 deletions.
2 changes: 1 addition & 1 deletion api.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !go1.24
//go:build !1.23rc2

package phpserialize

Expand Down
2 changes: 1 addition & 1 deletion internal/decoder/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func init() {
}

func char(ptr unsafe.Pointer, offset int64) byte {
return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset)))
return *(*byte)(unsafe.Add(ptr, offset))
}

// `:${length}:`
Expand Down
6 changes: 0 additions & 6 deletions internal/encoder/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,29 @@ package encoder

import (
"sync"
"unsafe"
)

var ctxPool = sync.Pool{
New: func() any {
return &Ctx{
Buf: make([]byte, 0, 1024),
KeepRefs: make([]unsafe.Pointer, 0, 8),
smallBuffer: make([]byte, 0, 20),
}
},
}

type Ctx struct {
smallBuffer []byte // a small buffer to encode float and time.Time as string
KeepRefs []unsafe.Pointer
Buf []byte
}

func newCtx() *Ctx {
ctx := ctxPool.Get().(*Ctx)
ctx.KeepRefs = ctx.KeepRefs[:0]
ctx.smallBuffer = ctx.smallBuffer[:0]

return ctx
}

func freeCtx(ctx *Ctx) {
ctx.KeepRefs = ctx.KeepRefs[:0]

ctxPool.Put(ctx)
}
7 changes: 1 addition & 6 deletions internal/encoder/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ LOOP:
}
}

value := rv.Interface()

v := *(*emptyInterface)(unsafe.Pointer(&value))
pp := uintptr(v.ptr)

// simple type
switch rv.Type().Kind() {
case reflect.Bool:
Expand All @@ -55,7 +50,7 @@ LOOP:
case reflect.Map:
return reflectMap(ctx, b, rv)
case reflect.Struct:
return reflectStruct(ctx, b, rv, pp)
return reflectStruct(ctx, b, rv)
}

return b, &UnsupportedInterfaceTypeError{rv.Type()}
Expand Down
2 changes: 1 addition & 1 deletion internal/encoder/struct_reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"reflect"
)

func reflectStruct(ctx *Ctx, b []byte, rv reflect.Value, p uintptr) ([]byte, error) {
func reflectStruct(ctx *Ctx, b []byte, rv reflect.Value) ([]byte, error) {
enc, err := compileWithCache(rv.Type())
if err != nil {
return nil, err
Expand Down
30 changes: 15 additions & 15 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,19 @@ Support All go type including `map`, `slice`, `struct`, `array`, and simple type
Encoding some type from standard library like `time.Time`, `net.IP` are not supported.
If you have any thought about how to support these types, please create an issue.

## supported and tested go version
## Supported and tested go version

- 1.20
- 1.21
- 1.22
- 1.23rc2

You may see compile error about `golang_version_higher_than_*_not_supported_yet is undefined`,
please try to upgrade version of this package.
This repo have `//go:build ...` to disallow downstream users compiling this package on newer version of go.

If you are using the latest version of this package, this is expected.
This is because the usage of unsafe package, and unsafe doesn't follow Go 1 promise of compatibility,
so new version of golang may break this package.

Due to the usage of unsafe (unsafe doesn't follow Go 1 promise of compatibility),
new version of golang may break this package,
so it use go build flags to make sure it only compile on tested go versions.

## Use case:

You serialize all data into php array only.

Decoding from php serialized array or class are both supported.
When a new version of go is released, I will test on new go version and create a new release.

## Install

Expand All @@ -47,10 +40,17 @@ So we didn't a major refactoring in v0.1.0 (not released yet).
For simplicity, support for embed struct has been removed,
if you need this feature, consider send a Pull Request.

### Marshal

Struct and map will be encoded to php array only.

### Unmarshal
`any` type will be decoded to `map[any]any` or `map[string]any`, depends on raw input is `array` or `class`,

map `any` key maybe `int64` or `string`.
Decoding from php serialized array, class and object are both supported.

go `any` type will be decoded as `map[any]any` or `map[string]any`, based on raw input is `array` or `class`,

keys of `map[any]any` maybe `int64` or `string`.

## Security

Expand Down

0 comments on commit 5d12f8a

Please sign in to comment.