aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource/csource.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-12-17 10:55:35 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-12-17 11:39:14 +0100
commitd5beb42acec986ef99739a4187ce8dd9513972cc (patch)
tree8618c6731c6b7ddf6a32d5e33c7ded885144106c /pkg/csource/csource.go
parent1db7a350a96490fac76da6fd384ba3d79a0d69b7 (diff)
pkg/csource: make strings more readable
If string contains a file name or a crypto alg name, don't escape it all to hex.
Diffstat (limited to 'pkg/csource/csource.go')
-rw-r--r--pkg/csource/csource.go67
1 files changed, 56 insertions, 11 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index 05b3b34e3..622b66f49 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -282,18 +282,8 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) {
fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = %v);\n",
arg.Size*8, copyin.Addr, resultRef(arg))
case prog.ExecArgData:
- var esc []byte
- for _, v := range arg.Data {
- hex := func(v byte) byte {
- if v < 10 {
- return '0' + v
- }
- return 'a' + v - 10
- }
- esc = append(esc, '\\', 'x', hex(v>>4), hex(v<<4>>4))
- }
fmt.Fprintf(w, "\tNONFAILING(memcpy((void*)0x%x, \"%s\", %v));\n",
- copyin.Addr, esc, len(arg.Data))
+ copyin.Addr, toCString(arg.Data), len(arg.Data))
case prog.ExecArgCsum:
switch arg.Kind {
case prog.ExecArgCsumInet:
@@ -388,3 +378,58 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) {
}
return calls, p.NumVars
}
+
+func toCString(data []byte) []byte {
+ if len(data) == 0 {
+ return nil
+ }
+ readable := true
+ for i, v := range data {
+ // Allow 0 only as last byte.
+ if !isReadable(v) && (i != len(data)-1 || v != 0) {
+ readable = false
+ break
+ }
+ }
+ if !readable {
+ buf := new(bytes.Buffer)
+ for _, v := range data {
+ buf.Write([]byte{'\\', 'x', toHex(v >> 4), toHex(v << 4 >> 4)})
+ }
+ return buf.Bytes()
+ }
+ if data[len(data)-1] == 0 {
+ // Don't serialize last 0, C strings are 0-terminated anyway.
+ data = data[:len(data)-1]
+ }
+ buf := new(bytes.Buffer)
+ for _, v := range data {
+ switch v {
+ case '\t':
+ buf.Write([]byte{'\\', 't'})
+ case '\r':
+ buf.Write([]byte{'\\', 'r'})
+ case '\n':
+ buf.Write([]byte{'\\', 'n'})
+ case '\\':
+ buf.Write([]byte{'\\', '\\'})
+ default:
+ if v < 0x20 || v >= 0x7f {
+ panic("unexpected char during data serialization")
+ }
+ buf.WriteByte(v)
+ }
+ }
+ return buf.Bytes()
+}
+
+func isReadable(v byte) bool {
+ return v >= 0x20 && v < 0x7f || v == '\t' || v == '\r' || v == '\n'
+}
+
+func toHex(v byte) byte {
+ if v < 10 {
+ return '0' + v
+ }
+ return 'a' + v - 10
+}