diff --git a/CHANGELOG.md b/CHANGELOG.md index 31f4f27..1aff5a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG - redis +## v1.5.8 (2026-06-21) +- **安全模式优化**: `checkSafe` 从写命令全量拦截改为仅拦截危险命令(`FLUSHDB`/`FLUSHALL`),常规写操作(HSET/HDEL/SET/DEL 等)在安全模式下不再受限。 +- **Result.Bool() 修复**: 增加 `"OK"` 响应判断(Redis RESP Simple String),解决 SET/SETEX 等命令永远返回 `false` 的问题。 +- **JS Logger 注入修复**: `getDefaultRedisForJS` 改用 `jsmod.Get(ctx, "Logger")` 替代 `ctx.Value("Logger")`,修复 jsmod Context 下 Logger 始终为 nil 导致的 panic。 + ## v1.5.7 (2026-06-21) - **兼容性增强**: 对已废弃的 Redis 命令增加新协议兼容支持。 - `SETEX` → `SET key val EX sec`,`SETNX` → `SET key val NX`,`HMSET` → `HSET`,`GETSET` → `SET key val GET`,`ZREVRANGE` → `ZRANGE ... REV`。 diff --git a/TEST.md b/TEST.md index 54d0b2d..81e35e7 100644 --- a/TEST.md +++ b/TEST.md @@ -17,7 +17,7 @@ - **BenchmarkIDMaker**: ~2,300 ns/op (High-performance sequence generation) ## 🛡️ 鲁棒性防御 (Robustness) -- **安全沙箱拦截**:在 `SafeMode` 下,仅允许 GET/EXISTS/ZRANGE 等读操作命令,自动拦截所有写操作命令并返回错误。 +- **安全沙箱拦截**:在 `SafeMode` 下,拦截危险命令(FLUSHDB/FLUSHALL),常规写操作(HSET/HDEL/SET/DEL 等)可正常执行。 - **JS 错误调用栈**:JS 桥接层改用具名导出并使用 `jsmod.MakeError` 包裹错误(包括 Do 返回的 Result.Error 字段),确保 JS 抛出异常时携带准确的 Go 运行时堆栈。 > Date: 2026-06-21 diff --git a/js_export.go b/js_export.go index 244425e..018f8a7 100644 --- a/js_export.go +++ b/js_export.go @@ -63,29 +63,26 @@ var defaultRedisForJS *jsRedis func getDefaultRedisForJS(ctx context.Context) *jsRedis { if defaultRedisForJS == nil { - defaultRedisForJS = &jsRedis{rd: GetRedis("default", ctx.Value("Logger").(*log.Logger)), ctx: ctx} + var logger *log.Logger + if l := jsmod.Get(ctx, "Logger"); l != nil { + logger = l.(*log.Logger) + } + defaultRedisForJS = &jsRedis{rd: GetRedis("default", logger), ctx: ctx} } return defaultRedisForJS } var errSafeMode = errors.New("redis operation is restricted in safe mode") -// 核心写操作指令集 -var writeCommands = map[string]bool{ - "SET": true, "SETEX": true, "SETNX": true, "MSET": true, "MSETNX": true, - "DEL": true, "EXPIRE": true, "EXPIREAT": true, "PEXPIRE": true, "PEXPIREAT": true, - "HSET": true, "HSETNX": true, "HDEL": true, "HMSET": true, - "LPUSH": true, "RPUSH": true, "LPOP": true, "RPOP": true, "LREM": true, "LTRIM": true, - "SADD": true, "SREM": true, "SPOP": true, "SMOVE": true, - "ZADD": true, "ZREM": true, "ZREMRANGEBYRANK": true, "ZREMRANGEBYSCORE": true, - "PUBLISH": true, "FLUSHDB": true, "FLUSHALL": true, +// 危险指令集,安全模式下禁止执行 +var dangerousCommands = map[string]bool{ + "FLUSHDB": true, + "FLUSHALL": true, } func (jr *jsRedis) checkSafe(cmd string) error { if jsmod.IsSafeMode(jr.ctx) { - cmd = strings.ToUpper(cmd) - if writeCommands[cmd] || !strings.Contains(" GET EXISTS ZRANGE HGET HGETALL SMEMBERS SISMEMBER LINDEX LLEN ", " "+cmd+" ") { - // 严格模式:不在白名单内的或在黑名单内的都禁止 + if dangerousCommands[strings.ToUpper(cmd)] { return errSafeMode } } diff --git a/result.go b/result.go index c6adaa7..3d161f4 100644 --- a/result.go +++ b/result.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "reflect" + "strings" "apigo.cc/go/cast" ) @@ -58,7 +59,11 @@ func (rs *Result) Bytes() []byte { return rs.bytes() } func (rs *Result) Bool() bool { - return cast.Bool(rs.String()) + s := strings.ToLower(rs.String()) + if s == "ok" { + return true + } + return cast.Bool(s) } func (rs *Result) Ints() []int {