fixed the blind conversion of a byte array to a string when the array may not contain a valid and complete utf8 sequence. it should have been treated as a binary blob. conversion is now using base64 encoding
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package hodu
|
package hodu
|
||||||
|
|
||||||
|
import "encoding/base64"
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
import "errors"
|
import "errors"
|
||||||
import "io"
|
import "io"
|
||||||
@@ -94,7 +95,7 @@ func (pty *client_pty_ws) ServeWebsocket(ws *websocket.Conn) (int, error) {
|
|||||||
n, err = out.Read(buf[:])
|
n, err = out.Read(buf[:])
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
var err2 error
|
var err2 error
|
||||||
err2 = send_ws_data_for_xterm(ws, "iov", string(buf[:n]))
|
err2 = send_ws_data_for_xterm(ws, "iov", base64.StdEncoding.EncodeToString(buf[:n]))
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
c.log.Write(pty.Id, LOG_ERROR, "[%s] Failed to send to websocket - %s", req.RemoteAddr, err2.Error())
|
c.log.Write(pty.Id, LOG_ERROR, "[%s] Failed to send to websocket - %s", req.RemoteAddr, err2.Error())
|
||||||
break
|
break
|
||||||
@@ -187,7 +188,14 @@ ws_recv_loop:
|
|||||||
if tty != nil {
|
if tty != nil {
|
||||||
var i int
|
var i int
|
||||||
for i, _ = range ev.Data {
|
for i, _ = range ev.Data {
|
||||||
in.Write([]byte(ev.Data[i]))
|
//in.Write([]byte(ev.Data[i]))
|
||||||
|
var bytes []byte
|
||||||
|
bytes, err = base64.StdEncoding.DecodeString(ev.Data[i])
|
||||||
|
if err != nil {
|
||||||
|
c.log.Write(pty.Id, LOG_WARN, "[%s] Invalid iov data received - %s", req.RemoteAddr, ev.Data[i])
|
||||||
|
} else {
|
||||||
|
in.Write(bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package hodu
|
package hodu
|
||||||
|
|
||||||
|
import "encoding/base64"
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
import "errors"
|
import "errors"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@@ -102,7 +103,7 @@ func (pty *server_pty_ws) ServeWebsocket(ws *websocket.Conn) (int, error) {
|
|||||||
n, err = out.Read(buf[:])
|
n, err = out.Read(buf[:])
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
var err2 error
|
var err2 error
|
||||||
err2 = send_ws_data_for_xterm(ws, "iov", string(buf[:n]))
|
err2 = send_ws_data_for_xterm(ws, "iov", base64.StdEncoding.EncodeToString(buf[:n]))
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
s.log.Write(pty.Id, LOG_ERROR, "[%s] Failed to send to websocket - %s", req.RemoteAddr, err2.Error())
|
s.log.Write(pty.Id, LOG_ERROR, "[%s] Failed to send to websocket - %s", req.RemoteAddr, err2.Error())
|
||||||
break
|
break
|
||||||
@@ -195,7 +196,14 @@ ws_recv_loop:
|
|||||||
if tty != nil {
|
if tty != nil {
|
||||||
var i int
|
var i int
|
||||||
for i, _ = range ev.Data {
|
for i, _ = range ev.Data {
|
||||||
in.Write([]byte(ev.Data[i]))
|
//in.Write([]byte(ev.Data[i]))
|
||||||
|
var bytes []byte
|
||||||
|
bytes, err = base64.StdEncoding.DecodeString(ev.Data[i])
|
||||||
|
if err != nil {
|
||||||
|
s.log.Write(pty.Id, LOG_WARN, "[%s] Invalid pty iov data received - %s", req.RemoteAddr, ev.Data[i])
|
||||||
|
} else {
|
||||||
|
in.Write(bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,9 +318,16 @@ ws_recv_loop:
|
|||||||
case "iov":
|
case "iov":
|
||||||
var i int
|
var i int
|
||||||
for i, _ = range ev.Data {
|
for i, _ = range ev.Data {
|
||||||
cts.WriteRpty(ws, []byte(ev.Data[i]))
|
//cts.WriteRpty(ws, []byte(ev.Data[i]))
|
||||||
|
var bytes []byte
|
||||||
|
bytes, err = base64.StdEncoding.DecodeString(ev.Data[i])
|
||||||
|
if err != nil {
|
||||||
|
s.log.Write(rpty.Id, LOG_WARN, "[%s] Invalid rpty iov data received - %s", req.RemoteAddr, ev.Data[i])
|
||||||
|
} else {
|
||||||
|
cts.WriteRpty(ws, bytes)
|
||||||
// ignore error for now
|
// ignore error for now
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case "size":
|
case "size":
|
||||||
if len(ev.Data) == 2 {
|
if len(ev.Data) == 2 {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package hodu
|
|||||||
import "bufio"
|
import "bufio"
|
||||||
import "context"
|
import "context"
|
||||||
import "crypto/tls"
|
import "crypto/tls"
|
||||||
|
import "encoding/base64"
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
import "errors"
|
import "errors"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@@ -704,7 +705,7 @@ func (pxy *server_pxy_ssh_ws) ServeWebsocket(ws *websocket.Conn) (int, error) {
|
|||||||
n, err = out.Read(buf[:])
|
n, err = out.Read(buf[:])
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
var err2 error
|
var err2 error
|
||||||
err2 = send_ws_data_for_xterm(ws, "iov", string(buf[:n]))
|
err2 = send_ws_data_for_xterm(ws, "iov", base64.StdEncoding.EncodeToString(buf[:n]))
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
s.log.Write(pxy.Id, LOG_ERROR, "[%s] Failed to send to websocket - %s", req.RemoteAddr, err2.Error())
|
s.log.Write(pxy.Id, LOG_ERROR, "[%s] Failed to send to websocket - %s", req.RemoteAddr, err2.Error())
|
||||||
break
|
break
|
||||||
@@ -777,7 +778,14 @@ ws_recv_loop:
|
|||||||
if sess != nil {
|
if sess != nil {
|
||||||
var i int
|
var i int
|
||||||
for i, _ = range ev.Data {
|
for i, _ = range ev.Data {
|
||||||
in.Write([]byte(ev.Data[i]))
|
//in.Write([]byte(ev.Data[i]))
|
||||||
|
var bytes []byte
|
||||||
|
bytes, err = base64.StdEncoding.DecodeString(ev.Data[i])
|
||||||
|
if err != nil {
|
||||||
|
s.log.Write(pxy.Id, LOG_WARN, "[%s] Invalid pxy iov data received - %s", req.RemoteAddr, ev.Data[i])
|
||||||
|
} else {
|
||||||
|
in.Write(bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
xterm.html
26
xterm.html
@@ -94,6 +94,22 @@ const xt_mode = '{{ .Mode }}';
|
|||||||
const conn_id = '{{ .ConnId }}';
|
const conn_id = '{{ .ConnId }}';
|
||||||
const route_id = '{{ .RouteId }}';
|
const route_id = '{{ .RouteId }}';
|
||||||
|
|
||||||
|
function utf8ToBase64(str) {
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const data = encoder.encode(str);
|
||||||
|
const binaryString = String.fromCharCode.apply(null, data);
|
||||||
|
return btoa(binaryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
function base64ToBinary(b64) {
|
||||||
|
const binaryString = atob(b64);
|
||||||
|
const bytes = new Uint8Array(binaryString.length);
|
||||||
|
for (let i = 0; i < binaryString.length; i++) {
|
||||||
|
bytes[i] = binaryString.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
window.onload = function(event) {
|
window.onload = function(event) {
|
||||||
const terminal_container = document.getElementById('terminal-container');
|
const terminal_container = document.getElementById('terminal-container');
|
||||||
const terminal_target = document.getElementById('terminal-target');
|
const terminal_target = document.getElementById('terminal-target');
|
||||||
@@ -235,9 +251,9 @@ window.onload = function(event) {
|
|||||||
let event_text;
|
let event_text;
|
||||||
event_text = (typeof event.data === 'string')? event.data: text_decoder.decode(new Uint8Array(event.data));
|
event_text = (typeof event.data === 'string')? event.data: text_decoder.decode(new Uint8Array(event.data));
|
||||||
const msg = JSON.parse(event_text);
|
const msg = JSON.parse(event_text);
|
||||||
if (msg.type == "iov") {
|
if (msg.type == 'iov') {
|
||||||
for (const data of msg.data) term.write(data);
|
for (const data of msg.data) term.write(base64ToBinary(data));
|
||||||
} else if (msg.type == "status") {
|
} else if (msg.type == 'status') {
|
||||||
if (msg.data.length >= 1) {
|
if (msg.data.length >= 1) {
|
||||||
if (msg.data[0] == 'opened') {
|
if (msg.data[0] == 'opened') {
|
||||||
set_terminal_status('Connected', '');
|
set_terminal_status('Connected', '');
|
||||||
@@ -248,7 +264,7 @@ window.onload = function(event) {
|
|||||||
// socket.onclose() will be executed anyway
|
// socket.onclose() will be executed anyway
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (msg.type == "error") {
|
} else if (msg.type == 'error') {
|
||||||
toggle_login_form(true);
|
toggle_login_form(true);
|
||||||
window.onresize = adjust_terminal_size_unconnected;
|
window.onresize = adjust_terminal_size_unconnected;
|
||||||
set_terminal_status(null, msg.data.join(' '))
|
set_terminal_status(null, msg.data.join(' '))
|
||||||
@@ -275,7 +291,7 @@ window.onload = function(event) {
|
|||||||
|
|
||||||
term.onData(function(data) {
|
term.onData(function(data) {
|
||||||
if (socket.readyState == 1) // if open
|
if (socket.readyState == 1) // if open
|
||||||
socket.send(JSON.stringify({ type: 'iov', data: [data] }));
|
socket.send(JSON.stringify({ type: 'iov', data: [utf8ToBase64(data)] }));
|
||||||
});
|
});
|
||||||
|
|
||||||
window.onresize = adjust_terminal_size_connected;
|
window.onresize = adjust_terminal_size_connected;
|
||||||
|
|||||||
Reference in New Issue
Block a user