THRIFT-3062 fix segfault on invalid port number
This closes #425
commit 9d5654389daab6ab6be6bdae110a1acede51e945
Author: Jim King <jim.king@simplivity.com>
Date: 2015-04-04T19:47:34Z
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp
index fccbcfa..cb4d1fc 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp
@@ -192,9 +192,14 @@
intSock2_ = sv[0];
}
+ // Validate port number
+ if (port_ < 0 || port_ > 0xFFFF) {
+ throw TTransportException(TTransportException::BAD_ARGS, "Specified port is invalid");
+ }
+
struct addrinfo hints, *res, *res0;
int error;
- char port[sizeof("65536") + 1];
+ char port[sizeof("65535")];
std::memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
diff --git a/lib/cpp/src/thrift/transport/TSocket.cpp b/lib/cpp/src/thrift/transport/TSocket.cpp
index 3295073..bcea291 100644
--- a/lib/cpp/src/thrift/transport/TSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSocket.cpp
@@ -358,7 +358,7 @@
// Validate port number
if (port_ < 0 || port_ > 0xFFFF) {
- throw TTransportException(TTransportException::NOT_OPEN, "Specified port is invalid");
+ throw TTransportException(TTransportException::BAD_ARGS, "Specified port is invalid");
}
struct addrinfo hints, *res, *res0;
diff --git a/lib/cpp/test/TServerSocketTest.cpp b/lib/cpp/test/TServerSocketTest.cpp
index ebfd03f..eee7c26 100644
--- a/lib/cpp/test/TServerSocketTest.cpp
+++ b/lib/cpp/test/TServerSocketTest.cpp
@@ -21,6 +21,7 @@
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerSocket.h>
#include "TestPortFixture.h"
+#include "TTransportCheckThrow.h"
using apache::thrift::transport::TServerSocket;
using apache::thrift::transport::TSocket;
@@ -51,6 +52,15 @@
sock2.close();
}
+BOOST_AUTO_TEST_CASE( test_listen_valid_port )
+{
+ TServerSocket sock1(-1);
+ TTRANSPORT_CHECK_THROW(sock1.listen(), TTransportException::BAD_ARGS);
+
+ TServerSocket sock2(65536);
+ TTRANSPORT_CHECK_THROW(sock2.listen(), TTransportException::BAD_ARGS);
+}
+
BOOST_AUTO_TEST_CASE( test_close_before_listen )
{
TServerSocket sock1("localhost", m_serverPort);
diff --git a/lib/cpp/test/TTransportCheckThrow.h b/lib/cpp/test/TTransportCheckThrow.h
new file mode 100644
index 0000000..3b212e1
--- /dev/null
+++ b/lib/cpp/test/TTransportCheckThrow.h
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+#define TTRANSPORT_CHECK_THROW(_CALL, _TYPE) \
+ { bool caught = false; \
+ try { (_CALL); } \
+ catch (TTransportException& ex) { BOOST_CHECK_EQUAL(ex.getType(), _TYPE); caught = true; } \
+ BOOST_CHECK_MESSAGE(caught, "expected TTransportException but nothing was thrown"); }
+
+#define TTRANSPORT_REQUIRE_THROW(_CALL, _TYPE) \
+ { bool caught = false; \
+ try { (_CALL); } \
+ catch (TTransportException& ex) { BOOST_REQUIRE_EQUAL(ex.getType(), _TYPE); caught = true; } \
+ BOOST_REQUIRE_MESSAGE(caught, "expected TTransportException but nothing was thrown"); }
+