From 7f2385b8a2ba73615cbd96742cb16d635db14adb Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Sun, 16 Sep 2018 09:12:59 +0930 Subject: [PATCH] rtmp: make C_AMFProp_Decode take a []byte Also fix errors that exists in the librtmp implementation that resulted in failure to progress the data pointer. --- rtmp/amf.go | 72 ++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/rtmp/amf.go b/rtmp/amf.go index 2678cd95..b4aba4fb 100644 --- a/rtmp/amf.go +++ b/rtmp/amf.go @@ -64,6 +64,14 @@ func pp2b(b, e *byte) []byte { return (*[_Gi]byte)(base)[:len] } +func pl2b(b *byte, l int) []byte { + if b == nil { + return nil + } + base := unsafe.Pointer(b) + return (*[_Gi]byte)(base)[:l] +} + func b2pp(buf []byte) (b, e *byte) { if buf == nil { return nil, nil @@ -341,19 +349,17 @@ func C_AMF_PropEncode(p *C_AMFObjectProperty, dst []byte) []byte { // int AMFProp_Decode(C_AMFObjectProperty* prop, const char* pBuffer, int nSize, int bDecodeName); // amf.c +619 -func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeName int32) int32 { - var nOriginalSize int32 = nSize - var nRes int32 - +func C_AMFProp_Decode(prop *C_AMFObjectProperty, data []byte, bDecodeName int32) int32 { prop.p_name = "" - if nSize == 0 || pBuffer == nil { + nOriginalSize := len(data) + if len(data) == 0 { // TODO use new logger here // RTMP_Log(RTMP_LOGDEBUG, "%s: Empty buffer/no buffer pointer!", __FUNCTION__); return -1 } - if bDecodeName != 0 && nSize < 4 { + if bDecodeName != 0 && len(data) < 4 { // at least name (length + at least 1 byte) and 1 byte of data // TODO use new logger here // RTMP_Log(RTMP_LOGDEBUG, "%s: Not enough data for decoding with name, less than 4 bytes!",__FUNCTION__); @@ -361,52 +367,50 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa } if bDecodeName != 0 { - nNameSize := C_AMF_DecodeInt16((*[_Gi]byte)(unsafe.Pointer(pBuffer))[:2]) - if int32(nNameSize) > nSize-2 { + nNameSize := C_AMF_DecodeInt16(data[:2]) + if int(nNameSize) > len(data)-2 { // TODO use new logger here //RTMP_Log(RTMP_LOGDEBUG, "%s: Name size out of range: namesize (%d) > len (%d) - 2",__FUNCTION__, nNameSize, nSize); return -1 } - prop.p_name = C_AMF_DecodeString((*[_Gi]byte)(unsafe.Pointer(pBuffer))[:nSize]) - nSize -= int32(2 + nNameSize) - pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(2+nNameSize))) + prop.p_name = C_AMF_DecodeString(data) + data = data[2+nNameSize:] } - if nSize == 0 { + if len(data) == 0 { return -1 } - nSize-- - - prop.p_type = (C_AMFDataType)(int32(*pBuffer)) - pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) + prop.p_type = C_AMFDataType(data[0]) + data = data[1:] + var nRes int32 switch prop.p_type { case AMF_NUMBER: - if nSize < 8 { + if len(data) < 8 { return -1 } - prop.p_vu.p_number = C_AMF_DecodeNumber((*[_Gi]byte)(unsafe.Pointer(pBuffer))[:nSize]) - nSize -= 8 + prop.p_vu.p_number = C_AMF_DecodeNumber(data[:8]) + data = data[8:] case AMF_BOOLEAN: panic("AMF_BOOLEAN not supported") case AMF_STRING: - var nStringSize = C_AMF_DecodeInt16((*[_Gi]byte)(unsafe.Pointer(pBuffer))[:2]) - if int64(nSize) < int64(nStringSize)+2 { + nStringSize := C_AMF_DecodeInt16(data[:2]) + if len(data) < int(nStringSize+2) { return -1 } - prop.p_vu.p_aval = C_AMF_DecodeString((*[_Gi]byte)(unsafe.Pointer(pBuffer))[:nSize]) - nSize -= int32(2 + nStringSize) + prop.p_vu.p_aval = C_AMF_DecodeString(data) + data = data[2+nStringSize:] case AMF_OBJECT: - var nRes int32 = C_AMF_Decode(&prop.p_vu.p_object, pBuffer, nSize, 1) + nRes := C_AMF_Decode(&prop.p_vu.p_object, bAddr(data), int32(len(data)), 1) if nRes == -1 { return -1 } - nSize -= nRes + data = data[nRes:] case AMF_MOVIECLIP: // TODO use new logger here @@ -418,26 +422,21 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa prop.p_type = AMF_NULL case AMF_REFERENCE: - // TODO use new logger here log.Println("AMFProp_Decode: AMF_REFERENCE not supported!") //RTMP_Log(RTMP_LOGERROR, "AMF_REFERENCE not supported!"); return -1 case AMF_ECMA_ARRAY: - - nSize -= 4 - // next comes the rest, mixed array has a final 0x000009 mark and names, so its an object - nRes = C_AMF_Decode(&prop.p_vu.p_object, (*byte)(incBytePtr( - unsafe.Pointer(pBuffer), 4)), nSize, 1) + data = data[4:] + nRes = C_AMF_Decode(&prop.p_vu.p_object, bAddr(data), int32(len(data)), 1) if nRes == -1 { return -1 } - nSize -= nRes + data = data[nRes:] case AMF_OBJECT_END: - return -1 case AMF_STRICT_ARRAY: @@ -456,7 +455,6 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa return -1 case AMF_TYPED_OBJECT: - // TODO use new logger here // RTMP_Log(RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!") return -1 @@ -471,7 +469,7 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa return -1 } - return nOriginalSize - nSize + return int32(nOriginalSize - len(data)) } // void AMFProp_Reset(AMFObjectProperty* prop); @@ -575,7 +573,7 @@ func C_AMF_DecodeArray(obj *C_AMFObject, pBuffer *byte, nSize, nArrayLen, bDecod bError = 1 break } - nRes = C_AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName) + nRes = C_AMFProp_Decode(&prop, pl2b(pBuffer, int(nSize)), bDecodeName) if nRes == -1 { bError = 1 break @@ -617,7 +615,7 @@ func C_AMF_Decode(obj *C_AMFObject, pBuffer *byte, nSize, bDecodeName int32) int continue } // TODO port AMFProp_Decode - nRes = C_AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName) + nRes = C_AMFProp_Decode(&prop, pl2b(pBuffer, int(nSize)), bDecodeName) // nRes = int32(C.AMFProp_Decode(&prop, (*byte)(unsafe.Pointer(pBuffer)), // int32(nSize), int32(bDecodeName))) if nRes == -1 {