diff --git a/messageparser.go b/messageparser.go index c757a70..7073860 100644 --- a/messageparser.go +++ b/messageparser.go @@ -197,7 +197,7 @@ func ParseMessage(buf []byte) (Message, *Delimiters, error) { } func unescape(b []byte, d *Delimiters) []byte { - r := make([]byte, len(b)) + r := make([]byte, len(b)+1) // +1 to make room for possible unpaired escape character j, e := 0, false for i := 0; i < len(b); i++ { @@ -225,6 +225,13 @@ func unescape(b []byte, d *Delimiters) []byte { r[j] = d.Escape j++ r[j] = c + j++ + i++ + for ; i < len(b) && b[i] != d.Escape; i++ { + r[j] = b[i] + j++ + } + r[j] = d.Escape } j++ diff --git a/messageparser_test.go b/messageparser_test.go index ec3bdc3..7fd8992 100644 --- a/messageparser_test.go +++ b/messageparser_test.go @@ -287,7 +287,7 @@ func TestParseSimpleContent(t *testing.T) { Field{FieldItem{Component{"^~\\&"}}}, Field{FieldItem{Component{"field"}}}, Field{FieldItem{ - Component{"\\|~^&\\X484559"}, + Component{"\\|~^&\\X484559\\"}, }}, Field{FieldItem{ Component{"component1"}, @@ -321,6 +321,40 @@ func TestParseLiteralNewline(t *testing.T) { }, m) } +func TestParseHexEscapes(t *testing.T) { + a := assert.New(t) + + m, d, err := ParseMessage([]byte(`MSH|^~\&|Foo\X41\|Bar\X42\Fred`)) + a.NoError(err) + a.Equal(&Delimiters{'|', '^', '~', '\\', '&'}, d) + a.Equal(Message{ + Segment{ + Field{FieldItem{Component{`MSH`}}}, + Field{FieldItem{Component{`|`}}}, + Field{FieldItem{Component{`^~\&`}}}, + Field{FieldItem{Component{`Foo\X41\`}}}, + Field{FieldItem{Component{`Bar\X42\Fred`}}}, + }, + }, m) +} + +func TestParseUnpairedInvalidHexEscapes(t *testing.T) { + a := assert.New(t) + + m, d, err := ParseMessage([]byte(`MSH|^~\&|Foo\X41|Bar\X42\Fred`)) + a.NoError(err) + a.Equal(&Delimiters{'|', '^', '~', '\\', '&'}, d) + a.Equal(Message{ + Segment{ + Field{FieldItem{Component{`MSH`}}}, + Field{FieldItem{Component{`|`}}}, + Field{FieldItem{Component{`^~\&`}}}, + Field{FieldItem{Component{`Foo\X41\`}}}, + Field{FieldItem{Component{`Bar\X42\Fred`}}}, + }, + }, m) +} + func TestParseBad(t *testing.T) { a := assert.New(t)