Repository: FluuxIO/go-xmpp (go)

Issue:
Problem with unescaped character %
I have a little bot which was sending me a message `https://da.wikipedia.org/wiki/J%C3%A6vnd%C3%B8gn 🔭` as `https://da.wikipedia.org/wiki/J%!C(MISSING)3%!A(MISSING)6vnd%!C(MISSING)3%!B(MISSING)8gn`.

@SamWhited figured out that it probably happens due to fprintf in the library which considered % a control character. I fixed this quick and dirty by replacing % by %% before sending but you should consider to properly escape messages before using fprintf.

But even with that little workaround there is still a problem as `Septemberjævndøgn ⌘ https://da.wikipedia.org/wiki/J%C3%A6vnd%C3%B8gn 🔭` turns to `Septemberjvndgn  https://da.wikipedia.org/wiki/J%C3%A6vnd%C3%B8gn`. 

Pull request:
Fixes issue with unescaped character %
Fixes #113

Patch:
diff --git a/_examples/go.sum b/_examples/go.sum
index be0c5ab..19ff04d 100644
--- a/_examples/go.sum
+++ b/_examples/go.sum
@@ -4,3 +4,4 @@ github.com/processone/soundcloud v1.0.0/go.mod h1:kDLeWpkRtN3C8kIReQdxoiRi92P9xR
 golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/client.go b/client.go
index 58d0da1..6275920 100644
--- a/client.go
+++ b/client.go
@@ -4,6 +4,7 @@ import (
 	"encoding/xml"
 	"errors"
 	"fmt"
+	"io"
 	"net"
 	"time"
 
@@ -211,7 +212,7 @@ func (c *Client) Send(packet stanza.Packet) error {
 		return errors.New("cannot marshal packet " + err.Error())
 	}
 
-	return c.sendWithLogger(string(data))
+	return c.sendWithWriter(c.Session.streamLogger, data)
 }
 
 // SendRaw sends an XMPP stanza as a string to the server.
@@ -224,12 +225,12 @@ func (c *Client) SendRaw(packet string) error {
 		return errors.New("client is not connected")
 	}
 
-	return c.sendWithLogger(packet)
+	return c.sendWithWriter(c.Session.streamLogger, []byte(packet))
 }
 
-func (c *Client) sendWithLogger(packet string) error {
+func (c *Client) sendWithWriter(writer io.Writer, packet []byte) error {
 	var err error
-	_, err = fmt.Fprintf(c.Session.streamLogger, packet)
+	_, err = writer.Write(packet)
 	return err
 }
 
diff --git a/cmd/go.sum b/cmd/go.sum
index aeeae9c..5d9460f 100644
--- a/cmd/go.sum
+++ b/cmd/go.sum
@@ -143,6 +143,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
diff --git a/go.mod b/go.mod
index 58297e4..1881899 100644
--- a/go.mod
+++ b/go.mod
@@ -4,5 +4,5 @@ go 1.12
 
 require (
 	github.com/google/go-cmp v0.3.0
-	golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522
+	golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
 )
diff --git a/go.sum b/go.sum
index 308f9eb..e9f7f23 100644
--- a/go.sum
+++ b/go.sum
@@ -2,3 +2,5 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=


Test patch:
diff --git a/client_internal_test.go b/client_internal_test.go
new file mode 100644
index 0000000..6daef09
--- /dev/null
+++ b/client_internal_test.go
@@ -0,0 +1,19 @@
+package xmpp
+
+import (
+	"bytes"
+	"testing"
+)
+
+func TestClient_Send(t *testing.T) {
+	buffer := bytes.NewBufferString("")
+	client := Client{}
+	data := []byte("https://da.wikipedia.org/wiki/J%C3%A6vnd%C3%B8gn")
+	if err := client.sendWithWriter(buffer, data); err != nil {
+		t.Errorf("Writing failed: %v", err)
+	}
+
+	if buffer.String() != string(data) {
+		t.Errorf("Incorrect value sent to buffer: '%s'", buffer.String())
+	}
+}