Fix gcc12 build failure caused by INT_MIN in NumberToHumanString (#12215)

Summary:
This closes https://github.com/facebook/rocksdb/issues/11619 and adds the test case for this.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12215

Reviewed By: hx235

Differential Revision: D52629313

Pulled By: ajkr

fbshipit-source-id: 86b51728d98cf6d9a642cd5993c55190aa7fe12b
This commit is contained in:
git-hulk 2024-01-10 10:17:31 -08:00 committed by Facebook GitHub Bot
parent 491e3d4342
commit 7f2c59e316
4 changed files with 51 additions and 2 deletions

View File

@ -1423,6 +1423,7 @@ if(WITH_TESTS)
util/ribbon_test.cc
util/slice_test.cc
util/slice_transform_test.cc
util/string_util_test.cc
util/timer_queue_test.cc
util/timer_test.cc
util/thread_list_test.cc

View File

@ -1768,6 +1768,9 @@ cuckoo_table_db_test: $(OBJ_DIR)/db/cuckoo_table_db_test.o $(TEST_LIBRARY) $(LIB
listener_test: $(OBJ_DIR)/db/listener_test.o $(TEST_LIBRARY) $(LIBRARY)
$(AM_LINK)
string_util_test: $(OBJ_DIR)/util/string_util_test.o $(TEST_LIBRARY) $(LIBRARY)
$(AM_LINK)
thread_list_test: $(OBJ_DIR)/util/thread_list_test.o $(TEST_LIBRARY) $(LIBRARY)
$(AM_LINK)

View File

@ -115,8 +115,17 @@ void AppendEscapedStringTo(std::string* str, const Slice& value) {
}
std::string NumberToHumanString(int64_t num) {
char buf[19];
int64_t absnum = num < 0 ? -num : num;
char buf[21];
int64_t absnum;
if (num < 0) {
// abs(INT64_MIN) is INT64_MAX+1 which overflows int64_t and become itself.
// So we convert it to INT64_MAX to avoid fall into <10000 slot.
absnum = num == INT64_MIN ? INT64_MAX : -num;
} else {
absnum = num;
}
if (absnum < 10000) {
snprintf(buf, sizeof(buf), "%" PRIi64, num);
} else if (absnum < 10000000) {

36
util/string_util_test.cc Normal file
View File

@ -0,0 +1,36 @@
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
//
#include "string_util.h"
#include <gtest/gtest.h>
#include <port/stack_trace.h>
#include "test_util/testutil.h"
namespace ROCKSDB_NAMESPACE {
TEST(StringUtilTest, NumberToHumanString) {
ASSERT_EQ("-9223372036G", NumberToHumanString(INT64_MIN));
ASSERT_EQ("9223372036G", NumberToHumanString(INT64_MAX));
ASSERT_EQ("0", NumberToHumanString(0));
ASSERT_EQ("9999", NumberToHumanString(9999));
ASSERT_EQ("10K", NumberToHumanString(10000));
ASSERT_EQ("10M", NumberToHumanString(10000000));
ASSERT_EQ("10G", NumberToHumanString(10000000000));
ASSERT_EQ("-9999", NumberToHumanString(-9999));
ASSERT_EQ("-10K", NumberToHumanString(-10000));
ASSERT_EQ("-10M", NumberToHumanString(-10000000));
ASSERT_EQ("-10G", NumberToHumanString(-10000000000));
}
} // namespace ROCKSDB_NAMESPACE
int main(int argc, char** argv) {
ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}