Skip to content

Commit

Permalink
capicxx-someip-runtime 3.1.12.5
Browse files Browse the repository at this point in the history
  • Loading branch information
juergengehring committed Jan 25, 2018
1 parent 83b2f35 commit 69a4939
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 61 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changes
=======

v3.1.12.5
- Fix possible heap corruption in conjunction with multiple mainloops
- Optimize (de)serialization of byte arrays

v3.1.12.4
- Fixed calling of on$(BROADCASTNAME)SelectiveSubscriptionChanged
hooks within correct thread context if mainloop integration is used
Expand Down
41 changes: 40 additions & 1 deletion include/CommonAPI/SomeIP/InputStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,46 @@ class InputStream: public CommonAPI::InputStream<InputStream> {
return (*this);
}

template<typename ElementType_, typename ElementDepl_>
template<typename ElementType_, typename ElementDepl_,
typename std::enable_if<(std::is_same<int8_t, ElementType_>::value ||
std::is_same<uint8_t, ElementType_>::value), int>::type = 0>
COMMONAPI_EXPORT InputStream &readValue(std::vector<ElementType_> &_value,
const ArrayDeployment<ElementDepl_> *_depl) {
bitAlign();

uint32_t itsSize;

uint8_t arrayLengthWidth = (_depl ? _depl->arrayLengthWidth_ : 4);
uint32_t arrayMinLength = (_depl ? _depl->arrayMinLength_ : 0);
uint32_t arrayMaxLength = (_depl ? _depl->arrayMaxLength_ : 0xFFFFFFFF);

// Read array size
if (arrayLengthWidth > 0) {
readValue(itsSize, arrayLengthWidth, true);
if (itsSize < arrayMinLength ||
(arrayMaxLength != 0 && itsSize > arrayMaxLength) ||
itsSize > remaining_) {
errorOccurred_ = true;
}
} else {
itsSize = arrayMaxLength;
}

// Reset target
_value.clear();

// Read elements, if reading size has been successful
if (!hasError()) {
ElementType_ *base = reinterpret_cast<ElementType_ *>(_readRaw(itsSize));
_value.assign(base, base+itsSize);
}

return (*this);
}

template<typename ElementType_, typename ElementDepl_,
typename std::enable_if<(!std::is_same<int8_t, ElementType_>::value &&
!std::is_same<uint8_t, ElementType_>::value), int>::type = 0>
COMMONAPI_EXPORT InputStream &readValue(std::vector<ElementType_> &_value,
const ArrayDeployment<ElementDepl_> *_depl) {
bitAlign();
Expand Down
36 changes: 35 additions & 1 deletion include/CommonAPI/SomeIP/OutputStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,41 @@ class OutputStream: public CommonAPI::OutputStream<OutputStream> {
return (*this);
}

template<typename ElementType_, typename ElementDepl_>
template<typename ElementType_, typename ElementDepl_,
typename std::enable_if<(std::is_same<int8_t, ElementType_>::value ||
std::is_same<uint8_t, ElementType_>::value), int>::type = 0>
COMMONAPI_EXPORT OutputStream &writeValue(const std::vector<ElementType_> &_value,
const ArrayDeployment<ElementDepl_> *_depl) {
bitAlign();

uint8_t arrayLengthWidth = (_depl ? _depl->arrayLengthWidth_ : 4);
uint32_t arrayMinLength = (_depl ? _depl->arrayMinLength_ : 0);
uint32_t arrayMaxLength = (_depl ? _depl->arrayMaxLength_ : 0xFFFFFFFF);

if (arrayLengthWidth != 0) {
if (arrayMinLength != 0 && _value.size() < arrayMinLength) {
errorOccurred_ = true;
}
if (arrayMaxLength != 0 && _value.size() > arrayMaxLength) {
errorOccurred_ = true;
}
} else {
if (arrayMaxLength != _value.size()) {
errorOccurred_ = true;
}
}

if (!hasError()) {
_writeValue(uint32_t(_value.size()), arrayLengthWidth);
_writeRaw(reinterpret_cast<const byte_t *>(&_value[0]), _value.size());
}

return (*this);
}

template<typename ElementType_, typename ElementDepl_,
typename std::enable_if<(!std::is_same<int8_t, ElementType_>::value &&
!std::is_same<uint8_t, ElementType_>::value), int>::type = 0>
COMMONAPI_EXPORT OutputStream &writeValue(const std::vector<ElementType_> &_value,
const ArrayDeployment<ElementDepl_> *_depl) {
bitAlign();
Expand Down
31 changes: 14 additions & 17 deletions include/CommonAPI/SomeIP/StubAdapterHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,14 +374,14 @@ class MethodWithReplyStubDispatcher<
const std::shared_ptr<StubClass_> &_stub,
RemoteEventHandlerType* _remoteEventHandler,
std::shared_ptr<ProxyConnection> _connection) {
connection_ = _connection;
return dispatchMessageHelper(
_message, _stub, _remoteEventHandler, _connection,
typename make_sequence_range<sizeof...(InArgs_), 0>::type(),
typename make_sequence_range<sizeof...(OutArgs_), 0>::type());
}

bool sendReplyMessage(const CommonAPI::CallId_t _call,
const std::weak_ptr<ProxyConnection> &_connection,
const std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...> _args = std::make_tuple()) {
{
std::lock_guard<std::mutex> lock(mutex_);
Expand All @@ -393,7 +393,7 @@ class MethodWithReplyStubDispatcher<
return false;
}
}
return sendReplyMessageHelper(_call, typename make_sequence_range<sizeof...(OutArgs_), 0>::type(), _args);
return sendReplyMessageHelper(_call, _connection, typename make_sequence_range<sizeof...(OutArgs_), 0>::type(), _args);
}

