From 35df73e04251014b903eca5a007c213e895b7440 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 26 Mar 2013 15:57:53 +0100 Subject: [PATCH] Fixed several buffer segfaults when multiple viewers are connected. --- lib/dtsc.cpp | 7 ++++--- lib/json.cpp | 41 ++++++++++++++++++++++++++--------------- lib/json.h | 1 + 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 7d2ad220..eb88eac1 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -126,6 +126,7 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){ std::string wholepacket = buffer.remove(len + 8); metadata = JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i); metadata.removeMember("moreheader"); + metadata.netPrepare(); if ( !buffer.available(8)){ return false; } @@ -332,7 +333,7 @@ void DTSC::Stream::updateHeaders(){ metadata.removeMember("frags"); metadata.removeMember("lastms"); metadata.removeMember("missed_frags"); - metadata.toPacked(); + metadata.netPrepare(); return; } metadata["keytime"].shrink(keyframes.size() - 2); @@ -370,7 +371,7 @@ void DTSC::Stream::updateHeaders(){ metadata["lastms"] = buffers[keyframes[0].b]["time"].asInt(); metadata["buffer_window"] = (long long int)buffertime; metadata["live"] = true; - metadata.toPacked(); + metadata.netPrepare(); updateRingHeaders(); } } @@ -592,7 +593,7 @@ void DTSC::File::readHeader(int pos){ } } metadata["vod"] = true; - metadata.toPacked(); + metadata.netPrepare(); } /// Reads the packet available at the current file position. diff --git a/lib/json.cpp b/lib/json.cpp index 68596e90..e5f2d72e 100644 --- a/lib/json.cpp +++ b/lib/json.cpp @@ -464,13 +464,36 @@ std::string JSON::Value::toPacked(){ } return r; } -; //toPacked +/// Pre-packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header. +/// Non-object-types will print an error to stderr. +/// The internal buffer is guaranteed to be up-to-date after this function is called. +void JSON::Value::netPrepare(){ + if (myType != OBJECT){ + fprintf(stderr, "Error: Only objects may be NetPacked!\n"); + return; + } + std::string packed = toPacked(); + strVal.resize(packed.size() + 8); + //insert proper header for this type of data + if (isMember("datatype")){ + memcpy((void*)strVal.c_str(), "DTPD", 4); + }else{ + memcpy((void*)strVal.c_str(), "DTSC", 4); + } + //insert the packet length at bytes 4-7 + unsigned int size = htonl(packed.size()); + memcpy((void*)(strVal.c_str() + 4), (void*) &size, 4); + //copy the rest of the string + memcpy((void*)(strVal.c_str() + 8), packed.c_str(), packed.size()); +} + /// Packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header. /// Non-object-types will print an error to stderr and return an empty string. /// This function returns a reference to an internal buffer where the prepared data is kept. -/// The internal buffer is *not* made stale if any changes occur inside the object - subsequent calls to toPacked() will clear the buffer. +/// The internal buffer is *not* made stale if any changes occur inside the object - subsequent calls to toPacked() will clear the buffer, +/// calls to netPrepare will guarantee it is up-to-date. std::string & JSON::Value::toNetPacked(){ static std::string emptystring; //check if this is legal @@ -480,19 +503,7 @@ std::string & JSON::Value::toNetPacked(){ } //if sneaky storage doesn't contain correct data, re-calculate it if (strVal.size() == 0 || strVal[0] != 'D' || strVal[1] != 'T'){ - std::string packed = toPacked(); - strVal.resize(packed.size() + 8); - //insert proper header for this type of data - if (isMember("datatype")){ - memcpy((void*)strVal.c_str(), "DTPD", 4); - }else{ - memcpy((void*)strVal.c_str(), "DTSC", 4); - } - //insert the packet length at bytes 4-7 - unsigned int size = htonl(packed.size()); - memcpy((void*)(strVal.c_str() + 4), (void*) &size, 4); - //copy the rest of the string - memcpy((void*)(strVal.c_str() + 8), packed.c_str(), packed.size()); + netPrepare(); } return strVal; } diff --git a/lib/json.h b/lib/json.h index a2db4845..2f2e4e55 100644 --- a/lib/json.h +++ b/lib/json.h @@ -70,6 +70,7 @@ namespace JSON { Value & operator[](unsigned int i); //handy functions and others std::string toPacked(); + void netPrepare(); std::string & toNetPacked(); std::string toString(); std::string toPrettyString(int indentation = 0);