Skip to content

Commit e7cd4cf

Browse files
authoredJul 31, 2021
Fix /emergeblocks crashing in debug builds (#11461)
The reason for the bug was an u16 overflow, thus failing the assert. This only happened in Debug build but not in Release builds.
1 parent 0257e71 commit e7cd4cf

File tree

5 files changed

+29
-24
lines changed

5 files changed

+29
-24
lines changed
 

‎builtin/settingtypes.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -2218,15 +2218,15 @@ chunksize (Chunk size) int 5
22182218
enable_mapgen_debug_info (Mapgen debug) bool false
22192219

22202220
# Maximum number of blocks that can be queued for loading.
2221-
emergequeue_limit_total (Absolute limit of queued blocks to emerge) int 1024
2221+
emergequeue_limit_total (Absolute limit of queued blocks to emerge) int 1024 1 1000000
22222222

22232223
# Maximum number of blocks to be queued that are to be loaded from file.
22242224
# This limit is enforced per player.
2225-
emergequeue_limit_diskonly (Per-player limit of queued blocks load from disk) int 128
2225+
emergequeue_limit_diskonly (Per-player limit of queued blocks load from disk) int 128 1 1000000
22262226

22272227
# Maximum number of blocks to be queued that are to be generated.
22282228
# This limit is enforced per player.
2229-
emergequeue_limit_generate (Per-player limit of queued blocks to generate) int 128
2229+
emergequeue_limit_generate (Per-player limit of queued blocks to generate) int 128 1 1000000
22302230

22312231
# Number of emerge threads to use.
22322232
# Value 0:

‎src/emerge.cpp

+12-17
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,17 @@ EmergeManager::EmergeManager(Server *server)
165165
if (nthreads < 1)
166166
nthreads = 1;
167167

168-
m_qlimit_total = g_settings->getU16("emergequeue_limit_total");
168+
m_qlimit_total = g_settings->getU32("emergequeue_limit_total");
169169
// FIXME: these fallback values are probably not good
170-
if (!g_settings->getU16NoEx("emergequeue_limit_diskonly", m_qlimit_diskonly))
170+
if (!g_settings->getU32NoEx("emergequeue_limit_diskonly", m_qlimit_diskonly))
171171
m_qlimit_diskonly = nthreads * 5 + 1;
172-
if (!g_settings->getU16NoEx("emergequeue_limit_generate", m_qlimit_generate))
172+
if (!g_settings->getU32NoEx("emergequeue_limit_generate", m_qlimit_generate))
173173
m_qlimit_generate = nthreads + 1;
174174

175175
// don't trust user input for something very important like this
176-
if (m_qlimit_total < 1)
177-
m_qlimit_total = 1;
178-
if (m_qlimit_diskonly < 1)
179-
m_qlimit_diskonly = 1;
180-
if (m_qlimit_generate < 1)
181-
m_qlimit_generate = 1;
176+
m_qlimit_total = rangelim(m_qlimit_total, 1, 1000000);
177+
m_qlimit_diskonly = rangelim(m_qlimit_diskonly, 1, 1000000);
178+
m_qlimit_generate = rangelim(m_qlimit_generate, 1, 1000000);
182179

183180
for (s16 i = 0; i < nthreads; i++)
184181
m_threads.push_back(new EmergeThread(server, i));
@@ -425,14 +422,14 @@ bool EmergeManager::pushBlockEmergeData(
425422
void *callback_param,
426423
bool *entry_already_exists)
427424
{
428-
u16 &count_peer = m_peer_queue_count[peer_requested];
425+
u32 &count_peer = m_peer_queue_count[peer_requested];
429426

430427
if ((flags & BLOCK_EMERGE_FORCE_QUEUE) == 0) {
431428
if (m_blocks_enqueued.size() >= m_qlimit_total)
432429
return false;
433430

434431
if (peer_requested != PEER_ID_INEXISTENT) {
435-
u16 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN) ?
432+
u32 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN) ?
436433
m_qlimit_generate : m_qlimit_diskonly;
437434
if (count_peer >= qlimit_peer)
438435
return false;
@@ -467,20 +464,18 @@ bool EmergeManager::pushBlockEmergeData(
467464

468465
bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata)
469466
{
470-
std::map<v3s16, BlockEmergeData>::iterator it;
471-
std::unordered_map<u16, u16>::iterator it2;
472-
473-
it = m_blocks_enqueued.find(pos);
467+
auto it = m_blocks_enqueued.find(pos);
474468
if (it == m_blocks_enqueued.end())
475469
return false;
476470

477471
*bedata = it->second;
478472

479-
it2 = m_peer_queue_count.find(bedata->peer_requested);
473+
auto it2 = m_peer_queue_count.find(bedata->peer_requested);
480474
if (it2 == m_peer_queue_count.end())
481475
return false;
482476

483-
u16 &count_peer = it2->second;
477+
u32 &count_peer = it2->second;
478+
484479
assert(count_peer != 0);
485480
count_peer--;
486481

‎src/emerge.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@ class EmergeManager {
194194

195195
std::mutex m_queue_mutex;
196196
std::map<v3s16, BlockEmergeData> m_blocks_enqueued;
197-
std::unordered_map<u16, u16> m_peer_queue_count;
197+
std::unordered_map<u16, u32> m_peer_queue_count;
198198

199-
u16 m_qlimit_total;
200-
u16 m_qlimit_diskonly;
201-
u16 m_qlimit_generate;
199+
u32 m_qlimit_total;
200+
u32 m_qlimit_diskonly;
201+
u32 m_qlimit_generate;
202202

203203
// Managers of various map generation-related components
204204
// Note that each Mapgen gets a copy(!) of these to work with

‎src/settings.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,15 @@ bool Settings::getS16NoEx(const std::string &name, s16 &val) const
755755
}
756756
}
757757

758+
bool Settings::getU32NoEx(const std::string &name, u32 &val) const
759+
{
760+
try {
761+
val = getU32(name);
762+
return true;
763+
} catch (SettingNotFoundException &e) {
764+
return false;
765+
}
766+
}
758767

759768
bool Settings::getS32NoEx(const std::string &name, s32 &val) const
760769
{

‎src/settings.h

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ class Settings {
186186
bool getFlag(const std::string &name) const;
187187
bool getU16NoEx(const std::string &name, u16 &val) const;
188188
bool getS16NoEx(const std::string &name, s16 &val) const;
189+
bool getU32NoEx(const std::string &name, u32 &val) const;
189190
bool getS32NoEx(const std::string &name, s32 &val) const;
190191
bool getU64NoEx(const std::string &name, u64 &val) const;
191192
bool getFloatNoEx(const std::string &name, float &val) const;

0 commit comments

Comments
 (0)
Please sign in to comment.