protected:
Expand All @@ -407,8 +407,6 @@ class MethodWithReplyStubDispatcher<
std::map<CommonAPI::CallId_t, Message> pending_;
std::mutex mutex_; // protects pending_

std::weak_ptr<ProxyConnection> connection_;

private:
template <int... DeplInArgIndices_>
inline void initialize(index_sequence<DeplInArgIndices_...>, const std::tuple<DeplInArgs_*...> &_in) {
Expand All @@ -423,13 +421,10 @@ class MethodWithReplyStubDispatcher<
index_sequence<InArgIndices_...>,
index_sequence<OutArgIndices_...>) {
(void) _remoteEventHandler;
(void) _connection;

if (!_message.isRequestType()) {
auto error = _message.createErrorResponseMessage(return_code_e::E_WRONG_MESSAGE_TYPE);
if(auto itsConnection = connection_.lock()) {
itsConnection->sendMessage(error);
}
_connection->sendMessage(error);
return true;
}

Expand All @@ -455,12 +450,14 @@ class MethodWithReplyStubDispatcher<
// and a lambda function which holds the call identifier the deployments
// for the out-Parameters and extracts them from the deployables before
// calling the send function.
std::weak_ptr<ProxyConnection> itsConnection = _connection;
(_stub.get()->*stubFunctor_)(
client,
std::move(std::get<InArgIndices_>(in).getValue())...,
[call, this](OutArgs_... _args) {
[call, itsConnection, this](OutArgs_... _args) {
this->sendReplyMessage(
call,
itsConnection,
std::make_tuple(
CommonAPI::Deployable<OutArgs_, DeplOutArgs_>(
_args, std::get<OutArgIndices_>(out_)
Expand All @@ -475,6 +472,7 @@ class MethodWithReplyStubDispatcher<

template<int... OutArgIndices_>
bool sendReplyMessageHelper(const CommonAPI::CallId_t _call,
const std::weak_ptr<ProxyConnection> &_connection,
index_sequence<OutArgIndices_...>,
const std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...>& _args) {
(void)_args;
Expand All @@ -495,7 +493,7 @@ class MethodWithReplyStubDispatcher<
return false;
}
bool isSuccessful = false;
if(auto itsConnection = connection_.lock()) {
if(auto itsConnection = _connection.lock()) {
isSuccessful = itsConnection->sendMessage(reply->second);
}
pending_.erase(_call);
Expand Down Expand Up @@ -552,7 +550,6 @@ class MethodWithReplyStubDispatcher<
const std::shared_ptr<StubClass_> &_stub,
RemoteEventHandlerType* _remoteEventHandler,
std::shared_ptr<ProxyConnection> _connection) {
this->connection_ = _connection;
return dispatchMessageHelper(
_message, _stub, _remoteEventHandler, _connection,
typename make_sequence_range<sizeof...(InArgs_), 0>::type(),
Expand Down Expand Up @@ -590,13 +587,10 @@ class MethodWithReplyStubDispatcher<
index_sequence<OutArgIndices_...>,
index_sequence<ErrorRepliesIndices_...>) {
(void) _remoteEventHandler;
(void) _connection;

if (!_message.isRequestType()) {
auto error = _message.createErrorResponseMessage(return_code_e::E_WRONG_MESSAGE_TYPE);
if(auto itsConnection = this->connection_.lock()) {
itsConnection->sendMessage(error);
}
_connection->sendMessage(error);
return true;
}

Expand All @@ -622,13 +616,15 @@ class MethodWithReplyStubDispatcher<
// and a lambda function which holds the call identifier the deployments
// for the out-Parameters and extracts them from the deployables before
// calling the send function.
std::weak_ptr<ProxyConnection> itsConnection = _connection;
(_stub.get()->*stubFunctor_)(
client,
call,
std::move(std::get<InArgIndices_>(in).getValue())...,
[call, this](OutArgs_... _args) {
[call, itsConnection, this](OutArgs_... _args) {
this->sendReplyMessage(
call,
itsConnection,
std::make_tuple(
CommonAPI::Deployable<OutArgs_, DeplOutArgs_>(
_args, std::get<OutArgIndices_>(this->out_)
Expand All @@ -644,6 +640,7 @@ class MethodWithReplyStubDispatcher<

template<int... OutArgIndices_>
bool sendErrorReplyMessageHelper(const CommonAPI::CallId_t _call,
const std::weak_ptr<ProxyConnection> &_connection,
index_sequence<OutArgIndices_...>,
const std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...>& _args) {
(void)_args;
Expand All @@ -664,7 +661,7 @@ class MethodWithReplyStubDispatcher<
return false;
}
bool isSuccessful = false;
if(auto itsConnection = this->connection_.lock()) {
if(auto itsConnection = _connection.lock()) {
isSuccessful = itsConnection->sendMessage(reply->second);
}
this->pending_.erase(_call);
Expand Down
28 changes: 8 additions & 20 deletions src/CommonAPI/SomeIP/InputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,28 +333,16 @@ InputStream& InputStream::readValue(ByteBuffer &_value, const ByteBufferDeployme
// Reset target
_value.clear();

if (itsSize < byteBufferMinLength
|| (0 != byteBufferMaxLength && itsSize > byteBufferMaxLength)
|| itsSize > remaining_) {
errorOccurred_ = true;
}

// Read elements, if reading size has been successful
if (!hasError()) {
while (itsSize > 0) {
size_t remainingBeforeRead = remaining_;

uint8_t itsElement;
readValue(itsElement, static_cast<const IntegerDeployment<uint8_t> *>(nullptr));
if (hasError()) {
break;
}

_value.push_back(std::move(itsElement));

itsSize -= uint32_t(remainingBeforeRead - remaining_);
}

if (byteBufferMinLength != 0 && _value.size() < byteBufferMinLength) {
errorOccurred_ = true;
}
if (byteBufferMaxLength != 0 && _value.size() > byteBufferMaxLength) {
errorOccurred_ = true;
}
byte_t *base = _readRaw(itsSize);
_value.assign(base, base+itsSize);
}

return (*this);
Expand Down
27 changes: 5 additions & 22 deletions src/CommonAPI/SomeIP/OutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,32 +268,15 @@ OutputStream& OutputStream::writeValue(const ByteBuffer &_value, const ByteBuffe
uint32_t byteBufferMinLength = (_depl ? _depl->byteBufferMinLength_ : 0);
uint32_t byteBufferMaxLength = (_depl ? _depl->byteBufferMaxLength_ : 0xFFFFFFFF);

pushPosition(); // Start of length field
_writeValue(0, 4); // Length field placeholder
pushPosition(); // Start of vector data

if (byteBufferMinLength != 0 && _value.size() < byteBufferMinLength) {
errorOccurred_ = true;
}
if (byteBufferMaxLength != 0 && _value.size() > byteBufferMaxLength) {
if (_value.size() < byteBufferMinLength
|| (byteBufferMaxLength != 0 && _value.size() > byteBufferMaxLength)) {
errorOccurred_ = true;
}

if (hasError()) {
return (*this);
if (!hasError()) {
_writeValue(uint32_t(_value.size()), 4);
_writeRaw(static_cast<const byte_t *>(&_value[0]), _value.size());
}
// Write array/vector content
for (auto i : _value) {
writeValue(i, static_cast<EmptyDeployment *>(nullptr));
if (hasError()) {
return (*this);
}
}

// Write actual value of length field
size_t length = getPosition() - popPosition();
size_t position2Write = popPosition();
_writeValueAt(uint32_t(length), 4, uint32_t(position2Write));

return (*this);
}
Expand Down

0 comments on commit 69a4939

Please sign in to comment.