Commit d5843329 authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

[2749] Check sizes in memory access functions in io_utilities.h

parent 8e2ea006
......@@ -15,6 +15,7 @@
#ifndef IO_UTILITIES_H
#define IO_UTILITIES_H
#include <exceptions/exceptions.h>
#include <cstddef>
namespace isc {
......@@ -28,10 +29,17 @@ namespace util {
/// \param buffer Data buffer at least two bytes long of which the first two
/// bytes are assumed to represent a 16-bit integer in network-byte
/// order.
/// \param length Length of the data buffer.
///
/// \return Value of 16-bit integer
inline uint16_t
readUint16(const void* buffer) {
readUint16(const void* buffer, size_t length) {
if (length < sizeof (uint16_t)) {
isc_throw(isc::OutOfRange,
"Length (" << length << ") of buffer is insufficient " <<
"to read a uint16_t");
}
const uint8_t* byte_buffer = static_cast<const uint8_t*>(buffer);
uint16_t result = (static_cast<uint16_t>(byte_buffer[0])) << 8;
......@@ -48,10 +56,17 @@ readUint16(const void* buffer) {
/// \param value 16-bit value to convert
/// \param buffer Data buffer at least two bytes long into which the 16-bit
/// value is written in network-byte order.
/// \param length Length of the data buffer.
///
/// \return pointer to the next byte after stored value
inline uint8_t*
writeUint16(uint16_t value, void* buffer) {
writeUint16(uint16_t value, void* buffer, size_t length) {
if (length < sizeof (uint16_t)) {
isc_throw(isc::OutOfRange,
"Length (" << length << ") of buffer is insufficient " <<
"to write a uint16_t");
}
uint8_t* byte_buffer = static_cast<uint8_t*>(buffer);
byte_buffer[0] = static_cast<uint8_t>((value & 0xff00U) >> 8);
......@@ -65,10 +80,17 @@ writeUint16(uint16_t value, void* buffer) {
/// \param buffer Data buffer at least four bytes long of which the first four
/// bytes are assumed to represent a 32-bit integer in network-byte
/// order.
/// \param length Length of the data buffer.
///
/// \return Value of 32-bit unsigned integer
inline uint32_t
readUint32(const uint8_t* buffer) {
readUint32(const uint8_t* buffer, size_t length) {
if (length < sizeof (uint32_t)) {
isc_throw(isc::OutOfRange,
"Length (" << length << ") of buffer is insufficient " <<
"to read a uint32_t");
}
const uint8_t* byte_buffer = static_cast<const uint8_t*>(buffer);
uint32_t result = (static_cast<uint32_t>(byte_buffer[0])) << 24;
......@@ -84,10 +106,17 @@ readUint32(const uint8_t* buffer) {
/// \param value 32-bit value to convert
/// \param buffer Data buffer at least four bytes long into which the 32-bit
/// value is written in network-byte order.
/// \param length Length of the data buffer.
///
/// \return pointer to the next byte after stored value
inline uint8_t*
writeUint32(uint32_t value, uint8_t* buffer) {
writeUint32(uint32_t value, uint8_t* buffer, size_t length) {
if (length < sizeof (uint32_t)) {
isc_throw(isc::OutOfRange,
"Length (" << length << ") of buffer is insufficient " <<
"to write a uint32_t");
}
uint8_t* byte_buffer = static_cast<uint8_t*>(buffer);
byte_buffer[0] = static_cast<uint8_t>((value & 0xff000000U) >> 24);
......
......@@ -42,11 +42,15 @@ TEST(asioutil, readUint16) {
data[0] = i8;
data[1] = j8;
buffer.setPosition(0);
EXPECT_EQ(buffer.readUint16(), readUint16(data));
EXPECT_EQ(buffer.readUint16(), readUint16(data, sizeof (data)));
}
}
}
TEST(asioutil, readUint16OutOfRange) {
uint8_t data;
EXPECT_THROW(readUint16(&data, sizeof (data)), isc::OutOfRange);
}
TEST(asioutil, writeUint16) {
......@@ -64,7 +68,7 @@ TEST(asioutil, writeUint16) {
buffer.writeUint16(i16);
// ... and the test data
writeUint16(i16, test);
writeUint16(i16, test, sizeof (test));
// ... and compare
const uint8_t* ref = static_cast<const uint8_t*>(buffer.getData());
......@@ -73,6 +77,12 @@ TEST(asioutil, writeUint16) {
}
}
TEST(asioutil, writeUint16OutOfRange) {
uint16_t i16 = 42;
uint8_t data;
EXPECT_THROW(writeUint16(i16, &data, sizeof (data)), isc::OutOfRange);
}
// test data shared amount readUint32 and writeUint32 tests
const static uint32_t test32[] = {
0,
......@@ -93,11 +103,15 @@ TEST(asioutil, readUint32) {
uint32_t tmp = htonl(test32[i]);
memcpy(&data[offset], &tmp, sizeof(uint32_t));
EXPECT_EQ(test32[i], readUint32(&data[offset]));
EXPECT_EQ(test32[i], readUint32(&data[offset], sizeof (uint32_t)));
}
}
}
TEST(asioutil, readUint32OutOfRange) {
uint8_t data[3];
EXPECT_THROW(readUint32(data, sizeof (data)), isc::OutOfRange);
}
TEST(asioutil, writeUint32) {
uint8_t data[8];
......@@ -107,7 +121,7 @@ TEST(asioutil, writeUint32) {
// it 4 times.
for (int offset=0; offset < 4; offset++) {
for (int i=0; i < sizeof(test32)/sizeof(uint32_t); i++) {
uint8_t* ptr = writeUint32(test32[i], &data[offset]);
uint8_t* ptr = writeUint32(test32[i], &data[offset], sizeof (uint32_t));
EXPECT_EQ(&data[offset]+sizeof(uint32_t), ptr);
......@@ -117,3 +131,9 @@ TEST(asioutil, writeUint32) {
}
}
}
TEST(asioutil, writeUint32OutOfRange) {
uint32_t i32 = 28;
uint8_t data[3];
EXPECT_THROW(writeUint32(i32, data, sizeof (data)), isc::OutOfRange);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment