From 2e608aba8856dee1c5eade5b6a0f8e9753691816 Mon Sep 17 00:00:00 2001 From: saxon Date: Wed, 15 Aug 2018 05:28:34 +0930 Subject: [PATCH] In the middle of AMFProp_Decode --- rtmp/rtmp.go | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 197 insertions(+), 1 deletion(-) diff --git a/rtmp/rtmp.go b/rtmp/rtmp.go index ead56895..8fb9a819 100644 --- a/rtmp/rtmp.go +++ b/rtmp/rtmp.go @@ -1909,7 +1909,6 @@ func C_RTMP_ClientPacket(r *C.RTMP, packet *C.RTMPPacket) int32 { // rtmp.c +3345 func C_HandleChangeChunkSize(r *C.RTMP, packet *C.RTMPPacket) { if packet.m_nBodySize >= 4 { - // TODO port C.AMF_DeocdeInt32 //r.m_inChunkSize = C.int(C.AMF_DecodeInt32((*C.char)(unsafe.Pointer(packet.m_body)))) r.m_inChunkSize = C.int(C_AMF_DecodeInt32((*byte)(unsafe.Pointer(packet.m_body)))) // TODO use new logger here @@ -2785,6 +2784,203 @@ func C_AMF_Decode(obj *C.AMFObject, pBuffer *byte, nSize int32, bDecodeName int3 return nOriginalSize - nSize } +// 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 + + prop.p_name.av_len = 0 + prop.p_name.av_val = nil + + if nSize == 0 || pBuffer == nil { + // TODO use new logger here + // RTMP_Log(RTMP_LOGDEBUG, "%s: Empty buffer/no buffer pointer!", __FUNCTION__); + return -1 + } + + if bDecodeName != 0 && nSize < 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__); + return -1 + } + + if bDecodeName != 0 { + var nNameSize uint8 = uint8(C_AMF_DecodeInt16(pBuffer)) + if int32(nNameSize) > nSize-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 + } + + C_AMF_DecodeString(pBuffer, &prop.p_name) + nSize -= int32(2 + nNameSize) + pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(2+nNameSize))) + } + + if nSize == 0 { + return -1 + } + + nSize-- + + prop.p_type = (C.AMFDataType)(int32(*pBuffer)) + pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) + + switch prop.p_type { + case AMF_NUMBER: + if nSize < 8 { + return -1 + } + prop.p_vu.p_number = C.double(C_AMF_DecodeNumber(pBuffer)) + nSize -= 8 + + case AMF_BOOLEAN: + if nSize < 1 { + return -1 + } + // TODO port AMF_DecodeBoolean + prop.p_vu.p_number = C.double(C.AMF_DecodeBoolean((*C.char)(unsafe.Pointer(pBuffer)))) + nSize-- + + case AMF_STRING: + { + var nStringSize uint8 = uint8(C_AMF_DecodeInt16(pBuffer)) + + if int64(nSize) < int64(nStringSize)+2 { + return -1 + } + C_AMF_DecodeString(pBuffer, &prop.p_vu.p_aval) + nSize -= uint8(2 + nStringSize) + } + + case AMF_OBJECT: + { + var nRes int32 = int32(C_AMF_Decode(&prop.p_vu.p_object, pBuffer, nSize, 1)) + if nRes == -1 { + return -1 + } + nSize -= nRes + + } + + case AMF_MOVIECLIP: + { + // TODO use new logger here + log.Println("AMFProp_Decode: MAF_MOVIECLIP reserved!") + //RTMP_Log(RTMP_LOGERROR, "AMF_MOVIECLIP reserved!"); + return -1 + + } + case AMF_NULL: + case AMF_UNDEFINED: + case AMF_UNSUPPORTED: + 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, TRUE) + if nRes == -1 { + return -1 + } + nSize -= nRes + } + + case AMF_OBJECT_END: + { + return -1 + } + case AMF_STRICT_ARRAY: + { + var nArrayLen uint32 = C_AMF_DecodeInt32(pBuffer) + nSize -= 4 + + nRes = C_AMF_DecodeArray(&prop.p_vu.p_object, pBuffer+4, nSize, + nArrayLen, FALSE) + if nRes == -1 { + return -1 + } + nSize -= nRes + } + + case AMF_DATE: + { + // TODO use new logger here + //RTMP_Log(RTMP_LOGDEBUG, "AMF_DATE"); + + if nSize < 10 { + return -1 + } + + prop.p_vu.p_number = C_AMF_DecodeNumber(pBuffer) + prop.p_UTCoffset = C_AMF_DecodeInt16(pBuffer + 8) + + nSize -= 10 + + } + case AMF_LONG_STRING: + case AMF_XML_DOC: + { + var nStringSize uint32 = C_AMF_DecodeInt32(pBuffer) + if nSize < int64(nStringSize)+4 { + return -1 + } + AMF_DecodeLongString(pBuffer, &prop.p_vu.p_aval) + nSize -= (4 + nStringSize) + if prop.p_type == AMF_LONG_STRING { + prop.p_type = AMF_STRING + } + } + + case AMF_RECORDSET: + { + // TODO use new logger here + log.Println("AMFProp_Decode: AMF_RECORDSET reserved!") + //RTMP_Log(RTMP_LOGERROR, "AMF_RECORDSET reserved!"); + return -1 + + } + case AMF_TYPED_OBJECT: + { + // TODO use new logger here + RTMP_Log(RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!") + return -1 + } + + case AMF_AVMPLUS: + { + var nRes int32 = int32(C.AMF3_Decode(&prop.p_vu.p_object, pBuffer, nSize, 1)) + if nRes == -1 { + return -1 + } + nSize -= nRes + prop.p_type = AMF_OBJECT + } + default: + // TODO use new logger here + //RTMP_Log(RTMP_LOGDEBUG, "%s - unknown datatype 0x%02x, @%p", __FUNCTION__, + //prop.p_type, pBuffer - 1); + return -1 + } + + return nOriginalSize - nSize +} + // void AMF_AddProp(AMFObject* obj, const AMFObjectProperty* prop); // amf.c + 1234 func C_AMF_AddProp(obj *C.AMFObject, prop *C.AMFObjectProperty) {