Skip to content

Bug:包含空格的参数值在加解密后会被错误拆分,导致参数个数/内容丢失 #15

Description

@12end1

问题描述

cargs.Init 在加解密参数时,使用 strings.Join(args, " ")strings.Split(output, " ") 来拼接 / 拆分参数。当某个参数值内部包含空格时,加密再解密后,该参数会被错误地拆成多个参数,参数个数和内容都无法还原。

复现步骤

  1. 使用 cargs 编译一个简单的程序:
package main

import (
    "fmt"
    "os"
    "github.com/12end/cargs"
)

func main() {
    cargs.Init([]byte("cargsRandomKey"), "getarg")
    fmt.Printf("args = %#v\n", os.Args[1:])
}
go build -tags cargs
  1. 生成加密参数,传入一个带空格的值:
./main getarg --name "hello world"
# 输出: cargs output: <base64>
  1. 用该加密参数运行:
./main <base64>

期望行为

程序看到的参数应为:

args = []string{"--name", "hello world"}

即与加密前完全一致,hello world 是一个完整的参数值。

实际行为

程序看到的参数变成了:

args = []string{"--name", "hello", "world"}

hello world 被拆成了两个独立参数,原本的参数语义被破坏(--name 只取到 hello,多出一个未知的 world)。

原因分析

cargs.go 中:

// 加密分支
input := []byte(strings.Join(os.Args[2:], " "))   // 用空格把多个参数拼成一个字符串

// 解密分支
os.Args = append(os.Args[:1], strings.Split(string(output), " ")...)  // 再用空格切回去

Join 时无法区分「参数之间的分隔空格」和「参数值内部的空格」,Split 时一律按空格切开,因此参数值内部的空格会被当作参数分隔符。同理,连续空格也会产生空字符串参数(strings.Split("a b", " ")["a", "", "b"])。

建议修复方向

不要用单一分隔符 join/split 来序列化参数切片,可采用任一可逆的编码方式,例如:

  • 对每个参数单独 base64 编码后再用空格连接,解密后再逐个 base64 解码;
  • 或用 encoding/gob / encoding/json 序列化整个 []string
  • 或使用一个不可能出现在 base64 输出里的分隔符(如换行符 \n)逐项拼接,并保留个数信息。

环境

  • OS:macOS(其他平台应同样复现)
  • Go 版本:go 1.21
  • cargs 版本:master(最新)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions