Coverage Report

Created: 2023-06-07 07:04

/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
243k
    : struct_pb_(struct_pb) {}
24
25
StructUtils::FindResult StructUtils::GetString(const std::string& name,
26
596k
                                               std::string* str_value) {
27
596k
  const ::google::protobuf::Value* found;
28
596k
  FindResult result = GetValue(name, found);
29
596k
  if (result != OK) {
30
277k
    return result;
31
277k
  }
32
319k
  if (found->kind_case() != google::protobuf::Value::kStringValue) {
33
2.04k
    return WRONG_TYPE;
34
2.04k
  }
35
317k
  *str_value = found->string_value();
36
317k
  return OK;
37
319k
}
38
39
StructUtils::FindResult StructUtils::GetDouble(const std::string& name,
40
7.57k
                                               double* double_value) {
41
7.57k
  const ::google::protobuf::Value* found;
42
7.57k
  FindResult result = GetValue(name, found);
43
7.57k
  if (result != OK) {
44
7.50k
    return result;
45
7.50k
  }
46
77
  if (found->kind_case() != google::protobuf::Value::kNumberValue) {
47
2
    return WRONG_TYPE;
48
2
  }
49
75
  *double_value = found->number_value();
50
75
  return OK;
51
77
}
52
53
StructUtils::FindResult StructUtils::GetUInt64(const std::string& name,
54
7.57k
                                               uint64_t* int_value) {
55
7.57k
  double double_value;
56
7.57k
  FindResult result = GetDouble(name, &double_value);
57
7.57k
  if (result != OK) {
58
7.50k
    return result;
59
7.50k
  }
60
75
  if (double_value < 0 ||
61
75
      double_value >=
62
73
          static_cast<double>(std::numeric_limits<uint64_t>::max())) {
63
3
    return OUT_OF_RANGE;
64
3
  }
65
72
  *int_value = static_cast<uint64_t>(double_value);
66
72
  return OK;
67
75
}
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
2.52k
    const std::string& name, std::vector<std::string>* list) {
85
2.52k
  const ::google::protobuf::Value* found;
86
2.52k
  FindResult result = GetValue(name, found);
87
2.52k
  if (result != OK) {
88
2.50k
    return result;
89
2.50k
  }
90
16
  if (found->kind_case() == google::protobuf::Value::kStringValue) {
91
14
    list->push_back(found->string_value());
92
14
    return OK;
93
14
  }
94
2
  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
2
  return WRONG_TYPE;
104
2
}
105
106
StructUtils::FindResult StructUtils::GetValue(
107
606k
    const std::string& nested_names, const google::protobuf::Value*& found) {
108
606k
  const std::vector<absl::string_view> name_vector =
109
606k
      absl::StrSplit(nested_names, '.');
110
111
606k
  const google::protobuf::Struct* current_struct = &struct_pb_;
112
606k
  for (int i = 0; i < name_vector.size(); ++i) {
113
606k
    const auto& fields = current_struct->fields();
114
606k
    const auto it = fields.find(std::string(name_vector[i]));
115
606k
    if (it == fields.end()) {
116
287k
      return MISSING;
117
287k
    }
118
319k
    if (i == name_vector.size() - 1) {
119
319k
      found = &it->second;
120
319k
      return OK;
121
319k
    }
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
606k
}
129
130
}  // namespace jwt_verify
131
}  // namespace google