From 1fef96a2e75b2318ecbb7c92895950aceedfa972 Mon Sep 17 00:00:00 2001
From: Gerhard Schlager <gerhard.schlager@discourse.org>
Date: Wed, 26 Jan 2022 23:34:28 +0100
Subject: [PATCH] FIX: Prevent "integer out of range" when merging post timings
 (#15723)

---
 app/services/user_merger.rb       | 2 +-
 spec/services/user_merger_spec.rb | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/app/services/user_merger.rb b/app/services/user_merger.rb
index 1284dd655ef..a17089200dc 100644
--- a/app/services/user_merger.rb
+++ b/app/services/user_merger.rb
@@ -118,7 +118,7 @@ class UserMerger
                                                "x.post_number = y.post_number"])
     sql = <<~SQL
       UPDATE post_timings AS t
-      SET msecs = t.msecs + s.msecs
+      SET msecs = LEAST(t.msecs::bigint + s.msecs, 2^31 - 1)
       FROM post_timings AS s
       WHERE t.user_id = :target_user_id AND s.user_id = :source_user_id
             AND t.topic_id = s.topic_id AND t.post_number = s.post_number
diff --git a/spec/services/user_merger_spec.rb b/spec/services/user_merger_spec.rb
index 604d795c4b8..ac955db5a55 100644
--- a/spec/services/user_merger_spec.rb
+++ b/spec/services/user_merger_spec.rb
@@ -404,17 +404,21 @@ describe UserMerger do
       post1 = p1
       post2 = p2
       post3 = p3
+      post4 = p4
 
       create_post_timing(post1, source_user, 12345)
       create_post_timing(post2, source_user, 9876)
+      create_post_timing(post4, source_user, 2**31 - 100)
       create_post_timing(post2, target_user, 3333)
       create_post_timing(post3, target_user, 10000)
+      create_post_timing(post4, target_user, 5000)
 
       merge_users!
 
       expect(post_timing_msecs_for(post1, target_user)).to eq(12345)
       expect(post_timing_msecs_for(post2, target_user)).to eq(13209)
       expect(post_timing_msecs_for(post3, target_user)).to eq(10000)
+      expect(post_timing_msecs_for(post4, target_user)).to eq(2**31 - 1)
 
       expect(PostTiming.where(user_id: source_user.id).count).to eq(0)
     end