Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions cargs.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ func Init(key []byte, flag string) {
fmt.Println("error: empty flag!")
os.Exit(1)
}
var newArgs []string
newArgs = append(newArgs, os.Args[0])
if len(os.Args) > 2 && os.Args[1] == flag {
// encode args
input := []byte(strings.Join(os.Args[2:], " "))
// encode args: base64 each arg, then join with newline
var encodedArgs []string
for _, arg := range os.Args[2:] {
encodedArgs = append(encodedArgs, base64.StdEncoding.EncodeToString([]byte(arg)))
}
input := []byte(strings.Join(encodedArgs, "\n"))
output := make([]byte, len(input))
salsa20.XORKeyStream(output, input, nonce, &key32)
fmt.Printf("cargs output: %s\n", base64.StdEncoding.EncodeToString(output))
Expand All @@ -42,7 +44,16 @@ func Init(key []byte, flag string) {
}
output := make([]byte, len(input))
salsa20.XORKeyStream(output, input, nonce, &key32)
os.Args = append(os.Args[:1], strings.Split(string(output), " ")...)
encodedArgs := strings.Split(string(output), "\n")
var decodedArgs []string
for _, enc := range encodedArgs {
decoded, err := base64.StdEncoding.DecodeString(enc)
if err != nil {
os.Exit(1)
}
decodedArgs = append(decodedArgs, string(decoded))
}
os.Args = append(os.Args[:1], decodedArgs...)
} else {
os.Exit(0)
}
Expand Down
78 changes: 78 additions & 0 deletions cargs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// +build cargs

package cargs

import (
"fmt"
"os"
"os/exec"
"testing"
)

// TestArgsWithSpaces verifies that arguments containing spaces survive the
// encrypt/decrypt round-trip without being split into multiple arguments.
func TestArgsWithSpaces(t *testing.T) {
// Build the test helper
testBin := "./cargs_test_helper"
cmd := exec.Command("go", "build", "-tags", "cargs", "-o", testBin, "./testdata/helper")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("build test helper: %v\n%s", err, out)
}
defer os.Remove(testBin)

// Step 1: encrypt an argument with a space in it
encOut, err := exec.Command(testBin, "getarg", "--name", "hello world").CombinedOutput()
if err != nil {
t.Fatalf("encrypt: %v\n%s", err, encOut)
}
// Extract the base64-encoded ciphertext from stdout
var ciphertext string
_, err = fmt.Sscanf(string(encOut), "cargs output: %s\n", &ciphertext)
if err != nil {
t.Fatalf("parse encrypted output: %v\n%s", err, encOut)
}
if ciphertext == "" {
t.Fatal("empty ciphertext")
}

// Step 2: decrypt and check that the arg with space is preserved
decOut, err := exec.Command(testBin, ciphertext).CombinedOutput()
if err != nil {
t.Fatalf("decrypt: %v\n%s", err, decOut)
}
expected := "args = []string{\"--name\", \"hello world\"}\n"
if string(decOut) != expected {
t.Errorf("unexpected args after decrypt:\n got: %q\n want: %q", string(decOut), expected)
}
}

// TestArgsWithConsecutiveSpaces verifies that arguments with multiple
// consecutive spaces are handled correctly.
func TestArgsWithConsecutiveSpaces(t *testing.T) {
testBin := "./cargs_test_helper"
cmd := exec.Command("go", "build", "-tags", "cargs", "-o", testBin, "./testdata/helper")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("build test helper: %v\n%s", err, out)
}
defer os.Remove(testBin)

// Encrypt
encOut, err := exec.Command(testBin, "getarg", "a", "b c", "d").CombinedOutput()
if err != nil {
t.Fatalf("encrypt: %v\n%s", err, encOut)
}
var ciphertext string
fmt.Sscanf(string(encOut), "cargs output: %s\n", &ciphertext)

// Decrypt
decOut, err := exec.Command(testBin, ciphertext).CombinedOutput()
if err != nil {
t.Fatalf("decrypt: %v\n%s", err, decOut)
}
expected := "args = []string{\"a\", \"b c\", \"d\"}\n"
if string(decOut) != expected {
t.Errorf("unexpected args after decrypt:\n got: %q\n want: %q", string(decOut), expected)
}
}
13 changes: 13 additions & 0 deletions testdata/helper/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

import (
"fmt"
"os"

"github.com/12end/cargs"
)

func main() {
cargs.Init([]byte("cargsRandomKey"), "getarg")
fmt.Printf("args = %#v\n", os.Args[1:])
}