SwapMetaView.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 #include "squid.h"
10 #include "base/Raw.h"
11 #include "base/TextException.h"
12 #include "debug/Stream.h"
13 #include "sbuf/Stream.h"
14 #include "store/SwapMetaView.h"
15 
16 #include <iostream>
17 
18 namespace Store {
19 
21 static void
23 {
24  if (ReservedSwapMetaType(type)) {
25  debugs(20, 3, "ignoring swap meta field with a reserved type: " << int(type));
26  return;
27  }
28 
29  if (DeprecatedSwapMetaType(type)) {
30  debugs(20, DBG_IMPORTANT, "ERROR: Ignoring swap meta field with a deprecated type: " << int(type));
31  return;
32  }
33 
34  // TODO: Instead of assuming that all future swap meta types can be ignored
35  // (and some should be reported at level-0/1), future-proof this code by
36  // using a type bit to define whether to silently ignore a swap meta field
37  // with that type (or even the whole Store entry with that field).
38 
39  const auto typeValuesWeMightAdd = 10;
40  // compute "type > RawSwapMetaTypeTop() + typeValuesWeMightAdd" w/o overflow
41  if (type >= typeValuesWeMightAdd && type - typeValuesWeMightAdd > RawSwapMetaTypeTop()) {
42  debugs(20, DBG_IMPORTANT, "ERROR: Malformed cache storage; ignoring swap meta field with an unexpected type: " << int(type));
43  return;
44  }
45 
46  if (type > RawSwapMetaTypeTop()) {
47  debugs(20, 3, "ignoring swap meta field with a presumed future type: " << int(type));
48  return;
49  }
50 
51  assert(type <= RawSwapMetaTypeBottom); // handled all other bad types above
52  debugs(20, DBG_IMPORTANT, "ERROR: Malformed cache storage; ignoring swap meta field with an invalid type: " << int(type));
53 }
54 
55 } // namespace Store
56 
57 Store::SwapMetaView::SwapMetaView(const void * const begin, const void * const end)
58 {
59  auto input = static_cast<const char *>(begin);
60 
61  SwapMetaExtract(rawType, input, end);
63  type = static_cast<SwapMetaType>(rawType);
64  else
65  HandleBadRawType(rawType); // and leave type as STORE_META_VOID
66 
67  RawSwapMetaLength lengthOrGarbage = 0;
68  SwapMetaExtract(lengthOrGarbage, input, end);
69  if (lengthOrGarbage < 0)
70  throw TextException("negative swap meta field length value", Here());
71  if (uint64_t(lengthOrGarbage) > SwapMetaFieldValueLengthMax)
72  throw TextException("huge swap meta field length value", Here());
73  if (input + lengthOrGarbage > end)
74  throw TextException("truncated swap meta field value", Here());
75  rawLength = static_cast<size_t>(lengthOrGarbage);
76 
77  assert(input > begin); // we consumed some input but stayed in the buffer range (the lower bound check)
78  assert(input + rawLength <= end); // we stayed in the buffer range (the upper bound check)
79  rawValue = input;
80 }
81 
82 void
83 Store::SwapMetaView::checkExpectedLength(const size_t expectedLength) const
84 {
85  if (rawLength != expectedLength)
86  throw TextException(ToSBuf("Bad value length in a Store entry meta field expecting a ",
87  expectedLength, "-byte value: ", *this), Here());
88 }
89 
90 std::ostream &
91 Store::operator <<(std::ostream &os, const SwapMetaView &meta)
92 {
93  os << "type=" << int(meta.rawType);
94  // XXX: Change Raw constructor to take void* data instead of casting here.
95  const auto rawValue = reinterpret_cast<const char*>(meta.rawValue);
96  os << Raw("value", rawValue, meta.rawLength).minLevel(DBG_DATA).hex();
97  return os;
98 }
99 
constexpr RawSwapMetaType RawSwapMetaTypeTop()
Definition: SwapMeta.h:131
Raw & minLevel(const int aLevel)
limit data printing to at least the given debugging level
Definition: Raw.h:27
#define Here()
source code location of the caller
Definition: Here.h:15
SwapMetaType type
Definition: SwapMetaView.h:43
void checkExpectedLength(size_t) const
ensures that our fixed-size field value has the given expected length
Definition: SwapMetaView.cc:83
#define DBG_DATA
Definition: Stream.h:40
Definition: Raw.h:20
static void HandleBadRawType(const RawSwapMetaType type)
properly reports or rejects a problematic raw swap meta field type
Definition: SwapMetaView.cc:22
a swap metadata field inside the buffer given to SwapMetaUnpacker
Definition: SwapMetaView.h:20
constexpr bool DeprecatedSwapMetaType(const RawSwapMetaType type)
Definition: SwapMeta.h:158
char RawSwapMetaType
Definition: SwapMeta.h:95
void SwapMetaExtract(Item &item, const char *&input, const void *end)
Definition: SwapMetaView.h:68
#define assert(EX)
Definition: assert.h:17
constexpr bool ReservedSwapMetaType(const RawSwapMetaType type)
Definition: SwapMeta.h:180
std::ostream & operator<<(std::ostream &os, const ParsingBuffer &b)
SwapMetaView()=default
int RawSwapMetaLength
Definition: SwapMeta.h:100
const size_t SwapMetaFieldValueLengthMax
Definition: SwapMeta.h:107
RawSwapMetaType rawType
Definition: SwapMetaView.h:39
an std::runtime_error with thrower location info
Definition: TextException.h:20
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63
Raw & hex()
print data using two hex digits per byte (decoder: xxd -r -p)
Definition: Raw.h:30
#define DBG_IMPORTANT
Definition: Stream.h:38
const RawSwapMetaType RawSwapMetaTypeBottom
Definition: SwapMeta.h:126
SwapMetaType
Definition: SwapMeta.h:52
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
constexpr bool HonoredSwapMetaType(const RawSwapMetaType type)
Definition: SwapMeta.h:197
int unsigned int
Definition: stub_fd.cc:19
const void * rawValue
Definition: SwapMetaView.h:30

 

Introduction

Documentation

Support

Miscellaneous