From: hyc Date: Wed, 6 Jan 2010 01:57:53 +0000 (+0000) Subject: Fixes for extended timestamps, bounds checks X-Git-Tag: v2.4~317 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=583959522710fc3c0bf462a14e7362326ed559c3;p=rtmpdump Fixes for extended timestamps, bounds checks git-svn-id: svn://svn.mplayerhq.hu/rtmpdump/trunk@194 400ebc74-4327-4243-bc38-086b20814532 --- diff --git a/amf.c b/amf.c index bf9bcac..ae7aaf2 100644 --- a/amf.c +++ b/amf.c @@ -119,7 +119,7 @@ AMF_DecodeBoolean(const char *data) char * AMF_EncodeInt16(char *output, char *outend, short nVal) { - if (output+2 >= outend) + if (output+2 > outend) return NULL; output[1] = nVal & 0xff; @@ -130,7 +130,7 @@ AMF_EncodeInt16(char *output, char *outend, short nVal) char * AMF_EncodeInt24(char *output, char *outend, int nVal) { - if (output+3 >= outend) + if (output+3 > outend) return NULL; output[2] = nVal & 0xff; @@ -142,7 +142,7 @@ AMF_EncodeInt24(char *output, char *outend, int nVal) char * AMF_EncodeInt32(char *output, char *outend, int nVal) { - if (output+4 >= outend) + if (output+4 > outend) return NULL; output[3] = nVal & 0xff; @@ -155,7 +155,7 @@ AMF_EncodeInt32(char *output, char *outend, int nVal) char * AMF_EncodeString(char *output, char *outend, const AVal * bv) { - if (output + 1 + 2 + bv->av_len >= outend) + if (output + 1 + 2 + bv->av_len > outend) return NULL; *output++ = AMF_STRING; @@ -171,7 +171,7 @@ AMF_EncodeString(char *output, char *outend, const AVal * bv) char * AMF_EncodeNumber(char *output, char *outend, double dVal) { - if (output+1+8 >= outend) + if (output+1+8 > outend) return NULL; *output++ = AMF_NUMBER; // type: Number @@ -232,7 +232,7 @@ AMF_EncodeNumber(char *output, char *outend, double dVal) char * AMF_EncodeBoolean(char *output, char *outend, bool bVal) { - if (output+2 >= outend) + if (output+2 > outend) return NULL; *output++ = AMF_BOOLEAN; @@ -245,7 +245,7 @@ AMF_EncodeBoolean(char *output, char *outend, bool bVal) char * AMF_EncodeNamedString(char *output, char *outend, const AVal * strName, const AVal * strValue) { - if (output+2+strName->av_len >= outend) + if (output+2+strName->av_len > outend) return NULL; output = AMF_EncodeInt16(output, outend, strName->av_len); @@ -258,7 +258,7 @@ AMF_EncodeNamedString(char *output, char *outend, const AVal * strName, const AV char * AMF_EncodeNamedNumber(char *output, char *outend, const AVal * strName, double dVal) { - if (output+2+strName->av_len >= outend) + if (output+2+strName->av_len > outend) return NULL; output = AMF_EncodeInt16(output, outend, strName->av_len); @@ -271,7 +271,7 @@ AMF_EncodeNamedNumber(char *output, char *outend, const AVal * strName, double d char * AMF_EncodeNamedBoolean(char *output, char *outend, const AVal * strName, bool bVal) { - if (output+2+strName->av_len >= outend) + if (output+2+strName->av_len > outend) return NULL; output = AMF_EncodeInt16(output, outend, strName->av_len); diff --git a/rtmp.c b/rtmp.c index cf25973..a949f90 100644 --- a/rtmp.c +++ b/rtmp.c @@ -1870,7 +1870,7 @@ EncodeInt32LE(char *output, int nVal) bool RTMP_ReadPacket(RTMP * r, RTMPPacket * packet) { - char hbuf[RTMP_MAX_HEADER_SIZE+1] = { 0 }, *header = hbuf; + char hbuf[RTMP_MAX_HEADER_SIZE] = { 0 }, *header = hbuf; Log(LOGDEBUG2, "%s: fd=%d", __FUNCTION__, r->m_socket); @@ -1910,7 +1910,7 @@ RTMP_ReadPacket(RTMP * r, RTMPPacket * packet) header += 2; } - int nSize = packetSize[packet->m_headerType]; + int nSize = packetSize[packet->m_headerType], hSize; if (nSize == RTMP_LARGE_HEADER_SIZE) // if we get a full header the timestamp is absolute packet->m_hasAbsTimestamp = true; @@ -1931,7 +1931,7 @@ RTMP_ReadPacket(RTMP * r, RTMPPacket * packet) return false; } - LogHexString(LOGDEBUG2, hbuf, nSize+(header-hbuf)); + hSize = nSize+(header-hbuf); if (nSize >= 3) { @@ -1953,8 +1953,21 @@ RTMP_ReadPacket(RTMP * r, RTMPPacket * packet) packet->m_nInfoField2 = DecodeInt32LE(header + 7); } } + if (packet->m_nInfoField1 == 0xffffff) + { + if (ReadN(r, header+nSize, 4) != 4) + { + Log(LOGERROR, "%s, failed to read extended timestamp", + __FUNCTION__); + return false; + } + packet->m_nInfoField1 = AMF_DecodeInt32(header+nSize); + hSize += 4; + } } + LogHexString(LOGDEBUG2, hbuf, hSize); + bool didAlloc = false; if (packet->m_nBodySize > 0 && packet->m_body == NULL) { @@ -2176,7 +2189,7 @@ RTMP_SendPacket(RTMP * r, RTMPPacket * packet, bool queue) } else { - header = hbuf+2; + header = hbuf+6; hend = hbuf+sizeof(hbuf); } @@ -2190,6 +2203,12 @@ RTMP_SendPacket(RTMP * r, RTMPPacket * packet, bool queue) hSize += cSize; } + if (nSize > 1 && packet->m_nInfoField1 >= 0xffffff) + { + header -= 4; + hSize += 4; + } + hptr = header; c = packet->m_headerType << 6; switch(cSize) @@ -2213,7 +2232,12 @@ RTMP_SendPacket(RTMP * r, RTMPPacket * packet, bool queue) } if (nSize > 1) - hptr = AMF_EncodeInt24(hptr, hend, packet->m_nInfoField1); + { + int t = packet->m_nInfoField1; + if (t > 0xffffff) + t = 0xffffff; + hptr = AMF_EncodeInt24(hptr, hend, t); + } if (nSize > 4) { @@ -2222,7 +2246,10 @@ RTMP_SendPacket(RTMP * r, RTMPPacket * packet, bool queue) } if (nSize > 8) - EncodeInt32LE(hptr, packet->m_nInfoField2); + hptr += EncodeInt32LE(hptr, packet->m_nInfoField2); + + if (nSize > 1 && packet->m_nInfoField1 >= 0xffffff) + hptr = AMF_EncodeInt32(hptr, hend, packet->m_nInfoField1); nSize = packet->m_nBodySize; char *buffer = packet->m_body; diff --git a/rtmp.h b/rtmp.h index 0830d75..d3e9a3e 100644 --- a/rtmp.h +++ b/rtmp.h @@ -76,7 +76,7 @@ uint32_t RTMP_GetTime(); #define RTMP_PACKET_TYPE_VIDEO 0x09 #define RTMP_PACKET_TYPE_INFO 0x12 -#define RTMP_MAX_HEADER_SIZE 14 +#define RTMP_MAX_HEADER_SIZE 18 typedef unsigned char BYTE;