]> git.ipfire.org Git - thirdparty/squid.git/blame_incremental - src/StoreMetaUnpacker.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / StoreMetaUnpacker.cc
... / ...
CommitLineData
1/*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9/* DEBUG: section 20 Storage Manager Swapfile Unpacker */
10
11#include "squid.h"
12#include "base/TextException.h"
13#include "Debug.h"
14#include "defines.h"
15#include "StoreMeta.h"
16#include "StoreMetaUnpacker.h"
17
18int const StoreMetaUnpacker::MinimumBufferLength = sizeof(char) + sizeof(int);
19
20/// useful for meta stored in pre-initialized (with zeros) db files
21bool
22StoreMetaUnpacker::isBufferZero()
23{
24 // We could memcmp the entire buffer, but it is probably safe enough
25 // to test a few bytes because if we do not detect a corrupted entry
26 // it is not a big deal. Empty entries are not isBufferSane anyway.
27 const int depth = 10;
28 if (buflen < depth)
29 return false; // cannot be sure enough
30
31 for (int i = 0; i < depth; ++i) {
32 if (buf[i])
33 return false;
34 }
35 return true;
36}
37
38void
39StoreMetaUnpacker::checkBuffer()
40{
41 assert(buf); // paranoid; already checked in the constructor
42 if (buf[0] != static_cast<char>(STORE_META_OK))
43 throw TexcHere("store entry metadata is corrupted");
44 /*
45 * sanity check on 'buflen' value. It should be at least big
46 * enough to hold one type and one length.
47 */
48 getBufferLength();
49 if (*hdr_len < MinimumBufferLength)
50 throw TexcHere("store entry metadata is too small");
51 if (*hdr_len > buflen)
52 throw TexcHere("store entry metadata is too big");
53}
54
55void
56StoreMetaUnpacker::getBufferLength()
57{
58 memcpy(hdr_len, &buf[1], sizeof(int));
59}
60
61StoreMetaUnpacker::StoreMetaUnpacker(char const *aBuffer, ssize_t aLen, int *anInt) :
62 buf(aBuffer),
63 buflen(aLen),
64 hdr_len(anInt),
65 position(1 + sizeof(int)),
66 type('\0'),
67 length(0),
68 tail(NULL)
69{
70 assert(aBuffer != NULL);
71}
72
73void
74StoreMetaUnpacker::getType()
75{
76 type = buf[position];
77 ++position;
78}
79
80void
81StoreMetaUnpacker::getLength()
82{
83 memcpy(&length, &buf[position], sizeof(int));
84 position += sizeof(int);
85}
86
87bool
88StoreMetaUnpacker::doOneEntry()
89{
90 getType();
91 getLength();
92
93 if (position + length > *hdr_len) {
94 debugs(20, DBG_CRITICAL, "storeSwapMetaUnpack: overflow!");
95 debugs(20, DBG_CRITICAL, "\ttype=" << type << ", length=" << length << ", *hdr_len=" << *hdr_len << ", offset=" << position);
96 return false;
97 }
98
99 StoreMeta *newNode = StoreMeta::Factory(type, length, &buf[position]);
100
101 if (newNode)
102 tail = StoreMeta::Add (tail, newNode);
103
104 position += length;
105
106 return true;
107}
108
109bool
110StoreMetaUnpacker::moreToProcess() const
111{
112 return *hdr_len - position - MinimumBufferLength >= 0;
113}
114
115StoreMeta *
116StoreMetaUnpacker::createStoreMeta ()
117{
118 tlv *TLV = NULL;
119 tail = &TLV;
120 assert(hdr_len != NULL);
121
122 checkBuffer();
123
124 getBufferLength();
125
126 assert (position == 1 + sizeof(int));
127
128 while (moreToProcess()) {
129 if (!doOneEntry())
130 break;
131 }
132
133 if (!TLV)
134 throw TexcHere("store entry metadata is empty");
135
136 assert(TLV);
137 return TLV;
138}
139