/* DEBUG: section 20 Storage Manager Swapfile Unpacker */
#include "squid.h"
+#include "base/TextException.h"
#include "Debug.h"
#include "defines.h"
#include "StoreMeta.h"
return true;
}
-bool
-StoreMetaUnpacker::isBufferSane()
+void
+StoreMetaUnpacker::checkBuffer()
{
- if (buf[0] != (char) STORE_META_OK)
- return false;
-
+ assert(buf); // paranoid; already checked in the constructor
+ if (buf[0] != static_cast<char>(STORE_META_OK))
+ throw TexcHere("store entry metadata is corrupted");
/*
* sanity check on 'buflen' value. It should be at least big
* enough to hold one type and one length.
*/
getBufferLength();
-
if (*hdr_len < MinimumBufferLength)
- return false;
-
+ throw TexcHere("store entry metadata is too small");
if (*hdr_len > buflen)
- return false;
-
- return true;
+ throw TexcHere("store entry metadata is too big");
}
void
tail = &TLV;
assert(hdr_len != NULL);
- if (!isBufferSane())
- return NULL;
+ checkBuffer();
getBufferLength();
break;
}
+ if (!TLV)
+ throw TexcHere("store entry metadata is empty");
+
+ assert(TLV);
return TLV;
}
public:
StoreMetaUnpacker (const char *buf, ssize_t bufferLength, int *hdrlen);
StoreMeta *createStoreMeta();
- bool isBufferZero(); ///< all-zeros buffer, implies !isBufferSane
- bool isBufferSane();
+ bool isBufferZero(); ///< all-zeros buffer, checkBuffer() would throw
+ /// validates buffer sanity and throws if validation fails
+ void checkBuffer();
private:
static int const MinimumBufferLength;
exchangeBuffer.length(),
&staleSwapHeaderSize);
// Squid assumes that metadata always fits into a single db slot
- Must(aBuilder.isBufferSane()); // cannot update what we cannot parse
+ aBuilder.checkBuffer(); // cannot update an entry with invalid metadata
debugs(47, 7, "staleSwapHeaderSize=" << staleSwapHeaderSize);
Must(staleSwapHeaderSize > 0);
exchangeBuffer.consume(staleSwapHeaderSize);
}
int swap_hdr_sz = 0;
- StoreMetaUnpacker aBuilder(buf, len, &swap_hdr_sz);
-
- if (!aBuilder.isBufferSane()) {
- /* oops, bad disk file? */
- debugs(90, DBG_IMPORTANT, "WARNING: swapfile header inconsistent with available data");
- return false;
- }
-
- tlv *tlv_list = aBuilder.createStoreMeta ();
-
- if (tlv_list == NULL) {
- debugs(90, DBG_IMPORTANT, "WARNING: failed to unpack meta data");
+ tlv *tlv_list = nullptr;
+ try {
+ StoreMetaUnpacker aBuilder(buf, len, &swap_hdr_sz);
+ tlv_list = aBuilder.createStoreMeta();
+ } catch (const std::exception &e) {
+ debugs(90, DBG_IMPORTANT, "WARNING: failed to unpack metadata because " << e.what());
return false;
}
+ assert(tlv_list);
/*
* Check the meta data and make sure we got the right object.
return false;
}
- if (!aBuilder.isBufferSane()) {
- debugs(47, DBG_IMPORTANT, "WARNING: Ignoring malformed cache entry.");
- return false;
- }
-
- StoreMeta *tlv_list = aBuilder.createStoreMeta();
- if (!tlv_list) {
- debugs(47, DBG_IMPORTANT, "WARNING: Ignoring cache entry with invalid " <<
- "meta data");
+ StoreMeta *tlv_list = nullptr;
+ try {
+ tlv_list = aBuilder.createStoreMeta();
+ } catch (const std::exception &e) {
+ debugs(47, DBG_IMPORTANT, "WARNING: Ignoring store entry because " << e.what());
return false;
}
+ assert(tlv_list);
// TODO: consume parsed metadata?
for_each(*metadata, dumper);
return 0;
- } catch (std::runtime_error error) {
- std::cout << "Failed : " << error.what() << std::endl;
+ } catch (const std::exception &e) {
+ std::cout << "Failed : " << e.what() << std::endl;
if (fd >= 0)
close(fd);