Coverage Report

Created: 2023-08-17 06:18

/proc/self/cwd/src/struct_utils.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2018 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//    https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "jwt_verify_lib/struct_utils.h"
16
17
#include "absl/strings/str_split.h"
18
19
namespace google {
20
namespace jwt_verify {
21
22
StructUtils::StructUtils(const ::google::protobuf::Struct& struct_pb)
23
217k
    : struct_pb_(struct_pb) {}
24
25
StructUtils::FindResult StructUtils::GetString(const std::string& name,
26
522k
                                               std::string* str_value) {
27
522k
  const ::google::protobuf::Value* found;
28
522k
  FindResult result = GetValue(name, found);
29
522k
  if (result != OK) {
30
240k
    return result;
31
240k
  }
32
282k
  if (found->kind_case() != google::protobuf::Value::kStringValue) {
33
2.19k
    return WRONG_TYPE;
34
2.19k
  }
35
279k
  *str_value = found->string_value();
36
279k
  return OK;
37
282k
}
38
39
StructUtils::FindResult StructUtils::GetDouble(const std::string& name,
40
5.73k
                                               double* double_value) {
41
5.73k
  const ::google::protobuf::Value* found;
42
5.73k
  FindResult result = GetValue(name, found);
43
5.73k
  if (result != OK) {
44
5.65k
    return result;
45
5.65k
  }
46
79
  if (found->kind_case() != google::protobuf::Value::kNumberValue) {
47
3
    return WRONG_TYPE;
48
3
  }
49
76
  *double_value = found->number_value();
50
76
  return OK;
51
79
}
52
53
StructUtils::FindResult StructUtils::GetUInt64(const std::string& name,
54
5.73k
                                               uint64_t* int_value) {
55
5.73k
  double double_value;
56
5.73k
  FindResult result = GetDouble(name, &double_value);
57
5.73k
  if (result != OK) {
58
5.65k
    return result;
59
5.65k
  }
60
76
  if (double_value < 0 ||
61
76
      double_value >=
62
73
          static_cast<double>(std::numeric_limits<uint64_t>::max())) {
63
3
    return OUT_OF_RANGE;
64
3
  }
65
73
  *int_value = static_cast<uint64_t>(double_value);
66
73
  return OK;
67
76
}
68
69
StructUtils::FindResult StructUtils::GetBoolean(const std::string& name,
70
0
                                                bool* bool_value) {
71
0
  const ::google::protobuf::Value* found;
72
0
  FindResult result = GetValue(name, found);
73
0
  if (result != OK) {
74
0
    return result;
75
0
  }
76
0
  if (found->kind_case() != google::protobuf::Value::kBoolValue) {
77
0
    return WRONG_TYPE;
78
0
  }
79
0
  *bool_value = found->bool_value();
80
0
  return OK;
81
0
}
82
83
StructUtils::FindResult StructUtils::GetStringList(
84
1.90k
    const std::string& name, std::vector<std::string>* list) {
85
1.90k
  const ::google::protobuf::Value* found;
86
1.90k
  FindResult result = GetValue(name, found);
87
1.90k
  if (result != OK) {
88
1.90k
    return result;
89
1.90k
  }
90
7
  if (found->kind_case() == google::protobuf::Value::kStringValue) {
91
7
    list->push_back(found->string_value());
92
7
    return OK;
93
7
  }
94
0
  if (found->kind_case() == google::protobuf::Value::kListValue) {
95
0
    for (const auto& v : found->list_value().values()) {
96
0
      if (v.kind_case() != google::protobuf::Value::kStringValue) {
97
0
        return WRONG_TYPE;
98
0
      }
99
0
      list->push_back(v.string_value());
100
0
    }
101
0
    return OK;
102
0
  }
103
0
  return WRONG_TYPE;
104
0
}
105
106
StructUtils::FindResult StructUtils::GetValue(
107
530k
    const std::string& nested_names, const google::protobuf::Value*& found) {
108
530k
  const std::vector<absl::string_view> name_vector =
109
530k
      absl::StrSplit(nested_names, '.');
110
111
530k
  const google::protobuf::Struct* current_struct = &struct_pb_;
112
530k
  for (int i = 0; i < name_vector.size(); ++i) {
113
530k
    const auto& fields = current_struct->fields();
114
530k
    const auto it = fields.find(std::string(name_vector[i]));
115
530k
    if (it == fields.end()) {
116
248k
      return MISSING;
117
248k
    }
118
282k
    if (i == name_vector.size() - 1) {
119
282k
      found = &it->second;
120
282k
      return OK;
121
282k
    }
122
0
    if (it->second.kind_case() != google::protobuf::Value::kStructValue) {
123
0
      return WRONG_TYPE;
124
0
    }
125
0
    current_struct = &it->second.struct_value();
126
0
  }
127
0
  return MISSING;
128
530k
}
129
130
}  // namespace jwt_verify
131
}  // namespace google