From a040fb8d4e294dd2c5cead6818089fc9512c6894 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Tue, 10 Jan 2023 06:48:53 -0800 Subject: [PATCH] Ensure logs don't indefinitely append past capacity Summary: ^ There could be cases, albeit unlikely, that logs could be appended for the current state indefintely that would ultimate fail due to not having enough memory. This change puts a cap on that. Reviewed By: mweststrate Differential Revision: D42313904 fbshipit-source-id: 7fd96be822c9427720bccb41c6c32a39213c7652 --- xplat/Flipper/FlipperState.cpp | 25 ++++++++++++++++++++----- xplat/Flipper/FlipperState.h | 4 +++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/xplat/Flipper/FlipperState.cpp b/xplat/Flipper/FlipperState.cpp index d601d33f3..104b590e9 100644 --- a/xplat/Flipper/FlipperState.cpp +++ b/xplat/Flipper/FlipperState.cpp @@ -10,6 +10,8 @@ #include "FlipperStateUpdateListener.h" #include "FlipperStep.h" +#define FLIPPER_LOGS_CAPACITY 4096 + #if FLIPPER_DEBUG_LOG #include "Log.h" #endif @@ -19,7 +21,8 @@ using namespace facebook::flipper; /* Class responsible for collecting state updates and combining them into a * view of the current state of the flipper client. */ -FlipperState::FlipperState() : logs("") {} +FlipperState::FlipperState() {} + void FlipperState::setUpdateListener( std::shared_ptr listener) { std::lock_guard lock(mutex); @@ -46,14 +49,25 @@ void FlipperState::started(std::string step) { } } +void FlipperState::ensureLogsCapacity() { + if (logs.tellp() > FLIPPER_LOGS_CAPACITY) { + logs.str(""); + logs.clear(); + logs << "[Truncated]" << std::endl; + } +} + void FlipperState::success(std::string step) { std::shared_ptr localListener; { std::lock_guard lock(mutex); + std::string message = "[Success] " + step; #if FLIPPER_DEBUG_LOG - log("[finished] " + step); + log(message); #endif - logs = logs + "[Success] " + step + "\n"; + ensureLogsCapacity(); + logs << message << std::endl; + stateMap[step] = State::success; localListener = mListener; } @@ -72,7 +86,8 @@ void FlipperState::failed(std::string step, std::string errorMessage) { #if FLIPPER_DEBUG_LOG log(message); #endif - logs = logs + message + "\n"; + ensureLogsCapacity(); + logs << message << std::endl; stateMap[step] = State::failed; localListener = mListener; } @@ -88,7 +103,7 @@ void FlipperState::failed(std::string step, std::string errorMessage) { // way std::string FlipperState::getState() { std::lock_guard lock(mutex); - return logs; + return logs.str(); } std::vector FlipperState::getStateElements() { diff --git a/xplat/Flipper/FlipperState.h b/xplat/Flipper/FlipperState.h index daa5b4f88..aa0f0e710 100644 --- a/xplat/Flipper/FlipperState.h +++ b/xplat/Flipper/FlipperState.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -53,10 +54,11 @@ class FlipperState { void success(std::string); void failed(std::string, std::string); void started(std::string); + void ensureLogsCapacity(); std::mutex mutex; // Protects all our member variables. std::shared_ptr mListener = nullptr; - std::string logs; + std::stringstream logs; std::vector insertOrder; std::map stateMap; };