Changeset - r24269:b9a89f6faab4
[Not reviewed]
master
0 1 0
Jonathan G Rennison - 4 years ago 2020-06-15 17:36:33
j.g.rennison@gmail.com
Fix: Violation of strict weak ordering in engine name sorter

This could be caused by an engine being renamed, and the old
name being cached from a previous sort.

See: #7838
1 file changed with 11 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -122,31 +122,33 @@ static bool EngineIntroDateSorter(const 
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _engine_sort_direction ? r > 0 : r < 0;
 
}
 

	
 
/* cached values for EngineNameSorter to spare many GetString() calls */
 
static EngineID _last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
 

	
 
/**
 
 * Determines order of engines by name
 
 * @param a first engine to compare
 
 * @param b second engine to compare
 
 * @return for descending order: returns true if a < b. Vice versa for ascending order
 
 */
 
static bool EngineNameSorter(const EngineID &a, const EngineID &b)
 
{
 
	static EngineID last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
 
	static char     last_name[2][64] = { "\0", "\0" };
 
	static char     last_name[2][64] = { "", "" };
 

	
 
	if (a != last_engine[0]) {
 
		last_engine[0] = a;
 
	if (a != _last_engine[0]) {
 
		_last_engine[0] = a;
 
		SetDParam(0, a);
 
		GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0]));
 
	}
 

	
 
	if (b != last_engine[1]) {
 
		last_engine[1] = b;
 
	if (b != _last_engine[1]) {
 
		_last_engine[1] = b;
 
		SetDParam(0, b);
 
		GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1]));
 
	}
 

	
 
	int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
 

	
 
@@ -1289,12 +1291,15 @@ struct BuildVehicleWindow : Window {
 

	
 
			if (eid == this->sel_engine) sel_id = eid;
 
		}
 

	
 
		this->SelectEngine(sel_id);
 

	
 
		/* invalidate cached values for name sorter - engine names could change */
 
		_last_engine[0] = _last_engine[1] = INVALID_ENGINE;
 

	
 
		/* make engines first, and then wagons, sorted by selected sort_criteria */
 
		_engine_sort_direction = false;
 
		EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter);
 

	
 
		/* and then sort engines */
 
		_engine_sort_direction = this->descending_sort_order;
0 comments (0 inline, 0 general)