]> git.ipfire.org Git - thirdparty/squid.git/blame - src/StoreMetaUnpacker.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / StoreMetaUnpacker.cc
CommitLineData
528b2c61 1/*
ef57eb7b 2 * Copyright (C) 1996-2016 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
23541b3e 64StoreMetaUnpacker::StoreMetaUnpacker(char const *aBuffer, ssize_t aLen, int *anInt) :
f53969cc
SM
65 buf(aBuffer),
66 buflen(aLen),
67 hdr_len(anInt),
68 position(1 + sizeof(int)),
69 type('\0'),
70 length(0),
71 tail(NULL)
528b2c61 72{
23541b3e 73 assert(aBuffer != NULL);
528b2c61 74}
75
76void
77StoreMetaUnpacker::getType()
78{
f412b2d6
FC
79 type = buf[position];
80 ++position;
528b2c61 81}
82
83void
84StoreMetaUnpacker::getLength()
85{
41d00cd3 86 memcpy(&length, &buf[position], sizeof(int));
528b2c61 87 position += sizeof(int);
88}
89
90bool
91StoreMetaUnpacker::doOneEntry()
92{
93 getType();
94 getLength();
62e76326 95
528b2c61 96 if (position + length > *hdr_len) {
fa84c01d
FC
97 debugs(20, DBG_CRITICAL, "storeSwapMetaUnpack: overflow!");
98 debugs(20, DBG_CRITICAL, "\ttype=" << type << ", length=" << length << ", *hdr_len=" << *hdr_len << ", offset=" << position);
528b2c61 99 return false;
100 }
62e76326 101
528b2c61 102 StoreMeta *newNode = StoreMeta::Factory(type, length, &buf[position]);
62e76326 103
5b8ddb2a 104 if (newNode)
26ac0430 105 tail = StoreMeta::Add (tail, newNode);
62e76326 106
528b2c61 107 position += length;
62e76326 108
528b2c61 109 return true;
110}
111
112bool
113StoreMetaUnpacker::moreToProcess() const
114{
7c209882 115 return *hdr_len - position - MinimumBufferLength >= 0;
528b2c61 116}
117
118StoreMeta *
119StoreMetaUnpacker::createStoreMeta ()
120{
121 tlv *TLV = NULL;
122 tail = &TLV;
123 assert(hdr_len != NULL);
62e76326 124
528b2c61 125 if (!isBufferSane())
62e76326 126 return NULL;
127
528b2c61 128 getBufferLength();
62e76326 129
528b2c61 130 assert (position == 1 + sizeof(int));
62e76326 131
528b2c61 132 while (moreToProcess()) {
62e76326 133 if (!doOneEntry())
134 break;
528b2c61 135 }
62e76326 136
528b2c61 137 return TLV;
138}
f53969cc 139