mirror of https://github.com/pkg/sftp.git
Make SSH_FXP_STATUS error message optional (#109)
Some SSH implementations do not include an error message in the SSH_FXP_STATUS response causing an "index out of range" panic.
This commit is contained in:
parent
530345cb99
commit
f4e06643a3
|
@ -1165,7 +1165,10 @@ func unmarshalStatus(id uint32, data []byte) error {
|
||||||
return &unexpectedIDErr{id, sid}
|
return &unexpectedIDErr{id, sid}
|
||||||
}
|
}
|
||||||
code, data := unmarshalUint32(data)
|
code, data := unmarshalUint32(data)
|
||||||
msg, data := unmarshalString(data)
|
msg, data, err := unmarshalStringSafe(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
lang, _, _ := unmarshalStringSafe(data)
|
lang, _, _ := unmarshalStringSafe(data)
|
||||||
return &StatusError{
|
return &StatusError{
|
||||||
Code: code,
|
Code: code,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kr/fs"
|
"github.com/kr/fs"
|
||||||
|
@ -87,13 +88,58 @@ func TestFlags(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMissingLangTag(t *testing.T) {
|
func TestUnmarshalStatus(t *testing.T) {
|
||||||
defer func() {
|
requestID := uint32(1)
|
||||||
if r := recover(); r != nil {
|
|
||||||
t.Fail()
|
id := marshalUint32([]byte{}, requestID)
|
||||||
|
idCode := marshalUint32(id, ssh_FX_FAILURE)
|
||||||
|
idCodeMsg := marshalString(idCode, "err msg")
|
||||||
|
idCodeMsgLang := marshalString(idCodeMsg, "lang tag")
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
desc string
|
||||||
|
reqID uint32
|
||||||
|
status []byte
|
||||||
|
want error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "well-formed status",
|
||||||
|
reqID: 1,
|
||||||
|
status: idCodeMsgLang,
|
||||||
|
want: &StatusError{
|
||||||
|
Code: ssh_FX_FAILURE,
|
||||||
|
msg: "err msg",
|
||||||
|
lang: "lang tag",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing error message and language tag",
|
||||||
|
reqID: 1,
|
||||||
|
status: idCode,
|
||||||
|
want: errShortPacket,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing language tag",
|
||||||
|
reqID: 1,
|
||||||
|
status: idCodeMsg,
|
||||||
|
want: &StatusError{
|
||||||
|
Code: ssh_FX_FAILURE,
|
||||||
|
msg: "err msg",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "request identifier mismatch",
|
||||||
|
reqID: 2,
|
||||||
|
status: idCodeMsgLang,
|
||||||
|
want: &unexpectedIDErr{2, requestID},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := unmarshalStatus(tt.reqID, tt.status)
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("unmarshalStatus(%v, %v), test %q\n- want: %#v\n- got: %#v",
|
||||||
|
requestID, tt.status, tt.desc, tt.want, got)
|
||||||
}
|
}
|
||||||
}()
|
}
|
||||||
buf := marshalUint32([]byte{}, 0)
|
|
||||||
buf = marshalStatus(buf, StatusError{})
|
|
||||||
_ = unmarshalStatus(0, buf[:len(buf)-4])
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue