]> git.ipfire.org Git - thirdparty/squid.git/blame - src/StoreMetaUnpacker.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / StoreMetaUnpacker.cc
CommitLineData
528b2c61 1/*
bbc27441 2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
528b2c61 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
528b2c61 7 */
8
bbc27441
AJ
9/* DEBUG: section 20 Storage Manager Swapfile Unpacker */
10
582c2af2 11#include "squid.h"
582c2af2 12#include "Debug.h"
602d9612 13#include "defines.h"
528b2c61 14#include "StoreMeta.h"
602d9612 15#include "StoreMetaUnpacker.h"
528b2c61 16
57d55dfa 17int const StoreMetaUnpacker::MinimumBufferLength = sizeof(char) + sizeof(int);
528b2c61 18
e2851fe7
AR
19/// useful for meta stored in pre-initialized (with zeros) db files
20bool
21StoreMetaUnpacker::isBufferZero()
22{
23 // We could memcmp the entire buffer, but it is probably safe enough
24 // to test a few bytes because if we do not detect a corrupted entry
25 // it is not a big deal. Empty entries are not isBufferSane anyway.
26 const int depth = 10;
27 if (buflen < depth)
28 return false; // cannot be sure enough
29
30 for (int i = 0; i < depth; ++i) {
31 if (buf[i])
32 return false;
33 }
34 return true;
35}
36
528b2c61 37bool
38StoreMetaUnpacker::isBufferSane()
39{
40 if (buf[0] != (char) STORE_META_OK)
62e76326 41 return false;
42
528b2c61 43 /*
44 * sanity check on 'buflen' value. It should be at least big
45 * enough to hold one type and one length.
46 */
47 getBufferLength();
62e76326 48
7c209882 49 if (*hdr_len < MinimumBufferLength)
62e76326 50 return false;
51
528b2c61 52 if (*hdr_len > buflen)
62e76326 53 return false;
54
528b2c61 55 return true;
56}
57
58void
59StoreMetaUnpacker::getBufferLength()
60{
41d00cd3 61 memcpy(hdr_len, &buf[1], sizeof(int));
528b2c61 62}
63
64StoreMetaUnpacker::StoreMetaUnpacker (char const *aBuffer, ssize_t aLen, int *anInt) : buf (aBuffer), buflen(aLen), hdr_len(anInt), position(1 + sizeof(int))
65{
66 assert (aBuffer != NULL);
67}
68
69void
70StoreMetaUnpacker::getType()
71{
f412b2d6
FC
72 type = buf[position];
73 ++position;
528b2c61 74}
75
76void
77StoreMetaUnpacker::getLength()
78{
41d00cd3 79 memcpy(&length, &buf[position], sizeof(int));
528b2c61 80 position += sizeof(int);
81}
82
83bool
84StoreMetaUnpacker::doOneEntry()
85{
86 getType();
87 getLength();
62e76326 88
528b2c61 89 if (position + length > *hdr_len) {
fa84c01d
FC
90 debugs(20, DBG_CRITICAL, "storeSwapMetaUnpack: overflow!");
91 debugs(20, DBG_CRITICAL, "\ttype=" << type << ", length=" << length << ", *hdr_len=" << *hdr_len << ", offset=" << position);
528b2c61 92 return false;
93 }
62e76326 94
528b2c61 95 StoreMeta *newNode = StoreMeta::Factory(type, length, &buf[position]);
62e76326 96
5b8ddb2a 97 if (newNode)
26ac0430 98 tail = StoreMeta::Add (tail, newNode);
62e76326 99
528b2c61 100 position += length;
62e76326 101
528b2c61 102 return true;
103}
104
105bool
106StoreMetaUnpacker::moreToProcess() const
107{
7c209882 108 return *hdr_len - position - MinimumBufferLength >= 0;
528b2c61 109}
110
111StoreMeta *
112StoreMetaUnpacker::createStoreMeta ()
113{
114 tlv *TLV = NULL;
115 tail = &TLV;
116 assert(hdr_len != NULL);
62e76326 117
528b2c61 118 if (!isBufferSane())
62e76326 119 return NULL;
120
528b2c61 121 getBufferLength();
62e76326 122
528b2c61 123 assert (position == 1 + sizeof(int));
62e76326 124
528b2c61 125 while (moreToProcess()) {
62e76326 126 if (!doOneEntry())
127 break;
528b2c61 128 }
62e76326 129
528b2c61 130 return TLV;
131}