From 69017298e8394d80436bedba86c2b9ab089bf5fe Mon Sep 17 00:00:00 2001 From: Osama Sayegh <asooomaasoooma90@gmail.com> Date: Thu, 18 Feb 2021 17:48:15 +0300 Subject: [PATCH] FIX: Limit post read time to the max integer value (#12126) Some users somehow manage to keep a topic open for a very long time that it causes the post read time to exceed the max integer value (2^31 - 1) which causes errors when we try to update the read time in the database to values above the integer limit. This PR will cap posts read time at 2^31 - 1 to prevent these errors. --- app/models/post_timing.rb | 2 +- spec/requests/topics_controller_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/models/post_timing.rb b/app/models/post_timing.rb index 8251d429074..7fbe31b8f81 100644 --- a/app/models/post_timing.rb +++ b/app/models/post_timing.rb @@ -165,7 +165,7 @@ class PostTiming < ActiveRecord::Base if join_table.length > 0 sql = <<~SQL UPDATE post_timings t - SET msecs = t.msecs + x.msecs + SET msecs = LEAST(t.msecs::bigint + x.msecs, 2^31 - 1) FROM (#{join_table.join(" UNION ALL ")}) x WHERE x.topic_id = t.topic_id AND x.post_number = t.post_number AND diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index dbeb2dc91b2..4714d4d44b8 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -3057,6 +3057,29 @@ RSpec.describe TopicsController do expect(post_timing.user).to eq(user) expect(post_timing.msecs).to eq(2) end + + it 'caps post read time at the max integer value (2^31 - 1)' do + PostTiming.create!( + topic_id: post_1.topic.id, + post_number: post_1.post_number, + user_id: user.id, + msecs: 2**31 - 10 + ) + sign_in(user) + + post "/topics/timings.json", params: { + topic_id: topic.id, + topic_time: 5, + timings: { post_1.post_number => 100 } + } + + expect(response.status).to eq(200) + post_timing = PostTiming.first + + expect(post_timing.topic).to eq(topic) + expect(post_timing.user).to eq(user) + expect(post_timing.msecs).to eq(2**31 - 1) + end end describe '#timer' do