Bug Summary

File:home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/dhcpsrv/testutils/test_utils.cc
Warning:line 124, column 13
An undefined value may be read from 'errno'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test_utils.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/dhcpsrv/testutils -fcoverage-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/dhcpsrv/testutils -resource-dir /usr/bin/../lib/clang/19 -D HAVE_CONFIG_H -I . -I ../../../.. -I ../../../../src/lib -I ../../../../src/lib -D DATABASE_SCRIPTS_DIR="/home/fedora/workspace/kea-dev/clang-static-analyzer/src/share/database/scripts" -I /usr/src/googletest/googletest -I /usr/src/googletest/googletest/include -D _GNU_SOURCE -I /usr/include/libxml2 -D WITH_GZFILEOP -I /usr/include -I /usr/include/pgsql/server -I /usr/include/mysql -I /usr/include/mysql/mysql -D OS_LINUX -I ../../../.. -I ../../../.. -D PIC -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/backward -internal-isystem /usr/bin/../lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -Wno-sign-compare -Wno-missing-field-initializers -std=c++20 -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/fedora/workspace/kea-dev/clang-static-analyzer/report/2024-12-20-083036-19082-1 -x c++ test_utils.cc
1// Copyright (C) 2012-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <asiolink/io_address.h>
10#include <dhcpsrv/testutils/test_utils.h>
11#include <testutils/gtest_utils.h>
12
13#include <gtest/gtest.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
18using namespace std;
19using namespace isc::asiolink;
20
21namespace isc {
22namespace dhcp {
23namespace test {
24
25void
26detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
27 // Compare address strings. Comparison of address objects is not used, as
28 // odd things happen when they are different: the EXPECT_EQ macro appears to
29 // call the operator uint32_t() function, which causes an exception to be
30 // thrown for IPv6 addresses.
31 ASSERT_TRUE(first)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(first)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "test_utils.cc", 31, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "first", "false", "true") .c_str()) = ::testing::
Message()
;
32 ASSERT_TRUE(second)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(second)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "test_utils.cc", 32, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "second", "false", "true") .c_str()) = ::testing
::Message()
;
33 EXPECT_EQ(first->addr_, second->addr_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->addr_"
, "second->addr_", first->addr_, second->addr_))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "test_utils.cc", 33, gtest_ar.failure_message
()) = ::testing::Message()
;
34
35 // We need to compare the actual HWAddr objects, not pointers
36 EXPECT_TRUE(*first->hwaddr_ == *second->hwaddr_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(*first->hwaddr_ ==
*second->hwaddr_)) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "test_utils.cc"
, 36, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "*first->hwaddr_ == *second->hwaddr_", "false", "true"
) .c_str()) = ::testing::Message()
;
37
38 if (first->client_id_ && second->client_id_) {
39 EXPECT_TRUE(*first->client_id_ == *second->client_id_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(*first->client_id_
== *second->client_id_)) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "test_utils.cc"
, 39, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "*first->client_id_ == *second->client_id_", "false",
"true") .c_str()) = ::testing::Message()
;
40 } else {
41 if (first->client_id_ && !second->client_id_) {
42
43 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "test_utils.cc", 43, "Failed") = ::testing::
Message()
<< "Client-id present in first lease ("
44 << first->client_id_->getClientId().size()
45 << " bytes), but missing in second.";
46 }
47 if (!first->client_id_ && second->client_id_) {
48 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "test_utils.cc", 48, "Failed") = ::testing::
Message()
<< "Client-id missing in first lease, but present in second ("
49 << second->client_id_->getClientId().size()
50 << " bytes).";
51 }
52 // else here would mean that both leases do not have client_id_
53 // which makes them equal in that regard. It is ok.
54 }
55
56 // Since the initial time values were set, one second could have ticked,
57 // so allow one second of margin error.
58 EXPECT_NEAR(first->valid_lft_, second->valid_lft_, 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::DoubleNearPredFormat("first->valid_lft_"
, "second->valid_lft_", "1", first->valid_lft_, second->
valid_lft_, 1))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "test_utils.cc", 58, gtest_ar
.failure_message()) = ::testing::Message()
;
59 EXPECT_NEAR(first->cltt_, second->cltt_, 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::DoubleNearPredFormat("first->cltt_"
, "second->cltt_", "1", first->cltt_, second->cltt_,
1))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 59, gtest_ar.failure_message
()) = ::testing::Message()
;
60
61 EXPECT_EQ(first->subnet_id_, second->subnet_id_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->subnet_id_"
, "second->subnet_id_", first->subnet_id_, second->subnet_id_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 61, gtest_ar.failure_message
()) = ::testing::Message()
;
62 EXPECT_EQ(first->pool_id_, second->pool_id_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->pool_id_"
, "second->pool_id_", first->pool_id_, second->pool_id_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 62, gtest_ar.failure_message
()) = ::testing::Message()
;
63 EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->fqdn_fwd_"
, "second->fqdn_fwd_", first->fqdn_fwd_, second->fqdn_fwd_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 63, gtest_ar.failure_message
()) = ::testing::Message()
;
64 EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->fqdn_rev_"
, "second->fqdn_rev_", first->fqdn_rev_, second->fqdn_rev_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 64, gtest_ar.failure_message
()) = ::testing::Message()
;
65 EXPECT_EQ(first->hostname_, second->hostname_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->hostname_"
, "second->hostname_", first->hostname_, second->hostname_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 65, gtest_ar.failure_message
()) = ::testing::Message()
;
66 if (first->getContext()) {
67 EXPECT_TRUE(second->getContext())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(second->getContext
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 67, ::testing::internal::
GetBoolAssertionFailureMessage( gtest_ar_, "second->getContext()"
, "false", "true") .c_str()) = ::testing::Message()
;
68 if (second->getContext()) {
69 EXPECT_EQ(first->getContext()->str(), second->getContext()->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->getContext()->str()"
, "second->getContext()->str()", first->getContext()
->str(), second->getContext()->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "test_utils.cc", 69, gtest_ar.failure_message()) = ::testing
::Message()
;
70 }
71 } else {
72 EXPECT_FALSE(second->getContext())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(second->getContext
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 72, ::testing::internal::
GetBoolAssertionFailureMessage( gtest_ar_, "second->getContext()"
, "true", "false") .c_str()) = ::testing::Message()
;
73 }
74}
75
76void
77detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
78 ASSERT_TRUE(first)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(first)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "test_utils.cc", 78, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "first", "false", "true") .c_str()) = ::testing::
Message()
;
79 ASSERT_TRUE(second)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(second)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "test_utils.cc", 79, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "second", "false", "true") .c_str()) = ::testing
::Message()
;
80 EXPECT_EQ(first->type_, second->type_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->type_"
, "second->type_", first->type_, second->type_))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "test_utils.cc", 80, gtest_ar.failure_message
()) = ::testing::Message()
;
81
82 // Compare address strings. Comparison of address objects is not used, as
83 // odd things happen when they are different: the EXPECT_EQ macro appears to
84 // call the operator uint32_t() function, which causes an exception to be
85 // thrown for IPv6 addresses.
86 EXPECT_EQ(first->addr_, second->addr_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->addr_"
, "second->addr_", first->addr_, second->addr_))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "test_utils.cc", 86, gtest_ar.failure_message
()) = ::testing::Message()
;
87 EXPECT_EQ(first->prefixlen_, second->prefixlen_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->prefixlen_"
, "second->prefixlen_", first->prefixlen_, second->prefixlen_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 87, gtest_ar.failure_message
()) = ::testing::Message()
;
88 EXPECT_EQ(first->iaid_, second->iaid_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->iaid_"
, "second->iaid_", first->iaid_, second->iaid_))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "test_utils.cc", 88, gtest_ar.failure_message
()) = ::testing::Message()
;
89 ASSERT_TRUE(first->duid_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(first->duid_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "test_utils.cc", 89, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "first->duid_", "false", "true") .c_str()) = ::
testing::Message()
;
90 ASSERT_TRUE(second->duid_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(second->duid_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "test_utils.cc", 90, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "second->duid_", "false", "true") .c_str()) =
::testing::Message()
;
91 EXPECT_TRUE(*first->duid_ == *second->duid_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(*first->duid_ == *
second->duid_)) ; else ::testing::internal::AssertHelper(::
testing::TestPartResult::kNonFatalFailure, "test_utils.cc", 91
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "*first->duid_ == *second->duid_", "false", "true") .
c_str()) = ::testing::Message()
;
92
93 // Since the initial time values were set, one second could have ticked,
94 // so allow one second of margin error.
95 EXPECT_NEAR(first->preferred_lft_, second->preferred_lft_, 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::DoubleNearPredFormat("first->preferred_lft_"
, "second->preferred_lft_", "1", first->preferred_lft_,
second->preferred_lft_, 1))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "test_utils.cc"
, 95, gtest_ar.failure_message()) = ::testing::Message()
;
96 EXPECT_NEAR(first->valid_lft_, second->valid_lft_, 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::DoubleNearPredFormat("first->valid_lft_"
, "second->valid_lft_", "1", first->valid_lft_, second->
valid_lft_, 1))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "test_utils.cc", 96, gtest_ar
.failure_message()) = ::testing::Message()
;
97 EXPECT_NEAR(first->cltt_, second->cltt_, 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::DoubleNearPredFormat("first->cltt_"
, "second->cltt_", "1", first->cltt_, second->cltt_,
1))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 97, gtest_ar.failure_message
()) = ::testing::Message()
;
98
99 EXPECT_EQ(first->subnet_id_, second->subnet_id_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->subnet_id_"
, "second->subnet_id_", first->subnet_id_, second->subnet_id_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 99, gtest_ar.failure_message
()) = ::testing::Message()
;
100 EXPECT_EQ(first->pool_id_, second->pool_id_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->pool_id_"
, "second->pool_id_", first->pool_id_, second->pool_id_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 100, gtest_ar.failure_message
()) = ::testing::Message()
;
101 EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->fqdn_fwd_"
, "second->fqdn_fwd_", first->fqdn_fwd_, second->fqdn_fwd_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 101, gtest_ar.failure_message
()) = ::testing::Message()
;
102 EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->fqdn_rev_"
, "second->fqdn_rev_", first->fqdn_rev_, second->fqdn_rev_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 102, gtest_ar.failure_message
()) = ::testing::Message()
;
103 EXPECT_EQ(first->hostname_, second->hostname_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->hostname_"
, "second->hostname_", first->hostname_, second->hostname_
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 103, gtest_ar.failure_message
()) = ::testing::Message()
;
104 if (first->getContext()) {
105 EXPECT_TRUE(second->getContext())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(second->getContext
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 105, ::testing::internal
::GetBoolAssertionFailureMessage( gtest_ar_, "second->getContext()"
, "false", "true") .c_str()) = ::testing::Message()
;
106 if (second->getContext()) {
107 EXPECT_EQ(first->getContext()->str(), second->getContext()->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("first->getContext()->str()"
, "second->getContext()->str()", first->getContext()
->str(), second->getContext()->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "test_utils.cc", 107, gtest_ar.failure_message()) = ::testing
::Message()
;
108 }
109 } else {
110 EXPECT_FALSE(second->getContext())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(second->getContext
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "test_utils.cc", 110, ::testing::internal
::GetBoolAssertionFailureMessage( gtest_ar_, "second->getContext()"
, "true", "false") .c_str()) = ::testing::Message()
;
111 }
112}
113
114int findLastSocketFd() {
115 int max_fd_number = getdtablesize();
116 int last_socket = -1;
117 struct stat stats;
118
119 // Iterate over the open fds
120 for (int fd = 0; fd <= max_fd_number; fd++ ) {
1
Assuming 'fd' is <= 'max_fd_number'
2
Loop condition is true. Entering loop body
121 errno(*__errno_location ()) = 0;
122 fstat(fd, &stats);
3
Assuming that 'fstat' is successful; 'errno' becomes undefined after the call
123
124 if (errno(*__errno_location ()) == EBADF9 ) {
4
An undefined value may be read from 'errno'
125 // Skip any that aren't open
126 continue;
127 }
128
129 // it's a socket, remember it
130 if (S_ISSOCK(stats.st_mode)((((stats.st_mode)) & 0170000) == (0140000))) {
131 last_socket = fd;
132 }
133 }
134
135 return (last_socket);
136}
137
138FillFdHoles::FillFdHoles(int limit) : fds_() {
139 if (limit <= 0) {
140 return;
141 }
142 for (;;) {
143 int fd = open("/dev/null", O_RDWR02, 0);
144 if (fd == -1) {
145 return;
146 }
147 if (fd < limit) {
148 fds_.push_front(fd);
149 } else {
150 static_cast<void>(close(fd));
151 return;
152 }
153 }
154}
155
156FillFdHoles::~FillFdHoles() {
157 while (!fds_.empty()) {
158 static_cast<void>(close(fds_.back()));
159 fds_.pop_back();
160 }
161}
162
163} // namespace test
164} // namespace dhcp
165} // namespace isc