Merge pull request #215 from pabigot/pr/213

Envelope: ensure const objects cannot be changed through _body
This commit is contained in:
Emiel Bruijntjes 2018-04-21 01:59:22 +02:00 committed by GitHub
commit d0a56f4235
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 24 deletions

View File

@ -32,7 +32,7 @@ protected:
* Pointer to the body data (the memory is not managed by the AMQP library!) * Pointer to the body data (the memory is not managed by the AMQP library!)
* @var const char * * @var const char *
*/ */
char *_body; const char *_body;
/** /**
* Size of the data * Size of the data
@ -40,12 +40,6 @@ protected:
*/ */
uint64_t _bodySize; uint64_t _bodySize;
/**
* Was the data allocated by this object?
* @var bool
*/
bool _allocated = false;
public: public:
/** /**
* Constructor * Constructor
@ -56,7 +50,7 @@ public:
* @param body * @param body
* @param size * @param size
*/ */
Envelope(const char *body, uint64_t size) : MetaData(), _body(const_cast<char *>(body)), _bodySize(size) {} Envelope(const char *body, uint64_t size) : MetaData(), _body(body), _bodySize(size) {}
/** /**
* Disabled copy constructor * Disabled copy constructor
@ -68,11 +62,7 @@ public:
/** /**
* Destructor * Destructor
*/ */
virtual ~Envelope() virtual ~Envelope() {}
{
// deallocate the data
if (_allocated) free(_body);
}
/** /**
* Access to the full message data * Access to the full message data

View File

@ -38,6 +38,13 @@ class DeferredReceiver;
*/ */
class Message : public Envelope class Message : public Envelope
{ {
private:
/**
* An allocated and mutable block of memory underlying _body
* @var char *
*/
char *_mutableBody = nullptr;
protected: protected:
/** /**
* The exchange to which it was originally published * The exchange to which it was originally published
@ -88,13 +95,13 @@ protected:
bool append(const char *buffer, uint64_t size) bool append(const char *buffer, uint64_t size)
{ {
// is the body already allocated? // is the body already allocated?
if (_allocated) if (_mutableBody)
{ {
// prevent overflow // prevent overflow
size = std::min(size, _bodySize - _filled); size = std::min(size, _bodySize - _filled);
// append more data // append more data
memcpy(_body + _filled, buffer, (size_t)size); memcpy(_mutableBody + _filled, buffer, (size_t)size);
// update filled data // update filled data
_filled += (size_t)size; _filled += (size_t)size;
@ -103,21 +110,19 @@ protected:
{ {
// we do not have to combine multiple frames, so we can store // we do not have to combine multiple frames, so we can store
// the buffer pointer in the message // the buffer pointer in the message
_body = const_cast<char *>(buffer); _body = buffer;
} }
else else
{ {
// allocate the buffer // allocate the buffer
_body = (char *)malloc((size_t)_bodySize); _mutableBody = (char *)malloc((size_t)_bodySize);
// remember that the buffer was allocated, so that the destructor can get rid of it // expose the body in its immutable form
_allocated = true; _body = _mutableBody;
// append more data // store the initial data
memcpy(_body, buffer, std::min((size_t)size, (size_t)_bodySize));
// update filled data
_filled = std::min((size_t)size, (size_t)_bodySize); _filled = std::min((size_t)size, (size_t)_bodySize);
memcpy(_mutableBody, buffer, _filled);
} }
// check if we're done // check if we're done
@ -144,7 +149,10 @@ public:
/** /**
* Destructor * Destructor
*/ */
virtual ~Message() = default; virtual ~Message()
{
if (_mutableBody) free(_mutableBody);
}
/** /**
* The exchange to which it was originally published * The exchange to which it was originally published