From 655763a9a7d55b1618d4df6f1b2f606ff16c04dc Mon Sep 17 00:00:00 2001 From: Thad House Date: Sun, 3 Mar 2019 15:43:04 -0800 Subject: [PATCH] Limit length of message sent to DS SendError call (#1618) If total length is over 65536, the packet will get thrown out. This can be a problem in stack overflow cases (e.g. infinite recursion). --- .../main/native/athena/FRCDriverStation.cpp | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp index 5409ad056f..018196313b 100644 --- a/hal/src/main/native/athena/FRCDriverStation.cpp +++ b/hal/src/main/native/athena/FRCDriverStation.cpp @@ -292,8 +292,43 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode, } int retval = 0; if (i == KEEP_MSGS || (curTime - prevMsgTime[i]) >= std::chrono::seconds(1)) { - retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode, - details, location, callStack); + wpi::StringRef detailsRef{details}; + wpi::StringRef locationRef{location}; + wpi::StringRef callStackRef{callStack}; + + // 1 tag, 4 timestamp, 2 seqnum + // 2 numOccur, 4 error code, 1 flags, 6 strlen + // 1 extra needed for padding on Netcomm end. + size_t baseLength = 21; + + if (baseLength + detailsRef.size() + locationRef.size() + + callStackRef.size() <= + 65536) { + // Pass through + retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode, + details, location, callStack); + } else if (baseLength + detailsRef.size() > 65536) { + // Details too long, cut both location and stack + auto newLen = 65536 - baseLength; + std::string newDetails{details, newLen}; + char empty = '\0'; + retval = FRC_NetworkCommunication_sendError( + isError, errorCode, isLVCode, newDetails.c_str(), &empty, &empty); + } else if (baseLength + detailsRef.size() + locationRef.size() > 65536) { + // Location too long, cut stack + auto newLen = 65536 - baseLength - detailsRef.size(); + std::string newLocation{location, newLen}; + char empty = '\0'; + retval = FRC_NetworkCommunication_sendError( + isError, errorCode, isLVCode, details, newLocation.c_str(), &empty); + } else { + // Stack too long + auto newLen = 65536 - baseLength - detailsRef.size() - locationRef.size(); + std::string newCallStack{callStack, newLen}; + retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode, + details, location, + newCallStack.c_str()); + } if (printMsg) { if (location && location[0] != '\0') { wpi::errs() << (isError ? "Error" : "Warning") << " at " << location