Incorrect port information after applying uri's assignment operator
Closed this issue · 2 comments
After overriding an URI that has port info with an URI that does not have port info, the URI object still tells that it has port info. I guess there is a bug in the implementation of network::uri
's assignment operator.
Furthermore, when I pass this re-assigned URI object into the network::uri_builder
constructor, the constructed new URI not only still tells it has port info, but also creates a broken URI string when calling network::uri::string()
. Checking with Google's AddressSanitizer it reports a heap-use-after-free error. It seems that the string_view
that points to the port info is dangling.
Some unit tests for reproduction:
#include <gtest/gtest.h>
#include "network/uri/uri_builder.hpp"
TEST(UriTest, AssignmentOperator) {
network::uri a("http://a.com:1234");
ASSERT_TRUE(a.has_port());
const network::uri b("http://b.com");
ASSERT_FALSE(b.has_port());
a = b;
ASSERT_FALSE(a.has_port()) << a.string();
}
TEST(UriTest, CopyConstructor) {
network::uri a("http://a.com:1234");
const network::uri b("http://b.com");
a = b;
const network::uri c(a);
ASSERT_FALSE(c.has_port()) << c.string();
}
TEST(UriBuilderTest, ConstructFromUri) {
network::uri a("http://a.com:1234");
const network::uri b("http://b.com");
a = b;
network::uri_builder ub(a); // ASAN reports heap-use-after-free here
const network::uri c(ub.uri());
ASSERT_FALSE(c.has_port()) << c.string();
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Output
[==========] Running 3 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from UriTest
[ RUN ] UriTest.AssignmentOperator
src/uri_test.cc:12: Failure
Value of: a.has_port()
Actual: true
Expected: false
http://b.com
[ FAILED ] UriTest.AssignmentOperator (0 ms)
[ RUN ] UriTest.CopyConstructor
src/uri_test.cc:21: Failure
Value of: c.has_port()
Actual: true
Expected: false
http://b.com
[ FAILED ] UriTest.CopyConstructor (0 ms)
[----------] 2 tests from UriTest (0 ms total)
[----------] 1 test from UriBuilderTest
[ RUN ] UriBuilderTest.ConstructFromUri
src/uri_test.cc:31: Failure
Value of: c.has_port()
Actual: true
Expected: false
http://b.com:1234
[ FAILED ] UriBuilderTest.ConstructFromUri (0 ms)
[----------] 1 test from UriBuilderTest (0 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 2 test cases ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 3 tests, listed below:
[ FAILED ] UriTest.AssignmentOperator
[ FAILED ] UriTest.CopyConstructor
[ FAILED ] UriBuilderTest.ConstructFromUri
3 FAILED TESTS
I can also provide ASAN output if needed. My compiler is gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
and I use the latest code from the master branch. Thank you for developing cppnetlib, btw -- it's awesome!
Thanks for the report, I will investigate. I also suspect the assignment operator is buggy.
Thanks for the fix. I can confirm my tests and ASan are happy now.