2024-09-24 16:11:08 +09:00
|
|
|
package helper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
ErrContainsNull = errors.New("argument contains null character")
|
|
|
|
)
|
|
|
|
|
2024-10-07 12:48:20 +09:00
|
|
|
type argsWt []string
|
2024-09-24 16:11:08 +09:00
|
|
|
|
2024-09-25 14:00:30 +09:00
|
|
|
// checks whether any element contains the null character
|
|
|
|
// must be called before args use and args must not be modified after call
|
2024-10-07 12:48:20 +09:00
|
|
|
func (a argsWt) check() error {
|
2024-09-25 14:00:30 +09:00
|
|
|
for _, arg := range a {
|
|
|
|
for _, b := range arg {
|
|
|
|
if b == '\x00' {
|
|
|
|
return ErrContainsNull
|
|
|
|
}
|
2024-09-24 16:11:08 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-10-07 12:48:20 +09:00
|
|
|
func (a argsWt) WriteTo(w io.Writer) (int64, error) {
|
2024-09-25 14:00:30 +09:00
|
|
|
// assuming already checked
|
|
|
|
|
|
|
|
nt := 0
|
|
|
|
// write null terminated arguments
|
|
|
|
for _, arg := range a {
|
|
|
|
n, err := w.Write([]byte(arg + "\x00"))
|
|
|
|
nt += n
|
2024-09-24 20:22:37 +09:00
|
|
|
|
2024-09-25 14:00:30 +09:00
|
|
|
if err != nil {
|
|
|
|
return int64(nt), err
|
|
|
|
}
|
2024-09-24 16:11:08 +09:00
|
|
|
}
|
|
|
|
|
2024-09-25 14:00:30 +09:00
|
|
|
return int64(nt), nil
|
2024-09-24 16:11:08 +09:00
|
|
|
}
|
|
|
|
|
2024-10-07 12:48:20 +09:00
|
|
|
func (a argsWt) String() string {
|
2024-09-25 14:00:30 +09:00
|
|
|
return strings.Join(a, " ")
|
2024-09-24 16:11:08 +09:00
|
|
|
}
|
|
|
|
|
2024-09-25 14:00:30 +09:00
|
|
|
// NewCheckedArgs returns a checked argument writer for args.
|
|
|
|
// Callers must not retain any references to args.
|
|
|
|
func NewCheckedArgs(args []string) (io.WriterTo, error) {
|
2024-10-07 12:48:20 +09:00
|
|
|
a := argsWt(args)
|
2024-09-25 14:00:30 +09:00
|
|
|
return a, a.check()
|
2024-09-24 16:11:08 +09:00
|
|
|
}
|