diff --git a/cockatrice/src/interface/widgets/tabs/tab_replays.cpp b/cockatrice/src/interface/widgets/tabs/tab_replays.cpp index 2db9e83c5..c92b1d704 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_replays.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_replays.cpp @@ -265,9 +265,11 @@ void TabReplays::actOpenLocalReplay() f.close(); GameReplay *replay = new GameReplay; - replay->ParseFromArray(_data.data(), _data.size()); - - emit openReplay(replay); + if (replay->ParseFromArray(_data.data(), _data.size())) { + emit openReplay(replay); + } else { + qDebug() << "could not parse replay!"; + } } } @@ -379,9 +381,12 @@ void TabReplays::openRemoteReplayFinished(const Response &r) const Response_ReplayDownload &resp = r.GetExtension(Response_ReplayDownload::ext); GameReplay *replay = new GameReplay; - replay->ParseFromString(resp.replay_data()); + if (replay->ParseFromString(resp.replay_data())) { - emit openReplay(replay); + emit openReplay(replay); + } else { + qDebug() << "could not parse replay!"; + } } void TabReplays::actDownload() diff --git a/cockatrice/src/interface/window_main.cpp b/cockatrice/src/interface/window_main.cpp index fbba6c3f5..6eb5fb3a2 100644 --- a/cockatrice/src/interface/window_main.cpp +++ b/cockatrice/src/interface/window_main.cpp @@ -277,9 +277,11 @@ void MainWindow::actWatchReplay() file.close(); replay = new GameReplay; - replay->ParseFromArray(buf.data(), buf.size()); - - tabSupervisor->openReplay(replay); + if (replay->ParseFromArray(buf.data(), buf.size())) { + tabSupervisor->openReplay(replay); + } else { + qDebug() << "[MainWindow] failed to parse replay!"; + } } void MainWindow::localGameEnded() diff --git a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp index 4b5d3f1b8..3e3ec889d 100644 --- a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp +++ b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp @@ -390,14 +390,18 @@ void RemoteClient::readData() return; ServerMessage newServerMessage; - newServerMessage.ParseFromArray(inputBuffer.data(), messageLength); - - qCDebug(RemoteClientLog).noquote() << "IN" << getSafeDebugString(newServerMessage); + bool ok = newServerMessage.ParseFromArray(inputBuffer.data(), messageLength); inputBuffer.remove(0, messageLength); messageInProgress = false; - processProtocolItem(newServerMessage); + if (ok) { + qCDebug(RemoteClientLog).noquote() << "IN" << getSafeDebugString(newServerMessage); + + processProtocolItem(newServerMessage); + } else { + qCDebug(RemoteClientLog) << "parsing error!"; + } if (getStatus() == StatusDisconnecting) // use thread-safe getter doDisconnectFromServer(); @@ -408,11 +412,13 @@ void RemoteClient::websocketMessageReceived(const QByteArray &message) { lastDataReceived = timeRunning; ServerMessage newServerMessage; - newServerMessage.ParseFromArray(message.data(), message.length()); + if (newServerMessage.ParseFromArray(message.data(), message.length())) { + qCDebug(RemoteClientLog).noquote() << "IN" << getSafeDebugString(newServerMessage); - qCDebug(RemoteClientLog).noquote() << "IN" << getSafeDebugString(newServerMessage); - - processProtocolItem(newServerMessage); + processProtocolItem(newServerMessage); + } else { + qCDebug(RemoteClientLog) << "parsing error!"; + } } void RemoteClient::sendCommandContainer(const CommandContainer &cont) @@ -426,19 +432,27 @@ void RemoteClient::sendCommandContainer(const CommandContainer &cont) qCDebug(RemoteClientLog).noquote() << "OUT" << getSafeDebugString(cont); QByteArray buf; + bool ok; if (usingWebSocket) { buf.resize(size); - cont.SerializeToArray(buf.data(), size); - websocket->sendBinaryMessage(buf); + ok = cont.SerializeToArray(buf.data(), size); + if (ok) { + websocket->sendBinaryMessage(buf); + } } else { buf.resize(size + 4); - cont.SerializeToArray(buf.data() + 4, size); - buf.data()[3] = (unsigned char)size; - buf.data()[2] = (unsigned char)(size >> 8); - buf.data()[1] = (unsigned char)(size >> 16); - buf.data()[0] = (unsigned char)(size >> 24); + ok = cont.SerializeToArray(buf.data() + 4, size); + if (ok) { + buf.data()[3] = (unsigned char)size; + buf.data()[2] = (unsigned char)(size >> 8); + buf.data()[1] = (unsigned char)(size >> 16); + buf.data()[0] = (unsigned char)(size >> 24); - socket->write(buf); + socket->write(buf); + } + } + if (!ok) { + qCDebug(RemoteClientLog) << "transmit error!"; } } diff --git a/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp b/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp index f0c3448b5..c168e7162 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp +++ b/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp @@ -101,6 +101,10 @@ QString getSafeDebugString(const ::google::protobuf::Message &message) #endif // GOOGLE_PROTOBUF_VERSION > 3004000 std::string debug_string; - printer.PrintToString(message, &debug_string); - return QString::number(size) + " bytes " + QString::fromStdString(debug_string); + bool ok = printer.PrintToString(message, &debug_string); + if (ok) { + return QString::number(size) + " bytes " + QString::fromStdString(debug_string); + } else { + return "could not convert message to string"; + } } diff --git a/servatrice/src/isl_interface.cpp b/servatrice/src/isl_interface.cpp index bcf71a98a..b2f0891fd 100644 --- a/servatrice/src/isl_interface.cpp +++ b/servatrice/src/isl_interface.cpp @@ -242,11 +242,15 @@ void IslInterface::readClient() return; IslMessage newMessage; - newMessage.ParseFromArray(inputBuffer.data(), messageLength); + bool ok = newMessage.ParseFromArray(inputBuffer.data(), messageLength); inputBuffer.remove(0, messageLength); messageInProgress = false; - processMessage(newMessage); + if (ok) { + processMessage(newMessage); + } else { + qDebug() << "[ISL] parsing error!"; + } } while (!inputBuffer.isEmpty()); } @@ -270,7 +274,10 @@ void IslInterface::transmitMessage(const IslMessage &item) unsigned int size = static_cast(item.ByteSize()); #endif buf.resize(size + 4); - item.SerializeToArray(buf.data() + 4, size); + if (!item.SerializeToArray(buf.data() + 4, size)) { + qDebug() << "[ISL] transmit error!"; + return; + } buf.data()[3] = (unsigned char)size; buf.data()[2] = (unsigned char)(size >> 8); buf.data()[1] = (unsigned char)(size >> 16); diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index fa9b14f31..a7e75d185 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -865,12 +865,16 @@ void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName, const unsigned int size = static_cast(replayList[i]->ByteSize()); #endif blob.resize(size); - replayList[i]->SerializeToArray(blob.data(), size); + qulonglong replayId = replayList[i]->replay_id(); + if (replayList[i]->SerializeToArray(blob.data(), size)) { - replayIds.append(QVariant((qulonglong)replayList[i]->replay_id())); - replayGameIds.append(gameInfo.game_id()); - replayDurations.append(replayList[i]->duration_seconds()); - replayBlobs.append(blob); + replayIds.append(QVariant(replayId)); + replayGameIds.append(gameInfo.game_id()); + replayDurations.append(replayList[i]->duration_seconds()); + replayBlobs.append(blob); + } else { + qDebug() << "failed to serialise replay, id:" << replayId << "game:" << gameInfo.game_id(); + } } { diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 619d36d3a..1d8db1f0a 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -1971,13 +1971,16 @@ void TcpServerSocketInterface::flushOutputQueue() unsigned int size = static_cast(item.ByteSize()); #endif buf.resize(size + 4); - item.SerializeToArray(buf.data() + 4, size); - buf.data()[3] = (unsigned char)size; - buf.data()[2] = (unsigned char)(size >> 8); - buf.data()[1] = (unsigned char)(size >> 16); - buf.data()[0] = (unsigned char)(size >> 24); - // In case socket->write() calls catchSocketError(), the mutex must not be locked during this call. - writeToSocket(buf); + if (item.SerializeToArray(buf.data() + 4, size)) { + buf.data()[3] = (unsigned char)size; + buf.data()[2] = (unsigned char)(size >> 8); + buf.data()[1] = (unsigned char)(size >> 16); + buf.data()[0] = (unsigned char)(size >> 24); + // In case socket->write() calls catchSocketError(), the mutex must not be locked during this call. + writeToSocket(buf); + } else { + qDebug() << "[TcpServerSocketInterface] serialisation error!"; + } totalBytes += size + 4; locker.relock(); @@ -2010,8 +2013,9 @@ void TcpServerSocketInterface::readClient() return; CommandContainer newCommandContainer; + bool ok; try { - newCommandContainer.ParseFromArray(inputBuffer.data(), messageLength); + ok = newCommandContainer.ParseFromArray(inputBuffer.data(), messageLength); } catch (std::exception &e) { qDebug() << "Caught std::exception in" << __FILE__ << __LINE__ << #ifdef _MSC_VER // Visual Studio @@ -2032,19 +2036,23 @@ void TcpServerSocketInterface::readClient() #endif qDebug() << "Message coming from:" << getAddress(); } - inputBuffer.remove(0, messageLength); messageInProgress = false; - // dirty hack to make v13 client display the correct error message - if (handshakeStarted) - processCommandContainer(newCommandContainer); - else if (!newCommandContainer.has_cmd_id()) { - handshakeStarted = true; - if (!initTcpSession()) - prepareDestroy(); + if (ok) { + // dirty hack to make v13 client display the correct error message + if (handshakeStarted) + processCommandContainer(newCommandContainer); + else if (!newCommandContainer.has_cmd_id()) { + handshakeStarted = true; + if (!initTcpSession()) + prepareDestroy(); + } + // end of hack + } else { + qDebug() << "[TcpServerSocketInterface] parsing error!"; } - // end of hack + } while (!inputBuffer.isEmpty()); } @@ -2172,9 +2180,12 @@ void WebsocketServerSocketInterface::flushOutputQueue() unsigned int size = static_cast(item.ByteSize()); #endif buf.resize(size); - item.SerializeToArray(buf.data(), size); - // In case socket->write() calls catchSocketError(), the mutex must not be locked during this call. - writeToSocket(buf); + if (item.SerializeToArray(buf.data(), size)) { + // In case socket->write() calls catchSocketError(), the mutex must not be locked during this call. + writeToSocket(buf); + } else { + qDebug() << "[TcpServerSocketInterface] serialisation error!"; + } totalBytes += size; locker.relock(); @@ -2190,8 +2201,9 @@ void WebsocketServerSocketInterface::binaryMessageReceived(const QByteArray &mes servatrice->incRxBytes(message.size()); CommandContainer newCommandContainer; + bool ok; try { - newCommandContainer.ParseFromArray(message.data(), message.size()); + ok = newCommandContainer.ParseFromArray(message.data(), message.size()); } catch (std::exception &e) { qDebug() << "Caught std::exception in" << __FILE__ << __LINE__ << #ifdef _MSC_VER // Visual Studio @@ -2213,7 +2225,11 @@ void WebsocketServerSocketInterface::binaryMessageReceived(const QByteArray &mes qDebug() << "Message coming from:" << getAddress(); } - processCommandContainer(newCommandContainer); + if (ok) { + processCommandContainer(newCommandContainer); + } else { + qDebug() << "[WebsocketServerSocketInterface] parsing error!"; + } } bool AbstractServerSocketInterface::isPasswordLongEnough(const int passwordLength)