Skip to content

Commit 405ebed

Browse files
authored
fix: avoid boundary ptr (#88)
* fxi: avoid boundary ptr * update ci * fix
1 parent d9ccd31 commit 405ebed

File tree

4 files changed

+39
-23
lines changed

4 files changed

+39
-23
lines changed

.github/workflows/push-check-linux-x64.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ jobs:
66
build:
77
strategy:
88
matrix:
9-
go-version: [1.20.x]
10-
runs-on: ubuntu-latest
9+
go-version: [1.23.x]
10+
runs-on: [macos-latest, ubuntu-latest]
1111
steps:
1212
- uses: actions/checkout@v2
1313

internal/json/decode.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ func decodeFalse(src string, pos int) (ret int) {
6464

6565
func decodeString(src string, pos int) (ret int, v string) {
6666
ret, ep := skipString(src, pos)
67+
if ret < 0 {
68+
return ret, ""
69+
}
6770
if ep == -1 {
6871
(*rt.GoString)(unsafe.Pointer(&v)).Ptr = rt.IndexChar(src, pos+1)
6972
(*rt.GoString)(unsafe.Pointer(&v)).Len = ret - pos - 2
@@ -97,18 +100,18 @@ func isDigit(c byte) bool {
97100
return c >= '0' && c <= '9'
98101
}
99102

103+
//go:nocheckptr
100104
func decodeInt64(src string, pos int) (ret int, v int64, err error) {
101-
sp := uintptr(rt.IndexChar(src, pos))
102-
ss := uintptr(sp)
103-
se := uintptr(rt.IndexChar(src, len(src)))
105+
sp := rt.IndexCharUint(src, pos)
106+
se := rt.StrBoundary(src)
104107
if uintptr(sp) >= se {
105108
return -int(types.ERR_EOF), 0, nil
106109
}
107110

108111
if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
109112
sp += 1
110113
}
111-
if sp == se {
114+
if sp >= se {
112115
return -int(types.ERR_EOF), 0, nil
113116
}
114117

@@ -126,7 +129,7 @@ func decodeInt64(src string, pos int) (ret int, v int64, err error) {
126129

127130
var vv string
128131
ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
129-
(*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
132+
(*rt.GoString)(unsafe.Pointer(&vv)).Ptr = rt.IndexChar(src, pos)
130133
(*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
131134

132135
v, err = strconv.ParseInt(vv, 10, 64)
@@ -146,10 +149,10 @@ func isNumberChars(c byte) bool {
146149
return (c >= '0' && c <= '9') || c == '+' || c == '-' || c == 'e' || c == 'E' || c == '.'
147150
}
148151

152+
//go:nocheckptr
149153
func decodeFloat64(src string, pos int) (ret int, v float64, err error) {
150-
sp := uintptr(rt.IndexChar(src, pos))
151-
ss := uintptr(sp)
152-
se := uintptr(rt.IndexChar(src, len(src)))
154+
sp := rt.IndexCharUint(src, pos)
155+
se := rt.StrBoundary(src)
153156
if uintptr(sp) >= se {
154157
return -int(types.ERR_EOF), 0, nil
155158
}
@@ -169,7 +172,7 @@ func decodeFloat64(src string, pos int) (ret int, v float64, err error) {
169172

170173
var vv string
171174
ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
172-
(*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
175+
(*rt.GoString)(unsafe.Pointer(&vv)).Ptr = rt.IndexChar(src, pos)
173176
(*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
174177

175178
v, err = strconv.ParseFloat(vv, 64)
@@ -290,9 +293,10 @@ func DecodeValue(src string, pos int) (ret int, v types.JsonState) {
290293
}
291294
}
292295

296+
//go:nocheckptr
293297
func skipNumber(src string, pos int) (ret int) {
294-
sp := uintptr(rt.IndexChar(src, pos))
295-
se := uintptr(rt.IndexChar(src, len(src)))
298+
sp := rt.IndexCharUint(src, pos)
299+
se := rt.StrBoundary(src)
296300
if uintptr(sp) >= se {
297301
return -int(types.ERR_EOF)
298302
}
@@ -354,13 +358,14 @@ func skipNumber(src string, pos int) (ret int) {
354358
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
355359
}
356360

361+
//go:nocheckptr
357362
func skipString(src string, pos int) (ret int, ep int) {
358363
if pos+1 >= len(src) {
359364
return -int(types.ERR_EOF), -1
360365
}
361366

362-
sp := uintptr(rt.IndexChar(src, pos))
363-
se := uintptr(rt.IndexChar(src, len(src)))
367+
sp := rt.IndexCharUint(src, pos)
368+
se := rt.StrBoundary(src)
364369

365370
if *(*byte)(unsafe.Pointer(sp)) != '"' {
366371
return -int(types.ERR_INVALID_CHAR), -1
@@ -391,13 +396,14 @@ func skipString(src string, pos int) (ret int, ep int) {
391396
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep
392397
}
393398

399+
//go:nocheckptr
394400
func skipPair(src string, pos int, lchar byte, rchar byte) (ret int) {
395401
if pos+1 >= len(src) {
396402
return -int(types.ERR_EOF)
397403
}
398404

399-
sp := uintptr(rt.IndexChar(src, pos))
400-
se := uintptr(rt.IndexChar(src, len(src)))
405+
sp := rt.IndexCharUint(src, pos)
406+
se := rt.StrBoundary(src)
401407

402408
if *(*byte)(unsafe.Pointer(sp)) != lchar {
403409
return -int(types.ERR_INVALID_CHAR)

internal/json/encoding.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@ func EncodeString(buf []byte, val string) []byte {
7070
return buf
7171
}
7272

73-
7473
func EncodeInt64(buf []byte, val int64) []byte {
7574
i64toa(&buf, val)
7675
return buf
7776
}
7877

79-
func EncodeFloat64(buf []byte, val float64) ([]byte) {
78+
func EncodeFloat64(buf []byte, val float64) []byte {
8079
f64toa(&buf, val)
8180
return buf
8281
}
@@ -125,8 +124,8 @@ const _blankCharsMask = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n')
125124

126125
//go:nocheckptr
127126
func SkipBlank(src string, pos int) int {
128-
se := uintptr(rt.IndexChar(src, len(src)))
129-
sp := uintptr(rt.IndexChar(src, pos))
127+
se := rt.StrBoundary(src)
128+
sp := rt.IndexCharUint(src, pos)
130129

131130
for sp < se {
132131
if !IsSpace(*(*byte)(unsafe.Pointer(sp))) {
@@ -138,5 +137,5 @@ func SkipBlank(src string, pos int) int {
138137
return -int(types.ERR_EOF)
139138
}
140139
runtime.KeepAlive(src)
141-
return int(sp - uintptr(rt.IndexChar(src, 0)))
142-
}
140+
return int(sp - rt.IndexCharUint(src, 0))
141+
}

internal/rt/fastmem.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ func IndexChar(src string, index int) unsafe.Pointer {
9393
return unsafe.Pointer(uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index))
9494
}
9595

96+
func IndexCharUint(src string, index int) uintptr {
97+
// if slice.Ptr == nil || slice.Cap == 0 {
98+
// return nil
99+
// }
100+
return uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index)
101+
}
102+
103+
func StrBoundary(src string) uintptr {
104+
return uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(len(src))
105+
}
106+
96107
func GuardSlice(buf *[]byte, n int) {
97108
c := cap(*buf)
98109
l := len(*buf)

0 commit comments

Comments
 (0)