@@ -896,9 +896,9 @@ static bool ensure_project_row_remote(CURL* curl, const CloudConfigurationStateS
896896 std::string url = snapshot.supabase_url + " /rest/v1/projects" ;
897897 std::ostringstream payload;
898898 payload << " [{" ;
899- payload << " \" project_key\" :\" " << snapshot.project_id << " \" " ;
899+ payload << " \" project_key\" :\" " << escape_json_string ( snapshot.project_id ) << " \" " ;
900900 if (!snapshot.project_scope .empty ()) {
901- payload << " ,\" name\" :\" " << snapshot.project_scope << " \" " ;
901+ payload << " ,\" name\" :\" " << escape_json_string ( snapshot.project_scope ) << " \" " ;
902902 }
903903 payload << " }]" ;
904904 struct curl_slist * headers = nullptr ;
@@ -934,12 +934,12 @@ static bool ensure_device_row_remote(CURL* curl, const CloudConfigurationStateSn
934934 std::string url = snapshot.supabase_url + " /rest/v1/devices" ;
935935 std::ostringstream payload;
936936 payload << " [{" ;
937- payload << " \" id\" :\" " << snapshot.device_id << " \" " ;
938- payload << " ,\" device_id\" :\" " << snapshot.device_id << " \" " ;
939- if (!snapshot.device_model .empty ()) payload << " ,\" model\" :\" " << snapshot.device_model << " \" " ;
940- if (!snapshot.device_os .empty ()) payload << " ,\" os\" :\" " << snapshot.device_os << " \" " ;
941- if (!snapshot.device_os_version .empty ()) payload << " ,\" os_version\" :\" " << snapshot.device_os_version << " \" " ;
942- if (!snapshot.device_brand .empty ()) payload << " ,\" brand\" :\" " << snapshot.device_brand << " \" " ;
937+ payload << " \" id\" :\" " << escape_json_string ( snapshot.device_id ) << " \" " ;
938+ payload << " ,\" device_id\" :\" " << escape_json_string ( snapshot.device_id ) << " \" " ;
939+ if (!snapshot.device_model .empty ()) payload << " ,\" model\" :\" " << escape_json_string ( snapshot.device_model ) << " \" " ;
940+ if (!snapshot.device_os .empty ()) payload << " ,\" os\" :\" " << escape_json_string ( snapshot.device_os ) << " \" " ;
941+ if (!snapshot.device_os_version .empty ()) payload << " ,\" os_version\" :\" " << escape_json_string ( snapshot.device_os_version ) << " \" " ;
942+ if (!snapshot.device_brand .empty ()) payload << " ,\" brand\" :\" " << escape_json_string ( snapshot.device_brand ) << " \" " ;
943943 payload << " }]" ;
944944 struct curl_slist * headers = nullptr ;
945945 headers = curl_slist_append (headers, " Content-Type: application/json" );
@@ -1063,16 +1063,16 @@ static CloudSendResult send_batch_to_cloud(const std::vector<Event>& local, cons
10631063 }
10641064 payload << " \" created_at\" :\" " << format_timestamp (e.timestamp ) << " \" ," ;
10651065 if (!snapshot.project_id .empty ()) {
1066- payload << " \" project_id\" :\" " << snapshot.project_id << " \" ," ;
1066+ payload << " \" project_id\" :\" " << escape_json_string ( snapshot.project_id ) << " \" ," ;
10671067 }
10681068 if (!snapshot.cloud_key .empty ()) {
1069- payload << " \" key_hash\" :\" " << snapshot.cloud_key << " \" ," ;
1069+ payload << " \" key_hash\" :\" " << escape_json_string ( snapshot.cloud_key ) << " \" ," ;
10701070 }
1071- payload << " \" framework\" :\" " << snapshot.framework << " \" ," ;
1071+ payload << " \" framework\" :\" " << escape_json_string ( snapshot.framework ) << " \" ," ;
10721072 if (!snapshot.cactus_version .empty ()) {
1073- payload << " \" framework_version\" :\" " << snapshot.cactus_version << " \" ," ;
1073+ payload << " \" framework_version\" :\" " << escape_json_string ( snapshot.cactus_version ) << " \" ," ;
10741074 }
1075- payload << " \" device_id\" :\" " << snapshot.device_id << " \" " ;
1075+ payload << " \" device_id\" :\" " << escape_json_string ( snapshot.device_id ) << " \" " ;
10761076 if (!snapshot.app_id .empty ()) {
10771077 payload << " ,\" app_id\" :\" " << escape_json_string (snapshot.app_id .c_str ()) << " \" " ;
10781078 } else {
@@ -1098,7 +1098,26 @@ static CloudSendResult send_batch_to_cloud(const std::vector<Event>& local, cons
10981098 return result;
10991099}
11001100
1101+ static const size_t kMaxCachedEventsPerFile = 1000 ;
1102+
1103+ static void trim_cache_file (const std::string& file, size_t max_lines) {
1104+ std::vector<std::string> lines;
1105+ {
1106+ std::ifstream in (file);
1107+ if (!in.is_open ()) return ;
1108+ std::string line;
1109+ while (std::getline (in, line)) lines.push_back (line);
1110+ }
1111+ if (lines.size () <= max_lines) return ;
1112+ std::ofstream out (file, std::ios::trunc);
1113+ if (!out.is_open ()) return ;
1114+ for (size_t i = lines.size () - max_lines; i < lines.size (); ++i) {
1115+ out << lines[i] << " \n " ;
1116+ }
1117+ }
1118+
11011119static void write_events_to_cache_in_dir (const std::vector<Event>& local, const std::string& dir) {
1120+ std::vector<std::string> touched_files;
11021121 for (const auto &e : local) {
11031122 std::ostringstream oss;
11041123 oss << " {\" event_type\" :\" " << event_type_to_string (e.type ) << " \" ," ;
@@ -1169,6 +1188,12 @@ static void write_events_to_cache_in_dir(const std::vector<Event>& local, const
11691188 out << oss.str () << " \n " ;
11701189 out.close ();
11711190 }
1191+ bool seen = false ;
1192+ for (const auto & f : touched_files) { if (f == file) { seen = true ; break ; } }
1193+ if (!seen) touched_files.push_back (file);
1194+ }
1195+ for (const auto & file : touched_files) {
1196+ trim_cache_file (file, kMaxCachedEventsPerFile );
11721197 }
11731198}
11741199
0 commit comments